From 60844359acf10405a7994b2b1f90997abcefe951 Mon Sep 17 00:00:00 2001
From: mage2-team <mage2-team@magento.com>
Date: Sat, 2 Feb 2013 10:31:43 -0800
Subject: [PATCH] 2.0.0.0-dev40 * Implemented ability to customize all the main
 directory paths for the application, i.e. locations of `var`, `etc`, `media`
 and other directories * Implemented ability to pass application configuration
 data from the environment * Magento Web API changes:   * Added SOAP V2 API
 coverage from Magento 1.x   * Improved integration testing framework to
 develop Web API tests. Covered SOAP V2 API with positive integration tests.  
 * Changed `Mage_Webapi` module front name from `api` to `webapi` *
 Improvements for product creation UI:   * Implemented AJAX suggestions popup
 and categories tree popup for convenient assignment of categories   * Moved
 selection of Bundle and Grouped sub-products to the "General" tab,
 implemented popup grids for them   * Made "Weight" checkbox to be selected by
 default for a Configurable product * Implemented integration test to measure
 and control PHP memory leak on application reinitialization * Changed format
 of configuration files for static tests that search for obsolete Magento 1.x
 code * Bug fixes:   * Fixed Web API WSDL incompatibility with C# and Java   *
 Fixed issue, that Magento duplicated custom options field for a product, if
 creating them via a multi-call to API   * Fixed `shoppingCartPaymentList`
 method in Web API, which was throwing exception "Object has no 'code'
 property"   * Fixed invalid Wishlist link and several invalid links in
 Checkout on frontend store view   * Made Stock Status in
 'quantity_and_stock_status' attribute editable again for a Configurable
 product   * Fixed issue, that it was not possible to save Customer after
 first save, because "Date Of Birth" format was reported by Magento to be
 incorrect   * Fixed fatal error in Code Sniffer exemplar test   * Fixed wrong
 failures of `Varien_Db_Adapter_Pdo_MysqlTest::testWaitTimeout()` integration
 test in developer mode   * Fixed issue, that mass-action column in backend
 grids moved to another position in single store mode

---
 .gitignore                                    |    1 -
 .htaccess                                     |    5 -
 CHANGELOG.markdown                            |   25 +
 app/Mage.php                                  |  106 +-
 app/bootstrap.php                             |   32 +-
 .../core/Mage/Adminhtml/Block/Api/Buttons.php |   88 +
 .../Mage/Adminhtml/Block/Api/Editroles.php    |   69 +
 .../Mage/Adminhtml/Block/Api/Grid/Role.php    |   81 +
 .../core/Mage/Adminhtml/Block/Api/Role.php    |   37 +
 .../Adminhtml/Block/Api/Role/Grid/User.php    |  182 ++
 .../core/Mage/Adminhtml/Block/Api/Roles.php   |   48 +
 .../Mage/Adminhtml/Block/Api/Tab/Roleinfo.php |   69 +
 .../Adminhtml/Block/Api/Tab/Rolesedit.php     |  122 +
 .../Adminhtml/Block/Api/Tab/Rolesusers.php    |   54 +
 .../Zend.php => Adminhtml/Block/Api/User.php} |   51 +-
 .../Mage/Adminhtml/Block/Api/User/Edit.php    |   58 +
 .../Adminhtml/Block/Api/User/Edit/Form.php    |   45 +
 .../Block/Api/User/Edit/Tab/Main.php          |  153 +
 .../Block/Api/User/Edit/Tab/Roles.php         |  119 +
 .../Adminhtml/Block/Api/User/Edit/Tabs.php    |   65 +
 .../Mage/Adminhtml/Block/Api/User/Grid.php    |  106 +
 .../Adminhtml/Block/Catalog/Category/Tree.php |    2 +-
 .../Product/Edit/Tab/Options/Option.php       |    4 +-
 .../Edit/Tab/Options/Type/Abstract.php        |    2 +-
 .../Catalog/Product/Edit/Tab/Super/Group.php  |  236 --
 .../Product/Frontend/Product/Watermark.php    |    4 +-
 .../Catalog/Product/Helper/Form/Category.php  |   48 +-
 .../Block/Catalog/Product/Options/Ajax.php    |    2 +-
 .../Block/Customer/Edit/Renderer/Newpass.php  |    4 +-
 .../Block/Customer/Edit/Renderer/Region.php   |    2 +-
 .../core/Mage/Adminhtml/Block/Html/Date.php   |   74 -
 .../core/Mage/Adminhtml/Block/Html/Select.php |   70 -
 .../core/Mage/Adminhtml/Block/Messages.php    |   72 -
 .../Adminhtml/Block/Notification/Baseurl.php  |    6 +-
 .../core/Mage/Adminhtml/Block/Page/Footer.php |    2 +-
 .../core/Mage/Adminhtml/Block/Page/Head.php   |    6 +-
 .../Block/Promo/Quote/Edit/Tab/Labels.php     |    8 +-
 .../Quote/Edit/Tab/Main/Renderer/Checkbox.php |    2 +-
 .../Block/Promo/Widget/Chooser/Daterange.php  |    2 +-
 .../Adminhtml/Block/Rating/Edit/Tab/Form.php  |    8 +-
 .../Block/Sales/Order/Create/Messages.php     |    2 +-
 .../Block/Sales/Order/View/Messages.php       |    2 +-
 .../Block/System/Currency/Rate/Services.php   |    2 +-
 .../Block/System/Email/Template/Edit.php      |    7 +-
 .../core/Mage/Adminhtml/Model/Extension.php   |  402 ---
 .../controllers/Api/RoleController.php        |  217 ++
 .../controllers/Api/UserController.php        |  190 ++
 .../controllers/Catalog/ProductController.php |   18 +-
 .../adminhtml/api/role_users_grid_js.phtml    |  105 +
 .../view/adminhtml/api/roleinfo.phtml         |   47 +
 .../Adminhtml/view/adminhtml/api/roles.phtml  |   31 +-
 .../view/adminhtml/api/rolesedit.phtml        |  143 +
 .../view/adminhtml/api/rolesusers.phtml       |    8 +-
 .../adminhtml/api/user_roles_grid_js.phtml    |   85 +
 .../view/adminhtml/api/userinfo.phtml         |   52 +
 .../view/adminhtml/api/usernroles.phtml       |   11 +-
 .../Mage/Adminhtml/view/adminhtml/catalog.xml |  208 +-
 .../adminhtml/catalog/product-variation.js    |    2 +-
 .../view/adminhtml/catalog/product.js         |  573 ----
 .../product/composite/fieldset/grouped.phtml  |    2 +-
 .../view/adminhtml/catalog/product/edit.phtml |   72 +-
 .../catalog/product/edit/options.phtml        |    6 +-
 .../edit/super/attribute-js-template.phtml    |    4 +-
 .../edit/super/attribute-template.phtml       |    6 +-
 .../catalog/product/edit/super/config.phtml   |   13 +-
 .../catalog/product/tab/inventory.phtml       |    2 +-
 .../view/adminhtml/catalog/type-switcher.js   |    8 +-
 .../Mage/Adminhtml/view/adminhtml/main.xml    |    1 -
 .../view/adminhtml/page/js/components.phtml   |   27 +-
 .../adminhtml/resetforgottenpassword.phtml    |   89 -
 app/code/core/Mage/Api/Controller/Action.php  |   61 +
 app/code/core/Mage/Api/Exception.php          |   53 +
 app/code/core/Mage/Api/Helper/Data.php        |  359 +++
 app/code/core/Mage/Api/Model/Acl.php          |  103 +
 app/code/core/Mage/Api/Model/Acl/Resource.php |   38 +
 app/code/core/Mage/Api/Model/Acl/Role.php     |   37 +
 .../core/Mage/Api/Model/Acl/Role/Generic.php  |   38 +
 .../core/Mage/Api/Model/Acl/Role/Group.php    |   38 +
 .../core/Mage/Api/Model/Acl/Role/Registry.php |   76 +
 .../core/Mage/Api/Model/Acl/Role/User.php     |   38 +
 app/code/core/Mage/Api/Model/Config.php       |  294 ++
 .../core/Mage/Api/Model/Resource/Abstract.php |  105 +
 app/code/core/Mage/Api/Model/Resource/Acl.php |  145 +
 .../core/Mage/Api/Model/Resource/Acl/Role.php |   59 +
 .../Model/Resource/Acl/Role/Collection.php    |   45 +
 .../Model/Resource/Permissions/Collection.php |   45 +
 .../core/Mage/Api/Model/Resource/Role.php     |   76 +
 .../Api/Model/Resource/Role/Collection.php    |   69 +
 .../core/Mage/Api/Model/Resource/Roles.php    |  151 +
 .../Api/Model/Resource/Roles/Collection.php   |   67 +
 .../Model/Resource/Roles/User/Collection.php  |   59 +
 .../core/Mage/Api/Model/Resource/Rules.php    |   87 +
 .../Api/Model/Resource/Rules/Collection.php   |   69 +
 .../core/Mage/Api/Model/Resource/User.php     |  435 +++
 .../Api/Model/Resource/User/Collection.php    |   45 +
 app/code/core/Mage/Api/Model/Role.php         |   58 +
 app/code/core/Mage/Api/Model/Roles.php        |  181 ++
 app/code/core/Mage/Api/Model/Rules.php        |   69 +
 app/code/core/Mage/Api/Model/Server.php       |  161 +
 .../Mage/Api/Model/Server/Adapter/Soap.php    |  241 ++
 .../Api/Model/Server/Adapter/Soap/Wsi.php     |  104 +
 .../Mage/Api/Model/Server/Handler/Soap.php    |   60 +
 .../Api/Model/Server/Handler/Soap/Wsi.php     |  182 ++
 .../Mage/Api/Model/Server/HandlerAbstract.php |  416 +++
 app/code/core/Mage/Api/Model/Session.php      |  207 ++
 app/code/core/Mage/Api/Model/User.php         |  254 ++
 app/code/core/Mage/Api/Model/Wsdl/Config.php  |  140 +
 .../core/Mage/Api/Model/Wsdl/Config/Base.php  |  136 +
 .../Mage/Api/Model/Wsdl/Config/Element.php    |  272 ++
 .../Api/controllers/Soap/WsiController.php    |   42 +
 .../Mage/Api/controllers/SoapController.php   |   42 +
 app/code/core/Mage/Api/etc/adminhtml.xml      |   62 +
 app/code/core/Mage/Api/etc/adminhtml/menu.xml |   39 +
 .../core/Mage/Api/etc/adminhtml/system.xml    |   50 +
 app/code/core/Mage/Api/etc/api.xml            |  260 ++
 app/code/core/Mage/Api/etc/config.xml         |  107 +
 app/code/core/Mage/Api/etc/wsdl.xml           |  242 ++
 app/code/core/Mage/Api/etc/wsi.xml            |  381 +++
 .../core/Mage/Api/locale/de_DE/Mage_Api.csv   |   16 +
 .../core/Mage/Api/locale/en_US/Mage_Api.csv   |   16 +
 .../core/Mage/Api/locale/es_ES/Mage_Api.csv   |   16 +
 .../core/Mage/Api/locale/fr_FR/Mage_Api.csv   |   16 +
 .../core/Mage/Api/locale/nl_NL/Mage_Api.csv   |   16 +
 .../core/Mage/Api/locale/pt_BR/Mage_Api.csv   |   16 +
 .../core/Mage/Api/locale/zh_CN/Mage_Api.csv   |   16 +
 .../Api/sql/api_setup/install-1.6.0.0.php     |  208 ++
 app/code/core/Mage/Backend/Block/Abstract.php |   10 +-
 .../Block/Catalog/Product/Tab/Container.php   |   70 +
 .../Mage/Backend/Block/Store/Switcher.php     |    8 +-
 .../Mage/Backend/Block/System/Config/Edit.php |    6 +-
 .../Mage/Backend/Block/System/Config/Form.php |    9 +-
 .../Block/System/Config/Form/Field.php        |   10 +-
 .../System/Config/Form/Field/Heading.php      |    2 +-
 .../Block/System/Config/Form/Fieldset.php     |    2 +-
 .../Mage/Backend/Block/System/Config/Tabs.php |    9 +-
 app/code/core/Mage/Backend/Block/Template.php |    6 +-
 .../Block/Widget/Form/Element/Dependence.php  |    2 +-
 .../Mage/Backend/Block/Widget/Grid/Column.php |   36 +-
 .../Widget/Grid/Column/Filter/Abstract.php    |    2 +-
 .../Block/Widget/Grid/Column/Multistore.php   |    8 +-
 .../Widget/Grid/Column/Renderer/Abstract.php  |    2 +-
 .../Widget/Grid/Column/Renderer/Button.php    |   45 +
 .../Widget/Grid/Column/Renderer/Currency.php  |   13 +-
 .../Widget/Grid/Column/Renderer/Grip.php      |   42 +
 .../Backend/Block/Widget/Grid/ColumnSet.php   |    8 +-
 .../Block/Widget/Grid/Massaction/Abstract.php |    5 +-
 .../Backend/Model/Config/Backend/Baseurl.php  |  176 +-
 .../Mage/Backend/etc/adminhtml/system.xml     |   39 +-
 .../Backend/view/adminhtml/widget/grid.phtml  |    4 +
 .../adminhtml/widget/grid/serializer.phtml    |    2 +-
 .../Product/Edit/Tab/Attributes/Extend.php    |    8 +-
 .../Catalog/Product/Edit/Tab/Bundle.php       |    2 +-
 .../Product/Edit/Tab/Bundle/Option.php        |   18 +-
 .../Product/Edit/Tab/Bundle/Option/Search.php |   40 +-
 .../Edit/Tab/Bundle/Option/Search/Grid.php    |   84 +-
 .../Edit/Tab/Bundle/Option/Selection.php      |    6 +-
 .../view/adminhtml/css/bundle-product.css     |   84 +
 .../view/adminhtml/js/bundle-product.js       |  206 ++
 .../Mage/Bundle/view/adminhtml/layout.xml     |   10 +-
 .../view/adminhtml/product/edit/bundle.phtml  |   44 +-
 .../product/edit/bundle/option.phtml          |  180 +-
 .../product/edit/bundle/option/search.phtml   |   13 +-
 .../edit/bundle/option/selection.phtml        |  252 +-
 app/code/core/Mage/Captcha/Helper/Data.php    |   22 +-
 app/code/core/Mage/Captcha/Model/Zend.php     |   18 +-
 app/code/core/Mage/Captcha/etc/config.xml     |    2 +-
 .../Backend/Grid/ColumnSet.php                |    6 +-
 .../Product/Grouped/AssociatedProducts.php    |   44 +
 .../Grouped/AssociatedProducts/Grid.php       |  137 +
 .../core/Mage/Catalog/Model/Api/Resource.php  |  135 +
 .../core/Mage/Catalog/Model/Category/Api.php  |  524 +++
 .../Mage/Catalog/Model/Category/Api/V2.php    |  165 +
 .../Catalog/Model/Category/Attribute/Api.php  |  109 +
 .../Model/Category/Attribute/Api/V2.php       |   36 +
 .../Category/Attribute/Backend/Image.php      |    1 -
 app/code/core/Mage/Catalog/Model/Config.php   |    1 +
 .../core/Mage/Catalog/Model/Product/Api.php   |  528 +++
 .../Mage/Catalog/Model/Product/Api/V2.php     |  308 ++
 .../Catalog/Model/Product/Attribute/Api.php   |  526 +++
 .../Model/Product/Attribute/Api/V2.php        |   99 +
 .../Model/Product/Attribute/Backend/Media.php |   70 +-
 .../Model/Product/Attribute/Media/Api.php     |  421 +++
 .../Model/Product/Attribute/Media/Api/V2.php  |   53 +
 .../Model/Product/Attribute/Set/Api.php       |  287 ++
 .../Model/Product/Attribute/Set/Api/V2.php    |   36 +
 .../Model/Product/Attribute/Tierprice/Api.php |  185 ++
 .../Product/Attribute/Tierprice/Api/V2.php    |   91 +
 .../Mage/Catalog/Model/Product/Link/Api.php   |  349 ++
 .../Catalog/Model/Product/Link/Api/V2.php     |  119 +
 .../Mage/Catalog/Model/Product/Option/Api.php |  331 ++
 .../Catalog/Model/Product/Option/Api/V2.php   |   81 +
 .../Model/Product/Option/Value/Api.php        |  226 ++
 .../Model/Product/Option/Value/Api/V2.php     |  104 +
 .../Mage/Catalog/Model/Product/Type/Api.php   |   54 +
 .../Catalog/Model/Product/Type/Api/V2.php     |   36 +
 .../Model/Product/Type/Configurable.php       |   10 -
 .../Grouped/AssociatedProductsCollection.php  |   70 +
 app/code/core/Mage/Catalog/etc/api.xml        |  828 +++++
 app/code/core/Mage/Catalog/etc/wsdl.xml       | 2326 +++++++++++++
 app/code/core/Mage/Catalog/etc/wsi.xml        | 2866 +++++++++++++++++
 .../view/adminhtml/js/grouped-product.js      |  182 ++
 .../adminhtml/product/grouped/container.phtml |   32 +-
 .../adminhtml/product/grouped/grouped.phtml   |   64 +
 .../view/adminhtml/product/product.css        |    9 +
 .../Block/Adminhtml/Form/Field/Stock.php      |   35 +-
 .../CatalogInventory/Model/Stock/Item/Api.php |   75 +
 .../Model/Stock/Item/Api/V2.php               |   89 +
 .../core/Mage/CatalogInventory/etc/api.xml    |   81 +
 .../core/Mage/CatalogInventory/etc/wsdl.xml   |  102 +
 .../core/Mage/CatalogInventory/etc/wsi.xml    |  133 +
 .../view/frontend/form.mini.phtml             |    1 +
 .../core/Mage/Checkout/Model/Api/Resource.php |  218 ++
 .../Checkout/Model/Api/Resource/Customer.php  |  213 ++
 .../Checkout/Model/Api/Resource/Product.php   |  128 +
 .../core/Mage/Checkout/Model/Cart/Api.php     |  366 +++
 .../core/Mage/Checkout/Model/Cart/Api/V2.php  |   47 +
 .../Mage/Checkout/Model/Cart/Coupon/Api.php   |   97 +
 .../Checkout/Model/Cart/Coupon/Api/V2.php     |   38 +
 .../Mage/Checkout/Model/Cart/Customer/Api.php |  232 ++
 .../Checkout/Model/Cart/Customer/Api/V2.php   |   70 +
 .../Mage/Checkout/Model/Cart/Payment/Api.php  |  200 ++
 .../Checkout/Model/Cart/Payment/Api/V2.php    |   45 +
 .../Mage/Checkout/Model/Cart/Product/Api.php  |  330 ++
 .../Checkout/Model/Cart/Product/Api/V2.php    |   76 +
 .../Mage/Checkout/Model/Cart/Shipping/Api.php |  117 +
 .../Checkout/Model/Cart/Shipping/Api/V2.php   |   38 +
 app/code/core/Mage/Checkout/etc/api.xml       |  536 +++
 app/code/core/Mage/Checkout/etc/wsdl.xml      |  805 +++++
 app/code/core/Mage/Checkout/etc/wsi.xml       | 1018 ++++++
 .../core/Mage/Cms/Helper/Wysiwyg/Images.php   |    4 +-
 .../Mage/Cms/Model/Wysiwyg/Images/Storage.php |    2 +-
 .../Extension/Custom/Edit/Tab/Local.php       |    2 +-
 .../core/Mage/Connect/Model/Extension.php     |   12 +-
 app/code/core/Mage/Core/Block/Template.php    |   95 +-
 .../Core/Controller/Varien/Router/Base.php    |   23 +-
 app/code/core/Mage/Core/Helper/Data.php       |    7 +-
 app/code/core/Mage/Core/Model/App.php         |  182 +-
 .../core/Mage/Core/Model/App/Emulation.php    |    2 +-
 app/code/core/Mage/Core/Model/App/Options.php |  133 -
 app/code/core/Mage/Core/Model/Cache.php       |   26 +-
 app/code/core/Mage/Core/Model/Config.php      |  253 +-
 .../core/Mage/Core/Model/Config/Options.php   |  325 --
 .../core/Mage/Core/Model/Design/Fallback.php  |   84 +-
 .../Model/Design/Fallback/CachingProxy.php    |  137 +-
 .../core/Mage/Core/Model/Design/Package.php   |   96 +-
 app/code/core/Mage/Core/Model/Dir.php         |  311 ++
 app/code/core/Mage/Core/Model/Encryption.php  |   29 +-
 .../Core/Model/Layout/Argument/Processor.php  |    5 -
 .../core/Mage/Core/Model/Layout/Merge.php     |    2 +-
 .../Core/Model/Layout/ScheduledStructure.php  |   15 -
 app/code/core/Mage/Core/Model/Logger.php      |   28 +-
 app/code/core/Mage/Core/Model/Magento/Api.php |   49 +
 .../core/Mage/Core/Model/Magento/Api/V2.php   |   19 +-
 app/code/core/Mage/Core/Model/Observer.php    |    2 +-
 app/code/core/Mage/Core/Model/Store.php       |  167 +-
 app/code/core/Mage/Core/Model/Store/Api.php   |   96 +
 .../Model/Store/Api/V2.php}                   |   10 +-
 app/code/core/Mage/Core/Model/Store/Group.php |   18 +-
 app/code/core/Mage/Core/Model/Theme.php       |    3 +-
 .../Mage/Core/Model/Theme/Registration.php    |   49 -
 .../core/Mage/Core/Model/Theme/Service.php    |    6 +-
 app/code/core/Mage/Core/Model/Translate.php   |   17 +-
 app/code/core/Mage/Core/etc/api.xml           |  103 +
 app/code/core/Mage/Core/etc/config.xml        |   20 +-
 app/code/core/Mage/Core/etc/wsdl.xml          |  105 +
 app/code/core/Mage/Core/etc/wsi.xml           |  148 +
 .../core/Mage/Customer/Model/Address/Api.php  |  143 +
 .../Mage/Customer/Model/Address/Api/V2.php    |  163 +
 .../core/Mage/Customer/Model/Api/Resource.php |   90 +
 .../core/Mage/Customer/Model/Customer/Api.php |  196 ++
 .../Mage/Customer/Model/Customer/Api/V2.php   |   50 +
 .../core/Mage/Customer/Model/Group/Api.php    |   53 +
 .../core/Mage/Customer/Model/Group/Api/V2.php |   36 +
 app/code/core/Mage/Customer/etc/api.xml       |  179 +
 app/code/core/Mage/Customer/etc/wsdl.xml      |  354 ++
 app/code/core/Mage/Customer/etc/wsi.xml       |  507 +++
 .../Editor/Toolbar/HandlesHierarchy.php       |    7 +-
 .../Theme/Selector/List/Abstract.php          |   10 +-
 .../Theme/Selector/List/Available.php         |    6 +-
 .../Adminhtml/Theme/Selector/StoreView.php    |    7 +-
 .../Controller/Varien/Router/Standard.php     |   56 +-
 .../core/Mage/DesignEditor/Model/State.php    |    3 +-
 .../core/Mage/Directory/Model/Country/Api.php |   54 +
 .../Mage/Directory/Model/Country/Api/V2.php   |   36 +
 .../core/Mage/Directory/Model/Region/Api.php  |   62 +
 .../Mage/Directory/Model/Region/Api/V2.php    |   36 +
 app/code/core/Mage/Directory/etc/api.xml      |   85 +
 app/code/core/Mage/Directory/etc/wsdl.xml     |   90 +
 app/code/core/Mage/Directory/etc/wsi.xml      |  119 +
 .../Product/Edit/Tab/Downloadable/Links.php   |    2 +-
 .../core/Mage/Downloadable/Model/Link/Api.php |  277 ++
 .../Downloadable/Model/Link/Api/Uploader.php  |  129 +
 .../Mage/Downloadable/Model/Link/Api/V2.php   |   67 +
 .../Downloadable/Model/Link/Api/Validator.php |  286 ++
 app/code/core/Mage/Downloadable/etc/api.xml   |  156 +
 app/code/core/Mage/Downloadable/etc/wsdl.xml  |  193 ++
 app/code/core/Mage/Downloadable/etc/wsi.xml   |  220 ++
 app/code/core/Mage/GiftMessage/Model/Api.php  |  187 ++
 .../core/Mage/GiftMessage/Model/Api/V2.php    |  113 +
 app/code/core/Mage/GiftMessage/etc/api.xml    |   92 +
 app/code/core/Mage/GiftMessage/etc/wsdl.xml   |  123 +
 app/code/core/Mage/GiftMessage/etc/wsi.xml    |  161 +
 .../Block/Adminhtml/Types/Edit/Attributes.php |    2 +-
 .../Block/Adminhtml/Import/Edit/Before.php    |    8 +-
 .../Model/Import/Entity/Product.php           |   12 +-
 .../core/Mage/Index/Model/Lock/Storage.php    |   13 +-
 app/code/core/Mage/Install/Helper/Data.php    |   61 -
 app/code/core/Mage/Install/Model/Config.php   |   13 +-
 .../core/Mage/Install/Model/Installer.php     |    8 +-
 .../Mage/Install/Model/Installer/Config.php   |  125 +-
 .../Mage/Install/Model/Installer/Console.php  |   59 +-
 .../Install/controllers/IndexController.php   |    4 +-
 .../Install/controllers/WizardController.php  |   18 -
 app/code/core/Mage/Install/etc/install.xml    |   12 +-
 .../Adminhtml/Oauth/Admin/TokenController.php |    2 +-
 .../Oauth/AuthorizedTokensController.php      |    2 +-
 .../Adminhtml/Oauth/ConsumerController.php    |    2 +-
 .../core/Mage/Oauth/etc/adminhtml/menu.xml    |   12 +-
 app/code/core/Mage/Page/Block/Html.php        |    4 +-
 app/code/core/Mage/Page/Block/Html/Header.php |   59 +-
 .../System/Config/Fieldset/Global.php         |    2 +-
 .../Adminhtml/System/Config/Fieldset/Hint.php |    2 +-
 .../System/Config/Fieldset/Store.php          |    2 +-
 .../System/Config/Payflowlink/Info.php        |    4 +-
 app/code/core/Mage/Paypal/Model/Observer.php  |    2 +-
 .../Mage/Paypal/Model/Report/Settlement.php   |   37 +-
 .../Adminhtml/Paypal/ReportsController.php    |    2 +-
 .../Billing/Agreement/View/Tab/Info.php       |    2 +-
 .../Adminhtml/Recurring/Profile/Edit/Form.php |    2 +-
 .../core/Mage/Sales/Model/Api/Resource.php    |  122 +
 app/code/core/Mage/Sales/Model/Order.php      |   10 +-
 app/code/core/Mage/Sales/Model/Order/Api.php  |  267 ++
 .../core/Mage/Sales/Model/Order/Api/V2.php    |   36 +
 .../Mage/Sales/Model/Order/Creditmemo/Api.php |  258 ++
 .../Sales/Model/Order/Creditmemo/Api/V2.php   |   58 +
 .../Mage/Sales/Model/Order/Invoice/Api.php    |  326 ++
 .../Mage/Sales/Model/Order/Invoice/Api/V2.php |  106 +
 .../core/Mage/Sales/Model/Order/Shipment.php  |   11 +
 .../Mage/Sales/Model/Order/Shipment/Api.php   |  352 ++
 .../Sales/Model/Order/Shipment/Api/V2.php     |  122 +
 app/code/core/Mage/Sales/etc/api.xml          |  375 +++
 app/code/core/Mage/Sales/etc/wsdl.xml         | 1346 ++++++++
 app/code/core/Mage/Sales/etc/wsi.xml          | 1686 ++++++++++
 .../Catalog/Product/Edit/Tab/Tag.php          |    6 +-
 .../Catalog/Product/Edit/Tab/Tag/Customer.php |   11 +-
 .../Block/Adminhtml/Customer/Edit/Tab/Tag.php |    9 +-
 app/code/core/Mage/Tag/Model/Api.php          |  245 ++
 app/code/core/Mage/Tag/Model/Api/V2.php       |  109 +
 app/code/core/Mage/Tag/etc/api.xml            |  138 +
 app/code/core/Mage/Tag/etc/wsdl.xml           |  189 ++
 app/code/core/Mage/Tag/etc/wsi.xml            |  262 ++
 .../System/Design/Theme/Edit/Tab/Css.php      |   28 +-
 .../Usa/Block/Adminhtml/Dhl/Unitofmeasure.php |    2 +-
 .../Adminhtml/Role/Edit/Tab/Resource.php      |    6 +-
 .../Dispatcher/Rest/Presentation.php          |  188 +-
 .../Dispatcher/Rest/Presentation/Request.php  |  127 +
 .../Dispatcher/Rest/Presentation/Response.php |  160 +
 .../core/Mage/Webapi/Controller/Front.php     |    8 +-
 .../core/Mage/Webapi/Controller/Request.php   |    2 +
 .../Mage/Webapi/Controller/Request/Rest.php   |    8 +-
 .../Request/Rest/Interpreter/Json.php         |    2 +-
 .../Request/Rest/Interpreter/Xml.php          |    2 +-
 .../Mage/Webapi/Controller/Request/Soap.php   |    2 +-
 .../Router/{RouteAbstract.php => Route.php}   |    2 +-
 .../Webapi/Controller/Router/Route/Rest.php   |    2 +-
 .../Webapi/Model/Authorization/Config.php     |    2 +-
 .../Model/Authorization/Config/Reader.php     |    5 +-
 .../core/Mage/Webapi/Model/Config/Rest.php    |    8 +-
 .../core/Mage/Webapi/Model/Config/Soap.php    |    6 +-
 .../core/Mage/Webapi/Model/ConfigAbstract.php |   10 +-
 .../core/Mage/Webapi/Model/Soap/Server.php    |    2 +-
 .../core/Mage/Webapi/etc/adminhtml/menu.xml   |    6 +-
 app/code/core/Mage/Webapi/etc/config.xml      |    7 +-
 app/design/adminhtml/default/basic/boxes.css  |   45 +
 .../iphone/Mage_CatalogSearch/form.mini.phtml |   16 +-
 .../modern/Mage_CatalogSearch/form.mini.phtml |   13 +-
 dev/shell/install.php                         |    3 +-
 .../Magento/Test/Annotation/AppIsolation.php  |  119 +-
 .../framework/Magento/Test/Bootstrap.php      |  113 +-
 .../framework/Magento/Test/Helper/Api.php     |  170 +
 .../framework/Magento/Test/Helper/Eav.php     |   49 +
 .../framework/Magento/Test/ObjectManager.php  |   22 -
 .../Test/TestCase/ControllerAbstract.php      |   13 +-
 .../Workaround/Cleanup/StaticProperties.php   |  135 +
 .../Cleanup/TestCaseProperties.php}           |    4 +-
 .../Test/Workaround/Segfault.php}             |   13 +-
 dev/tests/integration/framework/bootstrap.php |    8 +-
 .../testsuite/Magento/Test/BootstrapTest.php  |   60 +-
 .../Magento/Test/ClearPropertiesTest.php      |  118 -
 .../Magento/Test/ObjectManagerTest.php        |   18 +-
 .../Cleanup/TestCasePropertiesTest.php        |   87 +
 .../Cleanup}/_files/DummyTestCase.php         |   29 +-
 .../Block/Catalog/Category/TreeTest.php       |    2 +-
 .../Block/Notification/BaseurlTest.php        |   18 +-
 .../Mage/Adminhtml/Block/Page/HeadTest.php    |   32 +
 .../Block/Promo/Quote/Edit/Tab/LabelsTest.php |   33 +
 .../Block/Rating/Edit/Tab/FormTest.php        |   33 +
 .../Sales/Order/Create/Form/AbstractTest.php  |    2 +
 .../Block/Widget/Form/ContainerTest.php       |    6 +-
 .../Catalog/CategoryControllerTest.php        |    3 +-
 .../Product/AttributeControllerTest.php       |   12 +-
 .../Backend/Block/System/Config/FormStub.php  |    1 -
 .../Backend/Block/System/Config/FormTest.php  |    4 +-
 .../Block/Widget/Grid/MassactionTest.php      |   67 +-
 .../Mage/Backend/Block/Widget/GridTest.php    |   66 +-
 .../Backend/Block/_files/backend_theme.php    |   29 +
 .../Model/Config/Backend/BaseurlTest.php      |  148 +
 .../Mage/Backend/Utility/Controller.php       |    2 +-
 .../Mage/Captcha/Model/ObserverTest.php       |   18 +-
 .../Catalog/Model/Category/Api/V2Test.php     |   79 +
 .../Mage/Catalog/Model/Category/ApiTest.php   |  502 +++
 .../Model/Category/Attribute/ApiTest.php      |  104 +
 .../Model/Category/_files/category_data.php   |  104 +
 .../Filter/Price/AlgorithmAdvancedTest.php    |    1 -
 .../Product/Api/Attribute/TierPriceTest.php   |   87 +
 .../Product/Api/AttributeSetCRUDTest.php      |  235 ++
 .../Model/Product/Api/AttributeTest.php       |   57 +
 .../Model/Product/Api/BackorderStatusTest.php |   77 +
 .../Model/Product/Api/ConfigurableTest.php    |   62 +
 .../Product/Api/DownloadableLinkCRUDTest.php  |  127 +
 .../Model/Product/Api/Helper/Configurable.php |  192 ++
 .../Model/Product/Api/Helper/Simple.php       |  124 +
 .../Catalog/Model/Product/Api/ImageTest.php   |  185 ++
 .../Catalog/Model/Product/Api/SimpleTest.php  |  458 +++
 .../Catalog/Model/Product/Api/TagCRUDTest.php |  103 +
 .../Model/Product/Api/TestCaseAbstract.php    |  182 ++
 .../Model/Product/Api/_files/AttributeSet.php |   40 +
 .../Api/_files/AttributeSet_rollback.php      |   12 +-
 .../Model/Product/Api/_files/CustomOption.php |   34 +
 .../Product/Api/_files/CustomOptionValue.php  |   44 +
 .../Api/_files/CustomOptionValue_rollback.php |   26 +
 .../Api/_files/CustomOption_rollback.php      |   25 +
 .../Api/_files/DownloadableWithLinks.php      |   66 +
 .../_files/DownloadableWithLinks_rollback.php |   25 +
 .../Model/Product/Api/_files/LinkCRUD.php     |   41 +
 .../Product/Api/_files/LinkCRUD_rollback.php  |   26 +
 .../Api/_files/ProductAttributeData.php       |  148 +
 .../Model/Product/Api/_files/ProductData.php  |  147 +
 .../Api/_files/ProductWithOptionCrud.php      |   71 +
 .../_files/ProductWithOptionCrud_rollback.php |   27 +
 .../Model/Product/Api/_files/TagCRUD.php      |   41 +
 .../Product/Api/_files/TagCRUD_rollback.php   |   26 +
 .../Product/Api/_files/_data/files/book.pdf   |    0
 .../Product/Api/_files/_data/files/image.jpg  |  Bin 0 -> 157486 bytes
 .../_files/_data/files/images/test.bmp.jpg    |  Bin 0 -> 6966 bytes
 .../_files/_data/files/images/test.jpg.jpg    |  Bin 0 -> 1621 bytes
 .../_files/_data/files/images/test.php.jpg    |   41 +
 .../_files/_data/files/images/test.png.jpg    |  Bin 0 -> 2801 bytes
 .../Product/Api/_files/_data/files/song.mp3   |    0
 .../Product/Api/_files/_data/files/test.txt   |    1 +
 .../_data/product_configurable_all_fields.php |   38 +
 .../_data/simple_product_all_fields_data.php  |   82 +
 .../Api/_files/_data/simple_product_data.php  |   42 +
 .../simple_product_inventory_use_config.php   |   63 +
 ...simple_product_manage_stock_use_config.php |   59 +
 .../simple_product_special_chars_data.php     |   65 +
 .../Api/_files/_data/xml/AttributeSet.xml     |   85 +
 .../Api/_files/_data/xml/CustomOption.xml     |  147 +
 .../_files/_data/xml/CustomOptionTypes.xml    |   69 +
 .../_files/_data/xml/CustomOptionValue.xml    |   86 +
 .../Product/Api/_files/_data/xml/LinkCRUD.xml |  134 +
 .../Product/Api/_files/_data/xml/TagCRUD.xml  |   80 +
 .../attribute_set_with_configurable.php       |   83 +
 .../Api/_files/store_on_new_website.php       |   64 +
 .../_files/store_on_new_website_rollback.php  |   27 +
 .../Mage/Catalog/Model/Product/ApiTest.php    |  116 +
 .../Model/Product/Attribute/ApiTest.php       |  343 ++
 .../Product/Attribute/Backend/MediaTest.php   |    5 +-
 .../Model/Product/Attribute/Media/ApiTest.php |  176 +
 .../Attribute/Tierprice/Api/V2Test.php        |   84 +
 .../Product/Attribute/Tierprice/ApiTest.php   |  103 +
 .../Attribute/_files/select_attribute.php     |   55 +
 .../Catalog/Model/Product/Link/ApiTest.php    |  208 ++
 .../Catalog/Model/Product/Option/ApiTest.php  |  407 +++
 .../Catalog/Model/Product/Type/ApiTest.php    |   54 +
 .../Mage/Catalog/_files/categories.php        |    6 +
 .../Mage/Catalog/_files/product_simple.php    |    4 +
 .../controllers/_files/attribute_system.php   |    6 +-
 .../attribute_system_with_applyto_data.php    |    6 +-
 .../_files/attribute_user_defined.php         |    4 +-
 .../Model/Stock/Item/ApiTest.php              |   53 +
 .../controllers/ResultControllerTest.php      |    1 -
 .../Mage/Checkout/Model/Cart/AbstractTest.php |   42 +
 .../Cart/Api/_files/license_agreement.php     |   38 +
 .../Mage/Checkout/Model/Cart/ApiTest.php      |  445 +++
 .../Checkout/Model/Cart/Coupon/ApiTest.php    |  105 +
 .../Checkout/Model/Cart/Customer/ApiTest.php  |  116 +
 .../Checkout/Model/Cart/Payment/ApiTest.php   |   91 +
 .../Checkout/Model/Cart/Product/ApiTest.php   |  142 +
 .../Checkout/Model/Cart/Shipping/ApiTest.php  |  116 +
 .../Checkout/_files/discount_10percent.php    |   42 +
 .../testsuite/Mage/Checkout/_files/quote.php  |   34 +
 .../Checkout/_files/quote_with_address.php    |   46 +
 .../_files/quote_with_address_saved.php       |   32 +
 .../_files/quote_with_ccsave_payment.php      |   38 +
 .../_files/quote_with_check_payment.php       |   44 +
 .../quote_with_check_payment_rollback.php     |   10 +-
 .../Mage/Cms/Helper/Wysiwyg/ImagesTest.php    |   41 +
 .../Cms/Model/Wysiwyg/Images/StorageTest.php  |   10 +
 .../Mage/Core/Block/AbstractTest.php          |   40 +-
 .../Mage/Core/Block/TemplateTest.php          |   68 -
 .../Mage/Core/Controller/RequestHttpTest.php  |   10 +-
 .../Core/Controller/Varien/ActionTest.php     |   10 +-
 .../Mage/Core/Model/App/AreaTest.php          |   24 -
 .../testsuite/Mage/Core/Model/AppTest.php     |   43 +-
 .../Mage/Core/Model/Config/OptionsTest.php    |  151 -
 .../Mage/Core/Model/ConfigFactoryTest.php     |    9 +-
 .../testsuite/Mage/Core/Model/ConfigTest.php  |  272 +-
 .../Mage/Core/Model/Design/FallbackTest.php   |   63 +-
 .../Core/Model/Design/PackageFallbackTest.php |   17 +-
 .../Core/Model/Design/PackageMergingTest.php  |   21 +-
 .../Model/Design/PackagePublicationTest.php   |  146 +-
 .../Mage/Core/Model/Design/PackageTest.php    |  111 +-
 .../Core/Model/Email/Template/FilterTest.php  |   48 +-
 .../Mage/Core/Model/Email/TemplateTest.php    |   30 +-
 .../Mage/Core/Model/Email/_files/themes.php   |   29 +
 .../Mage/Core/Model/Layout/MergeTest.php      |   61 +-
 .../Mage/Core/Model/LayoutArgumentTest.php    |  111 -
 .../Mage/Core/Model/LayoutDirectivesTest.php  |  241 ++
 .../testsuite/Mage/Core/Model/LayoutTest.php  |  302 +-
 .../Mage/Core/Model/Magento/ApiTest.php       |   42 +
 .../Mage/Core/Model/ObserverTest.php          |   30 +-
 .../Mage/Core/Model/Store/ApiTest.php         |   68 +
 .../Model/Store/GroupTest.php}                |   38 +-
 .../testsuite/Mage/Core/Model/StoreTest.php   |   39 +-
 .../Mage/Core/Model/Theme/CollectionTest.php  |    2 -
 .../testsuite/Mage/Core/Model/ThemeTest.php   |   13 +-
 .../Mage/Core/Model/TranslateTest.php         |   22 +-
 .../test/default/Mage_Core/layout.xml         |  220 --
 .../test/default/Mage_Core/test.phtml         |    2 +-
 .../Mage/Core/Model/_files/design/themes.php  |   33 +
 .../fallback/pub/{js => lib}/mage/script.js   |    0
 .../action_for_anonymous_parent_block.xml}    |   20 +-
 .../layout_directives_test/arguments.xml      |   39 +
 .../arguments_complex_values.xml              |   59 +
 .../arguments_object_type.xml                 |   41 +
 .../arguments_object_type_updaters.xml        |   54 +
 .../arguments_url_type.xml                    |   55 +
 .../get_block.xml}                            |   10 +-
 .../get_block_exception.xml                   |   31 +
 .../_files/layout_directives_test/move.xml    |   48 +
 .../move_alias_broken.xml                     |   32 +
 .../move_broken.xml}                          |   11 +-
 .../layout_directives_test/move_new_alias.xml |   32 +
 .../move_the_same_alias.xml                   |   32 +
 .../_files/layout_directives_test/remove.xml  |   38 +
 .../layout_directives_test/remove_broken.xml  |   33 +
 .../_files/layout_directives_test/render.xml  |   47 +
 .../sort_after_after.xml                      |   38 +
 .../sort_after_previous.xml                   |   39 +
 .../sort_before_after.xml                     |   38 +
 .../sort_before_before.xml                    |   39 +
 .../custom}/local.xml                         |   10 +-
 .../custom/prohibited.filename.xml            |   39 +
 .../custom => local_config}/local.xml         |   10 +-
 .../z.xml                                     |   10 +-
 .../a.xml                                     |   10 +-
 .../b.xml                                     |   12 +-
 .../no_local_config/custom/local.xml          |   39 +
 .../custom/local.xml                          |   29 -
 .../Core/Model/_files/sort_special_cases.xml  |   84 -
 .../Model/_files/valid_layout_updates.xml     |   73 -
 .../testsuite/Mage/Core/Utility/Theme.php     |  211 --
 .../media_for_change.php}                     |   46 +-
 .../Core/_files/media_for_change_rollback.php |   29 +
 .../Mage/Customer/Model/Address/ApiTest.php   |  232 ++
 .../Mage/Customer/Model/Customer/ApiTest.php  |  166 +
 .../Mage/Customer/Model/Group/ApiTest.php     |   46 +
 .../Mage/Customer/_files/customer_address.php |    4 +-
 .../_files/customer_two_addresses.php         |    4 +-
 .../Mage/Customer/_files/two_customers.php    |   45 +
 .../Mage/Directory/Model/Country/ApiTest.php  |   43 +
 .../Mage/Directory/Model/Region/ApiTest.php   |   43 +
 .../Attribute/Edit/Main/AbstractTest.php      |    2 +
 .../Mage/GiftMessage/Model/ApiTest.php        |  167 +
 .../Model/Export/Entity/ProductTest.php       |    2 -
 .../Mage/Index/Model/Process/FileTest.php     |    6 +-
 .../Mage/Install/IndexControllerTest.php      |   39 +
 .../Install/Model/Installer/ConfigTest.php    |   70 +
 .../controllers/WizardControllerTest.php      |   48 +-
 .../Mage/Newsletter/Model/QueueTest.php       |    7 +-
 .../testsuite/Mage/Page/Block/HtmlTest.php    |   81 +
 .../Paypal/ReportsControllerTest.php          |   47 +
 .../Paypal/Model/Report/SettlementTest.php    |   63 +
 .../Sales/Model/Order/Api/_files/customer.php |   65 +
 .../Order/Api/_files/customer_rollback.php    |   25 +
 .../Order/Api/_files/multiple_invoices.php    |   50 +
 .../Api/_files/multiple_invoices_rollback.php |   25 +
 .../Sales/Model/Order/Api/_files/order.php    |   78 +
 .../Model/Order/Api/_files/order_rollback.php |   28 +
 .../Order/Api/_files/order_with_shipping.php  |   71 +
 .../_files/order_with_shipping_rollback.php   |   31 +
 .../Model/Order/Api/_files/product_simple.php |   48 +
 .../Api/_files/product_simple_rollback.php    |   24 +
 .../Order/Api/_files/product_virtual.php      |   46 +
 .../Api/_files/product_virtual_rollback.php   |   24 +
 .../Sales/Model/Order/Api/_files/shipment.php |   35 +
 .../Order/Api/_files/shipment_rollback.php    |   32 +
 .../Mage/Sales/Model/Order/ApiTest.php        |  221 ++
 .../Sales/Model/Order/Creditmemo/ApiTest.php  |  357 ++
 .../Mage/Sales/Model/Order/CreditmemoTest.php |    2 +-
 .../Sales/Model/Order/Invoice/ApiTest.php     |  319 ++
 .../Mage/Sales/Model/Order/InvoiceTest.php    |    2 +-
 .../Mage/Sales/Model/Order/OrderTest.php      |    2 +-
 .../Sales/Model/Order/Shipment/ApiTest.php    |  279 ++
 .../Mage/Sales/Model/Order/ShipmentTest.php   |    2 +-
 .../testsuite/Mage/Sales/_files/invoice.php   |   35 +
 .../Mage/Sales/_files/invoice_verisign.php    |   36 +
 .../testsuite/Mage/Sales/_files/order.php     |   13 +-
 .../Model/Resource/Catalog/ProductTest.php    |    1 -
 .../Mage/Tag/Model/Api/_files/tag.php         |   29 +
 .../testsuite/Mage/Tag/Model/ApiTest.php      |   81 +
 .../Block/Adminhtml/Dhl/UnitofmeasureTest.php |   37 +
 .../Block/Adminhtml/FormTestAbstract.php      |    4 +-
 .../Block/Adminhtml/Role/Edit/FormTest.php    |    2 +-
 .../Adminhtml/Role/Edit/Tab/MainTest.php      |    6 +-
 .../Adminhtml/Role/Edit/Tab/ResourceTest.php  |    6 +-
 .../Block/Adminhtml/User/Edit/FormTest.php    |    2 +-
 .../Adminhtml/User/Edit/Tab/MainTest.php      |    8 +-
 .../Block/Adminhtml/User/Edit/TabsTest.php    |   10 +-
 .../Webapi/Block/Adminhtml/User/EditTest.php  |   10 +-
 .../Mage/Webapi/Helper/ConfigTest.php         |    2 +-
 .../testsuite/Mage/Webapi/Helper/DataTest.php |   26 +-
 .../Mage/Webapi/Model/Acl/RoleTest.php        |    8 +-
 .../Mage/Webapi/Model/Acl/RuleTest.php        |    8 +-
 .../Mage/Webapi/Model/Acl/UserTest.php        |    8 +-
 .../Config/Reader/Rest/RouteGeneratorTest.php |    4 +-
 .../Mage/Webapi/Model/Config/RestTest.php     |   32 +-
 .../Webapi/Model/Config/Soap/DataTest.php     |    2 +-
 .../Mage/Webapi/Model/Config/SoapTest.php     |   32 +-
 .../Webapi/Model/Resource/Acl/RoleTest.php    |   10 +-
 .../Webapi/Model/Resource/Acl/RuleTest.php    |    6 +-
 .../Webapi/Model/Soap/AutoDiscoverTest.php    |   43 +-
 .../Model/Soap/Security/UsernameTokenTest.php |   43 +-
 .../Mage/Webapi/Model/Soap/ServerTest.php     |   14 +-
 .../empty_property_description/class.php      |    2 +-
 .../autodiscovery/empty_var_tags/class.php    |    2 +-
 .../empty_var_tags/data_type.php              |    2 +-
 .../invalid_deprecation_policy/class.php      |    2 +-
 .../autodiscovery/no_resources/class.php      |    2 +-
 .../reference_to_invalid_type/class.php       |    2 +-
 .../file_with_classes.php                     |    4 +-
 .../resource_with_invalid_interface.php       |    8 +-
 .../_files/resource_with_invalid_name.php     |    2 +-
 .../Mage/Widget/Model/WidgetTest.php          |    7 +-
 .../testsuite/Mage/Widget/_files/themes.php   |   33 +
 .../Mage/Wishlist/Block/AbstractTest.php      |    4 +-
 .../testsuite/Magento/Di/GeneratorTest.php    |   12 +-
 .../Magento/Filesystem/Adapter/LocalTest.php  |   29 +-
 .../integration/testsuite/MemoryUsageTest.php |  192 ++
 .../Varien/Db/Adapter/Pdo/MysqlTest.php       |   60 +-
 .../Varien/Image/Adapter/InterfaceTest.php    |    2 +-
 .../integrity/modular/AclConfigFilesTest.php  |    2 -
 .../integrity/modular/TemplateFilesTest.php   |    6 +-
 dev/tests/performance/run_scenarios.php       |   26 +-
 .../CodingStandard/Tool/CodeSniffer.php       |   10 +
 .../CodingStandard/Tool/CodeSnifferTest.php   |    5 +
 .../testsuite/Js/_files/blacklist/ee.txt      |    2 -
 .../static/testsuite/Legacy/ConfigTest.php    |    3 +
 .../testsuite/Legacy/EmailTemplateTest.php    |    3 +-
 .../static/testsuite/Legacy/LayoutTest.php    |    3 +-
 .../testsuite/Legacy/ObsoleteCodeTest.php     |  285 +-
 .../Legacy/_files/obsolete_classes.php        |  843 ++---
 .../Legacy/_files/obsolete_constants.php      |   86 +-
 .../Legacy/_files/obsolete_methods.php        |  806 ++---
 .../Legacy/_files/obsolete_properties.php     |  102 +-
 .../testsuite/Legacy/_files/words_core.xml    |    3 +
 .../testsuite/Php/Exemplar/CodeStyleTest.php  |    2 +-
 .../static/testsuite/Php/LiveCodeTest.php     |    2 +-
 .../testsuite/Php/_files/blacklist/common.txt |   11 +-
 .../testsuite/Php/_files/whitelist/common.txt |   30 +-
 .../Magento/Test/Helper/ObjectManager.php     |    2 +
 .../Mage/Captcha/Helper/DataTest.php          |  118 +-
 .../testsuite/Mage/Captcha/Model/ZendTest.php |   15 +-
 .../Product/Attribute/Backend/MediaTest.php   |    4 +
 .../Model/Product/Type/ConfigurableTest.php   |    4 +-
 .../Mage/Core/Block/AbstractTest.php          |   40 +-
 .../Mage/Core/Block/TemplateTest.php          |  104 +
 .../Block/_files/template_test_assign.phtml   |    3 +-
 .../Mage/Core/Model/App/OptionsTest.php       |   69 -
 .../testsuite/Mage/Core/Model/AppTest.php     |   67 +-
 .../testsuite/Mage/Core/Model/CacheTest.php   |  150 +-
 .../Mage/Core/Model/Config/OptionsTest.php    |  114 -
 .../testsuite/Mage/Core/Model/ConfigTest.php  |   32 +-
 .../Design/Fallback/CachingProxyTest.php      |  212 +-
 .../testsuite/Mage/Core/Model/DirTest.php     |  124 +
 .../Mage/Core/Model/EncryptionTest.php        |   71 +
 .../testsuite/Mage/Core/Model/LoggerTest.php  |   26 +-
 .../testsuite/Mage/Core/Model/ThemeTest.php   |   25 +-
 .../Mage/Core/Model/Validator/FactoryTest.php |    3 +-
 .../Controller/Varien/Router/StandardTest.php |   98 +-
 .../Mage/DesignEditor/Model/StateTest.php     |   17 +-
 .../Mage/Index/Model/Lock/StorageTest.php     |   43 +-
 .../Mage/Page/Block/Html/HeaderTest.php       |   19 +-
 .../Adminhtml/Role/Edit/Tab/ResourceTest.php  |    8 +-
 .../Block/Adminhtml/Role/Edit/TabsTest.php    |    6 +-
 .../Webapi/Block/Adminhtml/Role/EditTest.php  |   14 +-
 .../Mage/Webapi/Block/Adminhtml/RoleTest.php  |   12 +-
 .../Webapi/Block/Adminhtml/User/EditTest.php  |   12 +-
 .../Mage/Webapi/Block/Adminhtml/UserTest.php  |   12 +-
 .../Dispatcher/ErrorProcessorTest.php         |   42 +-
 .../Webapi/Controller/Dispatcher/RestTest.php |   10 +-
 .../Dispatcher/Soap/AuthenticationTest.php    |    2 +-
 .../Dispatcher/Soap/HandlerTest.php           |    2 +-
 .../Webapi/Controller/Dispatcher/SoapTest.php |    2 +-
 .../Mage/Webapi/Controller/FrontTest.php      |   20 +-
 .../Request/Rest/Interpreter/FactoryTest.php  |    2 +-
 .../Request/Rest/Interpreter/JsonTest.php     |    6 +-
 .../Request/Rest/Interpreter/XmlTest.php      |    4 +-
 .../Webapi/Controller/Request/RestTest.php    |   48 +-
 .../Webapi/Controller/Request/SoapTest.php    |    6 +-
 .../Mage/Webapi/Controller/RequestTest.php    |   14 +-
 .../Controller/Response/FactoryTest.php       |   10 +-
 .../Response/Rest/Renderer/FactoryTest.php    |    8 +-
 .../Response/Rest/Renderer/JsonTest.php       |    8 +-
 .../Response/Rest/Renderer/XmlTest.php        |    2 +-
 .../Webapi/Controller/Response/RestTest.php   |   16 +-
 .../Mage/Webapi/Controller/ResponseTest.php   |   10 +-
 .../Controller/Router/Route/RestTest.php      |   12 +-
 .../{Route/ApiTypeTest.php => RouteTest.php}  |   10 +-
 .../Webapi/Model/Acl/Role/FactoryTest.php     |    4 +-
 .../Model/Acl/Role/InRoleUserUpdaterTest.php  |    2 +-
 .../Mage/Webapi/Model/Acl/RoleTest.php        |    6 +-
 .../Mage/Webapi/Model/Acl/RuleTest.php        |   12 +-
 .../Webapi/Model/Acl/User/FactoryTest.php     |    2 +-
 .../Mage/Webapi/Model/Acl/UserTest.php        |   12 +-
 .../Model/Authorization/Config/ReaderTest.php |    4 +-
 .../Webapi/Model/Authorization/ConfigTest.php |   12 +-
 .../Authorization/Loader/ResourceTest.php     |    8 +-
 .../Model/Authorization/Loader/RoleTest.php   |   10 +-
 .../Model/Authorization/Loader/RuleTest.php   |    4 +-
 .../Webapi/Model/Resource/Acl/RoleTest.php    |   10 +-
 .../Webapi/Model/Resource/Acl/RuleTest.php    |   18 +-
 .../Webapi/Model/Resource/Acl/UserTest.php    |    8 +-
 .../Webapi/Model/Rest/Oauth/ServerTest.php    |    6 +-
 .../Webapi/Model/Soap/AutoDiscoverTest.php    |   10 +-
 .../Mage/Webapi/Model/Soap/FaultTest.php      |   20 +-
 .../Model/Soap/Security/UsernameTokenTest.php |    6 +-
 .../Mage/Webapi/Model/Soap/ServerTest.php     |   53 +-
 .../ComplexTypeStrategy/ConfigBasedTest.php   |    6 +-
 .../Mage/Webapi/Model/Source/Acl/RoleTest.php |    4 +-
 .../unit/testsuite/Magento/ShellTest.php      |   98 +-
 index.php                                     |   13 +-
 lib/Magento/Filesystem/Adapter/Local.php      |    7 +-
 lib/Magento/ObjectManager/Zend.php            |    7 +-
 lib/Magento/Shell.php                         |   53 +-
 lib/Varien/Data/Form/Element/Date.php         |   23 +-
 pub/.htaccess                                 |    5 -
 pub/get.php                                   |   32 +-
 pub/index.php                                 |    5 +-
 pub/lib/.htaccess                             |    6 +
 pub/lib/jquery/jstree/jquery.hotkeys.js       |   99 +
 pub/lib/mage/adminhtml/grid.js                |   17 +
 pub/lib/mage/backend/action-link.js           |    2 +-
 pub/lib/mage/backend/multisuggest.js          |  152 +
 pub/lib/mage/backend/suggest.js               |  298 +-
 pub/lib/mage/backend/tree-suggest.js          |  169 +
 pub/lib/mage/mage.js                          |   78 +-
 pub/lib/mage/validation.js                    |    6 -
 759 files changed, 56348 insertions(+), 8523 deletions(-)
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Buttons.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Editroles.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Grid/Role.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Role.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Role/Grid/User.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Roles.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Tab/Roleinfo.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesedit.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesusers.php
 rename app/code/core/Mage/{Core/Block/Template/Zend.php => Adminhtml/Block/Api/User.php} (57%)
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/User/Edit.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Form.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Roles.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tabs.php
 create mode 100644 app/code/core/Mage/Adminhtml/Block/Api/User/Grid.php
 delete mode 100644 app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Group.php
 delete mode 100644 app/code/core/Mage/Adminhtml/Block/Html/Date.php
 delete mode 100644 app/code/core/Mage/Adminhtml/Block/Html/Select.php
 delete mode 100644 app/code/core/Mage/Adminhtml/Block/Messages.php
 delete mode 100644 app/code/core/Mage/Adminhtml/Model/Extension.php
 create mode 100644 app/code/core/Mage/Adminhtml/controllers/Api/RoleController.php
 create mode 100644 app/code/core/Mage/Adminhtml/controllers/Api/UserController.php
 create mode 100644 app/code/core/Mage/Adminhtml/view/adminhtml/api/role_users_grid_js.phtml
 create mode 100644 app/code/core/Mage/Adminhtml/view/adminhtml/api/roleinfo.phtml
 rename dev/tests/integration/testsuite/Mage/Core/Block/_files/frontend/default/demo/theme.xml => app/code/core/Mage/Adminhtml/view/adminhtml/api/roles.phtml (61%)
 create mode 100644 app/code/core/Mage/Adminhtml/view/adminhtml/api/rolesedit.phtml
 rename dev/tests/integration/testsuite/Mage/Core/Block/_files/frontend/default/demo/Mage_Core/dummy.phtml => app/code/core/Mage/Adminhtml/view/adminhtml/api/rolesusers.phtml (83%)
 create mode 100644 app/code/core/Mage/Adminhtml/view/adminhtml/api/user_roles_grid_js.phtml
 create mode 100644 app/code/core/Mage/Adminhtml/view/adminhtml/api/userinfo.phtml
 rename dev/tests/integration/testsuite/Mage/Core/Block/_files/adminhtml/default/basic/Mage_Core/dummy.phtml => app/code/core/Mage/Adminhtml/view/adminhtml/api/usernroles.phtml (72%)
 delete mode 100644 app/code/core/Mage/Adminhtml/view/adminhtml/resetforgottenpassword.phtml
 create mode 100644 app/code/core/Mage/Api/Controller/Action.php
 create mode 100644 app/code/core/Mage/Api/Exception.php
 create mode 100644 app/code/core/Mage/Api/Helper/Data.php
 create mode 100644 app/code/core/Mage/Api/Model/Acl.php
 create mode 100644 app/code/core/Mage/Api/Model/Acl/Resource.php
 create mode 100644 app/code/core/Mage/Api/Model/Acl/Role.php
 create mode 100644 app/code/core/Mage/Api/Model/Acl/Role/Generic.php
 create mode 100644 app/code/core/Mage/Api/Model/Acl/Role/Group.php
 create mode 100644 app/code/core/Mage/Api/Model/Acl/Role/Registry.php
 create mode 100644 app/code/core/Mage/Api/Model/Acl/Role/User.php
 create mode 100644 app/code/core/Mage/Api/Model/Config.php
 create mode 100644 app/code/core/Mage/Api/Model/Resource/Abstract.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Acl.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Acl/Role.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Acl/Role/Collection.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Permissions/Collection.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Role.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Role/Collection.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Roles.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Roles/Collection.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Roles/User/Collection.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Rules.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/Rules/Collection.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/User.php
 create mode 100755 app/code/core/Mage/Api/Model/Resource/User/Collection.php
 create mode 100644 app/code/core/Mage/Api/Model/Role.php
 create mode 100644 app/code/core/Mage/Api/Model/Roles.php
 create mode 100644 app/code/core/Mage/Api/Model/Rules.php
 create mode 100644 app/code/core/Mage/Api/Model/Server.php
 create mode 100644 app/code/core/Mage/Api/Model/Server/Adapter/Soap.php
 create mode 100644 app/code/core/Mage/Api/Model/Server/Adapter/Soap/Wsi.php
 create mode 100644 app/code/core/Mage/Api/Model/Server/Handler/Soap.php
 create mode 100644 app/code/core/Mage/Api/Model/Server/Handler/Soap/Wsi.php
 create mode 100644 app/code/core/Mage/Api/Model/Server/HandlerAbstract.php
 create mode 100644 app/code/core/Mage/Api/Model/Session.php
 create mode 100644 app/code/core/Mage/Api/Model/User.php
 create mode 100644 app/code/core/Mage/Api/Model/Wsdl/Config.php
 create mode 100644 app/code/core/Mage/Api/Model/Wsdl/Config/Base.php
 create mode 100644 app/code/core/Mage/Api/Model/Wsdl/Config/Element.php
 create mode 100644 app/code/core/Mage/Api/controllers/Soap/WsiController.php
 create mode 100644 app/code/core/Mage/Api/controllers/SoapController.php
 create mode 100644 app/code/core/Mage/Api/etc/adminhtml.xml
 create mode 100644 app/code/core/Mage/Api/etc/adminhtml/menu.xml
 create mode 100644 app/code/core/Mage/Api/etc/adminhtml/system.xml
 create mode 100644 app/code/core/Mage/Api/etc/api.xml
 create mode 100644 app/code/core/Mage/Api/etc/config.xml
 create mode 100644 app/code/core/Mage/Api/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Api/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Api/locale/de_DE/Mage_Api.csv
 create mode 100644 app/code/core/Mage/Api/locale/en_US/Mage_Api.csv
 create mode 100644 app/code/core/Mage/Api/locale/es_ES/Mage_Api.csv
 create mode 100644 app/code/core/Mage/Api/locale/fr_FR/Mage_Api.csv
 create mode 100644 app/code/core/Mage/Api/locale/nl_NL/Mage_Api.csv
 create mode 100644 app/code/core/Mage/Api/locale/pt_BR/Mage_Api.csv
 create mode 100644 app/code/core/Mage/Api/locale/zh_CN/Mage_Api.csv
 create mode 100644 app/code/core/Mage/Api/sql/api_setup/install-1.6.0.0.php
 create mode 100644 app/code/core/Mage/Backend/Block/Catalog/Product/Tab/Container.php
 create mode 100644 app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Button.php
 create mode 100644 app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Grip.php
 create mode 100644 app/code/core/Mage/Bundle/view/adminhtml/css/bundle-product.css
 create mode 100644 app/code/core/Mage/Bundle/view/adminhtml/js/bundle-product.js
 create mode 100644 app/code/core/Mage/Catalog/Block/Product/Grouped/AssociatedProducts.php
 create mode 100644 app/code/core/Mage/Catalog/Block/Product/Grouped/AssociatedProducts/Grid.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Api/Resource.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Category/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Category/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Category/Attribute/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Category/Attribute/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Attribute/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Attribute/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Attribute/Media/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Attribute/Media/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Attribute/Set/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Attribute/Set/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Link/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Link/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Option/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Option/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Option/Value/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Option/Value/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Type/Api.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Product/Type/Api/V2.php
 create mode 100644 app/code/core/Mage/Catalog/Model/Resource/Product/Type/Grouped/AssociatedProductsCollection.php
 create mode 100644 app/code/core/Mage/Catalog/etc/api.xml
 create mode 100644 app/code/core/Mage/Catalog/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Catalog/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Catalog/view/adminhtml/js/grouped-product.js
 rename dev/tests/integration/testsuite/Mage/Core/Block/_files/adminhtml/default/basic/theme.xml => app/code/core/Mage/Catalog/view/adminhtml/product/grouped/container.phtml (66%)
 create mode 100644 app/code/core/Mage/Catalog/view/adminhtml/product/grouped/grouped.phtml
 create mode 100644 app/code/core/Mage/CatalogInventory/Model/Stock/Item/Api.php
 create mode 100644 app/code/core/Mage/CatalogInventory/Model/Stock/Item/Api/V2.php
 create mode 100644 app/code/core/Mage/CatalogInventory/etc/api.xml
 create mode 100644 app/code/core/Mage/CatalogInventory/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/CatalogInventory/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Checkout/Model/Api/Resource.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Api/Resource/Customer.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Api/Resource/Product.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Api.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Api/V2.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Coupon/Api.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Coupon/Api/V2.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Customer/Api.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Customer/Api/V2.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Payment/Api.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Payment/Api/V2.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Product/Api.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Product/Api/V2.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Shipping/Api.php
 create mode 100644 app/code/core/Mage/Checkout/Model/Cart/Shipping/Api/V2.php
 create mode 100644 app/code/core/Mage/Checkout/etc/api.xml
 create mode 100644 app/code/core/Mage/Checkout/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Checkout/etc/wsi.xml
 delete mode 100644 app/code/core/Mage/Core/Model/App/Options.php
 delete mode 100644 app/code/core/Mage/Core/Model/Config/Options.php
 create mode 100644 app/code/core/Mage/Core/Model/Dir.php
 create mode 100644 app/code/core/Mage/Core/Model/Magento/Api.php
 rename dev/tests/integration/testsuite/Mage/Core/_files/load_configuration.php => app/code/core/Mage/Core/Model/Magento/Api/V2.php (81%)
 create mode 100644 app/code/core/Mage/Core/Model/Store/Api.php
 rename app/code/core/Mage/{Adminhtml/Block/Abstract.php => Core/Model/Store/Api/V2.php} (85%)
 create mode 100644 app/code/core/Mage/Core/etc/api.xml
 create mode 100644 app/code/core/Mage/Core/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Core/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Customer/Model/Address/Api.php
 create mode 100644 app/code/core/Mage/Customer/Model/Address/Api/V2.php
 create mode 100644 app/code/core/Mage/Customer/Model/Api/Resource.php
 create mode 100644 app/code/core/Mage/Customer/Model/Customer/Api.php
 create mode 100644 app/code/core/Mage/Customer/Model/Customer/Api/V2.php
 create mode 100644 app/code/core/Mage/Customer/Model/Group/Api.php
 create mode 100644 app/code/core/Mage/Customer/Model/Group/Api/V2.php
 create mode 100644 app/code/core/Mage/Customer/etc/api.xml
 create mode 100644 app/code/core/Mage/Customer/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Customer/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Directory/Model/Country/Api.php
 create mode 100644 app/code/core/Mage/Directory/Model/Country/Api/V2.php
 create mode 100644 app/code/core/Mage/Directory/Model/Region/Api.php
 create mode 100644 app/code/core/Mage/Directory/Model/Region/Api/V2.php
 create mode 100644 app/code/core/Mage/Directory/etc/api.xml
 create mode 100644 app/code/core/Mage/Directory/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Directory/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Downloadable/Model/Link/Api.php
 create mode 100644 app/code/core/Mage/Downloadable/Model/Link/Api/Uploader.php
 create mode 100644 app/code/core/Mage/Downloadable/Model/Link/Api/V2.php
 create mode 100644 app/code/core/Mage/Downloadable/Model/Link/Api/Validator.php
 create mode 100644 app/code/core/Mage/Downloadable/etc/api.xml
 create mode 100644 app/code/core/Mage/Downloadable/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Downloadable/etc/wsi.xml
 create mode 100644 app/code/core/Mage/GiftMessage/Model/Api.php
 create mode 100644 app/code/core/Mage/GiftMessage/Model/Api/V2.php
 create mode 100644 app/code/core/Mage/GiftMessage/etc/api.xml
 create mode 100644 app/code/core/Mage/GiftMessage/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/GiftMessage/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Sales/Model/Api/Resource.php
 create mode 100644 app/code/core/Mage/Sales/Model/Order/Api.php
 create mode 100644 app/code/core/Mage/Sales/Model/Order/Api/V2.php
 create mode 100644 app/code/core/Mage/Sales/Model/Order/Creditmemo/Api.php
 create mode 100644 app/code/core/Mage/Sales/Model/Order/Creditmemo/Api/V2.php
 create mode 100644 app/code/core/Mage/Sales/Model/Order/Invoice/Api.php
 create mode 100644 app/code/core/Mage/Sales/Model/Order/Invoice/Api/V2.php
 create mode 100644 app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
 create mode 100644 app/code/core/Mage/Sales/Model/Order/Shipment/Api/V2.php
 create mode 100644 app/code/core/Mage/Sales/etc/api.xml
 create mode 100644 app/code/core/Mage/Sales/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Sales/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Tag/Model/Api.php
 create mode 100644 app/code/core/Mage/Tag/Model/Api/V2.php
 create mode 100644 app/code/core/Mage/Tag/etc/api.xml
 create mode 100644 app/code/core/Mage/Tag/etc/wsdl.xml
 create mode 100644 app/code/core/Mage/Tag/etc/wsi.xml
 create mode 100644 app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation/Request.php
 create mode 100644 app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation/Response.php
 rename app/code/core/Mage/Webapi/Controller/Router/{RouteAbstract.php => Route.php} (93%)
 create mode 100644 dev/tests/integration/framework/Magento/Test/Helper/Api.php
 create mode 100644 dev/tests/integration/framework/Magento/Test/Helper/Eav.php
 create mode 100644 dev/tests/integration/framework/Magento/Test/Workaround/Cleanup/StaticProperties.php
 rename dev/tests/integration/framework/Magento/Test/{ClearProperties.php => Workaround/Cleanup/TestCaseProperties.php} (91%)
 rename dev/tests/integration/framework/{tests/unit/testsuite/Magento/Test/_files/Stub.php => Magento/Test/Workaround/Segfault.php} (81%)
 delete mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ClearPropertiesTest.php
 create mode 100644 dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Cleanup/TestCasePropertiesTest.php
 rename dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/{ => Workaround/Cleanup}/_files/DummyTestCase.php (84%)
 rename app/code/core/Mage/Webapi/Controller/Router/Route/Webapi.php => dev/tests/integration/testsuite/Mage/Adminhtml/Block/Notification/BaseurlTest.php (70%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Adminhtml/Block/Page/HeadTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/LabelsTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Adminhtml/Block/Rating/Edit/Tab/FormTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Backend/Block/_files/backend_theme.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Backend/Model/Config/Backend/BaseurlTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Api/V2Test.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Category/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Attribute/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Category/_files/category_data.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Attribute/TierPriceTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/AttributeSetCRUDTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/AttributeTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/BackorderStatusTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/ConfigurableTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/DownloadableLinkCRUDTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Helper/Configurable.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Helper/Simple.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/ImageTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/SimpleTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/TagCRUDTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/TestCaseAbstract.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/AttributeSet.php
 rename index.php.sample => dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/AttributeSet_rollback.php (64%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOption.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOptionValue.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOptionValue_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOption_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/LinkCRUD.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/LinkCRUD_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductAttributeData.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductData.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/TagCRUD.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/TagCRUD_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/book.pdf
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/image.jpg
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.bmp.jpg
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.jpg.jpg
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.php.jpg
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.png.jpg
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/song.mp3
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/test.txt
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/product_configurable_all_fields.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_all_fields_data.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_data.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_inventory_use_config.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_manage_stock_use_config.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_special_chars_data.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/AttributeSet.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOption.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOptionTypes.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOptionValue.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/LinkCRUD.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/TagCRUD.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/attribute_set_with_configurable.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/store_on_new_website.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/store_on_new_website_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Media/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2Test.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Link/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Option/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/CatalogInventory/Model/Stock/Item/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/AbstractTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Api/_files/license_agreement.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Coupon/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Customer/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Payment/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Product/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Shipping/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/_files/discount_10percent.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/_files/quote.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_address.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_address_saved.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_ccsave_payment.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_check_payment.php
 rename app/code/core/Mage/Core/Block/Template/Smarty.php => dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_check_payment_rollback.php (87%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Cms/Helper/Wysiwyg/ImagesTest.php
 delete mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/Config/OptionsTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/Email/_files/themes.php
 delete mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/LayoutArgumentTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/LayoutDirectivesTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/Magento/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/Store/ApiTest.php
 rename dev/tests/integration/testsuite/Mage/{Install/Helper/DataTest.php => Core/Model/Store/GroupTest.php} (53%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/design/themes.php
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/fallback/pub/{js => lib}/mage/script.js (100%)
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/{local_config/no_local_config_no_custom_config/a.xml => layout_directives_test/action_for_anonymous_parent_block.xml} (69%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_complex_values.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_object_type.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_object_type_updaters.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_url_type.xml
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/{local_config/local_config_custom_config/custom/invalid.pattern.xml => layout_directives_test/get_block.xml} (81%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/get_block_exception.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_alias_broken.xml
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/{local_config/local_config_custom_config/local.xml => layout_directives_test/move_broken.xml} (85%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_new_alias.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_the_same_alias.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/remove.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/remove_broken.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/render.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_after_after.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_after_previous.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_before_after.xml
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_before_before.xml
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/{local_config_no_custom_config => local_config/custom}/local.xml (82%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/custom/prohibited.filename.xml
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/{local_config_custom_config/custom => local_config}/local.xml (82%)
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/{local_config_no_custom_config => local_config}/z.xml (82%)
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/{no_local_config_custom_config => no_local_config}/a.xml (82%)
 rename dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/{no_local_config_no_custom_config => no_local_config}/b.xml (82%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/custom/local.xml
 delete mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_custom_config/custom/local.xml
 delete mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/sort_special_cases.xml
 delete mode 100644 dev/tests/integration/testsuite/Mage/Core/Model/_files/valid_layout_updates.xml
 delete mode 100644 dev/tests/integration/testsuite/Mage/Core/Utility/Theme.php
 rename dev/tests/integration/testsuite/Mage/Core/{Model/LayoutTestBase.php => _files/media_for_change.php} (50%)
 create mode 100644 dev/tests/integration/testsuite/Mage/Core/_files/media_for_change_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Customer/Model/Address/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Customer/Model/Customer/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Customer/Model/Group/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Customer/_files/two_customers.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Directory/Model/Country/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Directory/Model/Region/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/GiftMessage/Model/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Install/IndexControllerTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Install/Model/Installer/ConfigTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Page/Block/HtmlTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Paypal/Adminhtml/Paypal/ReportsControllerTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Paypal/Model/Report/SettlementTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/customer.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/customer_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/multiple_invoices.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/multiple_invoices_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_with_shipping.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_with_shipping_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_simple.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_simple_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_virtual.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_virtual_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/shipment.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/shipment_rollback.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Creditmemo/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Invoice/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/Model/Order/Shipment/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/_files/invoice.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Sales/_files/invoice_verisign.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Tag/Model/Api/_files/tag.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Tag/Model/ApiTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Usa/Block/Adminhtml/Dhl/UnitofmeasureTest.php
 create mode 100644 dev/tests/integration/testsuite/Mage/Widget/_files/themes.php
 create mode 100644 dev/tests/integration/testsuite/MemoryUsageTest.php
 delete mode 100644 dev/tests/static/testsuite/Js/_files/blacklist/ee.txt
 create mode 100644 dev/tests/unit/testsuite/Mage/Core/Block/TemplateTest.php
 rename dev/tests/{integration => unit}/testsuite/Mage/Core/Block/_files/template_test_assign.phtml (96%)
 delete mode 100644 dev/tests/unit/testsuite/Mage/Core/Model/App/OptionsTest.php
 delete mode 100644 dev/tests/unit/testsuite/Mage/Core/Model/Config/OptionsTest.php
 create mode 100644 dev/tests/unit/testsuite/Mage/Core/Model/DirTest.php
 create mode 100644 dev/tests/unit/testsuite/Mage/Core/Model/EncryptionTest.php
 rename dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/{Route/ApiTypeTest.php => RouteTest.php} (78%)
 create mode 100644 pub/lib/.htaccess
 create mode 100644 pub/lib/jquery/jstree/jquery.hotkeys.js
 create mode 100644 pub/lib/mage/backend/multisuggest.js
 create mode 100644 pub/lib/mage/backend/tree-suggest.js

diff --git a/.gitignore b/.gitignore
index ee2ae170cef..1f08e5627de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,4 +29,3 @@ atlassian*
 /pub/media/customer/*
 /pub/media/downloadable/*
 /var/*
-
diff --git a/.htaccess b/.htaccess
index e02679d64fa..0a28bdaf030 100644
--- a/.htaccess
+++ b/.htaccess
@@ -141,11 +141,6 @@
     #RewriteCond %{HTTP_USER_AGENT} "android|blackberry|ipad|iphone|ipod|iemobile|opera mobile|palmos|webos|googlebot-mobile" [NC]
     #RewriteRule ^(.*)$ /mobiledirectoryhere/ [L,R=302]
 
-############################################
-## always send 404 on missing files in these folders
-
-    RewriteCond %{REQUEST_URI} !^/pub/(media|js)/
-
 ############################################
 ## never rewrite for existing files, directories and links
 
diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
index c8816df7256..32e34eceb03 100644
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,28 @@
+2.0.0.0-dev40
+=============
+* Implemented ability to customize all the main directory paths for the application, i.e. locations of `var`, `etc`, `media` and other directories
+* Implemented ability to pass application configuration data from the environment
+* Magento Web API changes:
+  * Added SOAP V2 API coverage from Magento 1.x
+  * Improved integration testing framework to develop Web API tests. Covered SOAP V2 API with positive integration tests.
+  * Changed `Mage_Webapi` module front name from `api` to `webapi`
+* Improvements for product creation UI:
+  * Implemented AJAX suggestions popup and categories tree popup for convenient assignment of categories
+  * Moved selection of Bundle and Grouped sub-products to the "General" tab, implemented popup grids for them
+  * Made "Weight" checkbox to be selected by default for a Configurable product
+* Implemented integration test to measure and control PHP memory leak on application reinitialization
+* Changed format of configuration files for static tests that search for obsolete Magento 1.x code
+* Bug fixes:
+  * Fixed Web API WSDL incompatibility with C# and Java
+  * Fixed issue, that Magento duplicated custom options field for a product, if creating them via a multi-call to API
+  * Fixed `shoppingCartPaymentList` method in Web API, which was throwing exception "Object has no 'code' property"
+  * Fixed invalid Wishlist link and several invalid links in Checkout on frontend store view
+  * Made Stock Status in 'quantity_and_stock_status' attribute editable again for a Configurable product
+  * Fixed issue, that it was not possible to save Customer after first save, because "Date Of Birth" format was reported by Magento to be incorrect
+  * Fixed fatal error in Code Sniffer exemplar test
+  * Fixed wrong failures of `Varien_Db_Adapter_Pdo_MysqlTest::testWaitTimeout()` integration test in developer mode
+  * Fixed issue, that mass-action column in backend grids moved to another position in single store mode
+
 2.0.0.0-dev39
 =============
 * Visual design editor improvements:
diff --git a/app/Mage.php b/app/Mage.php
index 6629187adfc..02c46493940 100644
--- a/app/Mage.php
+++ b/app/Mage.php
@@ -29,6 +29,26 @@
  */
 final class Mage
 {
+    /**#@+
+     * Application initialization options to inject custom request/response objects
+     */
+    const INIT_OPTION_REQUEST  = 'request';
+    const INIT_OPTION_RESPONSE = 'response';
+    /**#@-*/
+
+    /**
+     * Application initialization option to specify custom product edition label
+     */
+    const INIT_OPTION_EDITION = 'edition';
+
+    /**
+     * Product edition labels
+     */
+    const EDITION_COMMUNITY    = 'Community';
+    const EDITION_ENTERPRISE   = 'Enterprise';
+    const EDITION_PROFESSIONAL = 'Professional';
+    const EDITION_GO           = 'Go';
+
     /**
      * Registry collection
      *
@@ -113,14 +133,6 @@ final class Mage
      */
     protected static $_design;
 
-    /**
-     * Magento edition constants
-     */
-    const EDITION_COMMUNITY    = 'Community';
-    const EDITION_ENTERPRISE   = 'Enterprise';
-    const EDITION_PROFESSIONAL = 'Professional';
-    const EDITION_GO           = 'Go';
-
     /**
      * Current Magento edition.
      *
@@ -163,7 +175,7 @@ final class Mage
             'revision'  => '0',
             'patch'     => '0',
             'stability' => 'dev',
-            'number'    => '39',
+            'number'    => '40',
         );
     }
 
@@ -311,9 +323,11 @@ final class Mage
      * @param string $type
      * @return string
      */
-    public static function getBaseDir($type = 'base')
+    public static function getBaseDir($type = Mage_Core_Model_Dir::ROOT)
     {
-        return self::getConfig()->getOptions()->getDir($type);
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = self::$_objectManager->get('Mage_Core_Model_Dir');
+        return $dirs->getDir($type);
     }
 
     /**
@@ -398,14 +412,23 @@ final class Mage
     /**
      * Retrieve a config instance
      *
+     * This method doesn't suit Magento 2 anymore, it is left only until refactoring, when all calls
+     * to Mage::getConfig() will be removed in favor of config dependency injection.
+     *
      * @return Mage_Core_Model_Config
      */
     public static function getConfig()
     {
-        if (!self::$_config) {
-            self::$_config = self::getObjectManager()->get('Mage_Core_Model_Config');
+        if (self::$_app) {
+            // Usual workflow - act as a proxy, retrieve config from the application
+            return self::$_app->getConfig();
+        } else {
+            // Temp workaround for unit tests only, so there is no urgent need to check and refactor them all
+            if (!self::$_config) {
+                self::$_config = self::getObjectManager()->get('Mage_Core_Model_Config');
+            }
+            return self::$_config;
         }
-        return self::$_config;
     }
 
     /**
@@ -620,19 +643,17 @@ final class Mage
     /**
      * Get initialized application object.
      *
-     * @param string $code
-     * @param string $type
-     * @param string|array $options
+     * @param array $params
      * @return Mage_Core_Model_App
      */
-    public static function app($code = '', $type = 'store', $options = array())
+    public static function app(array $params = array())
     {
         if (null === self::$_app) {
             self::$_app = self::getObjectManager()->get('Mage_Core_Model_App');
             self::$_events = new Varien_Event_Collection();
 
             Magento_Profiler::start('self::app::init');
-            self::$_app->init($code, $type, $options);
+            self::$_app->init($params);
             Magento_Profiler::stop('self::app::init');
         }
         return self::$_app;
@@ -640,26 +661,25 @@ final class Mage
 
     /**
      * @static
-     * @param string $code
-     * @param string $type
-     * @param array $options
+     * @param array $params
      * @param string|array $modules
      */
-    public static function init($code = '', $type = 'store', $options = array(), $modules = array())
+    public static function init(array $params, $modules = array())
     {
         try {
-            self::$_app = self::getObjectManager()->create('Mage_Core_Model_App');
-
+            /** @var $app Mage_Core_Model_App */
+            $app = self::getObjectManager()->create('Mage_Core_Model_App');
+            self::$_app = $app;
             if (!empty($modules)) {
-                self::$_app->initSpecified($code, $type, $options, $modules);
+                self::$_app->initSpecified($params, $modules);
             } else {
-                self::$_app->init($code, $type, $options);
+                self::$_app->init($params);
             }
         } catch (Mage_Core_Model_Session_Exception $e) {
             header('Location: ' . self::getBaseUrl());
             die;
         } catch (Mage_Core_Model_Store_Exception $e) {
-            require_once(self::getBaseDir() . DS . 'pub' . DS . 'errors' . DS . '404.php');
+            require_once(self::getBaseDir(Mage_Core_Model_Dir::PUB) . DS . 'errors' . DS . '404.php');
             die;
         } catch (Exception $e) {
             self::printException($e);
@@ -670,30 +690,26 @@ final class Mage
     /**
      * Front end main entry point
      *
-     * @param string $code
-     * @param string $type
-     * @param string|array $options
+     * @param array $params
      */
-    public static function run($code = '', $type = 'store', $options = array())
+    public static function run(array $params)
     {
         try {
             Magento_Profiler::start('mage');
-            if (isset($options['edition'])) {
-                self::$_currentEdition = $options['edition'];
+            if (isset($params[self::INIT_OPTION_EDITION])) {
+                self::$_currentEdition = $params[self::INIT_OPTION_EDITION];
             }
-            self::$_app    = self::getObjectManager()->get('Mage_Core_Model_App');
-            if (isset($options['request'])) {
-                self::$_app->setRequest($options['request']);
+            /** @var $app Mage_Core_Model_App */
+            $app = self::getObjectManager()->create('Mage_Core_Model_App');
+            self::$_app = $app;
+            if (isset($params[self::INIT_OPTION_REQUEST])) {
+                self::$_app->setRequest($params[self::INIT_OPTION_REQUEST]);
             }
-            if (isset($options['response'])) {
-                self::$_app->setResponse($options['response']);
+            if (isset($params[self::INIT_OPTION_RESPONSE])) {
+                self::$_app->setResponse($params[self::INIT_OPTION_RESPONSE]);
             }
             self::$_events = new Varien_Event_Collection();
-            self::$_app->run(array(
-                'scope_code' => $code,
-                'scope_type' => $type,
-                'options'    => $options,
-            ));
+            self::$_app->run($params);
             Magento_Profiler::stop('mage');
         } catch (Mage_Core_Model_Session_Exception $e) {
             header('Location: ' . self::getBaseUrl());
@@ -822,7 +838,7 @@ final class Mage
             } catch (Exception $e) {
             }
 
-            require_once(self::getBaseDir() . DS . 'pub' . DS . 'errors' . DS . 'report.php');
+            require_once(self::getBaseDir(Mage_Core_Model_Dir::PUB) . DS . 'errors' . DS . 'report.php');
         }
 
         die();
diff --git a/app/bootstrap.php b/app/bootstrap.php
index 22da0bd5b7a..bac5bf5a10d 100644
--- a/app/bootstrap.php
+++ b/app/bootstrap.php
@@ -43,6 +43,22 @@ umask(0);
 require_once BP . '/app/code/core/Mage/Core/functions.php';
 require_once BP . '/app/Mage.php';
 
+require_once __DIR__ . '/autoload.php';
+Magento_Autoload_IncludePath::addIncludePath(array(
+    BP . DS . 'app' . DS . 'code' . DS . 'local',
+    BP . DS . 'app' . DS . 'code' . DS . 'community',
+    BP . DS . 'app' . DS . 'code' . DS . 'core',
+    BP . DS . 'lib',
+    BP . DS . 'var' . DS . 'generation',
+));
+$classMapPath = BP . DS . 'var/classmap.ser';
+if (file_exists($classMapPath)) {
+    require_once BP . '/lib/Magento/Autoload/ClassMap.php';
+    $classMap = new Magento_Autoload_ClassMap(BP);
+    $classMap->addMap(unserialize(file_get_contents($classMapPath)));
+    spl_autoload_register(array($classMap, 'load'));
+}
+
 if (!defined('BARE_BOOTSTRAP')) {
     /* PHP version validation */
     if (version_compare(phpversion(), '5.3.0', '<') === true) {
@@ -94,22 +110,6 @@ HTML;
     }
 }
 
-require_once __DIR__ . '/autoload.php';
-Magento_Autoload_IncludePath::addIncludePath(array(
-    BP . DS . 'app' . DS . 'code' . DS . 'local',
-    BP . DS . 'app' . DS . 'code' . DS . 'community',
-    BP . DS . 'app' . DS . 'code' . DS . 'core',
-    BP . DS . 'lib',
-    BP . DS . 'var' . DS . 'generation',
-));
-$classMapPath = BP . DS . 'var/classmap.ser';
-if (file_exists($classMapPath)) {
-    require_once BP . '/lib/Magento/Autoload/ClassMap.php';
-    $classMap = new Magento_Autoload_ClassMap(BP);
-    $classMap->addMap(unserialize(file_get_contents($classMapPath)));
-    spl_autoload_register(array($classMap, 'load'));
-}
-
 $definitionsFile = BP . DS . 'var/di/definitions.php';
 if (file_exists($definitionsFile)) {
     Mage::initializeObjectManager($definitionsFile);
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Buttons.php b/app/code/core/Mage/Adminhtml/Block/Api/Buttons.php
new file mode 100644
index 00000000000..1f8e478523f
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Buttons.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.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Adminhtml_Block_Api_Buttons extends Mage_Adminhtml_Block_Template
+{
+
+    protected $_template = 'api/userinfo.phtml';
+
+    protected function _prepareLayout()
+    {
+        $this->addChild('backButton', 'Mage_Adminhtml_Block_Widget_Button', array(
+            'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Back'),
+            'onclick'   => 'window.location.href=\''.$this->getUrl('*/*/').'\'',
+            'class' => 'back'
+        ));
+
+        $this->addChild('resetButton', 'Mage_Adminhtml_Block_Widget_Button', array(
+            'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Reset'),
+            'onclick'   => 'window.location.reload()'
+        ));
+
+        $this->addChild('saveButton', 'Mage_Adminhtml_Block_Widget_Button', array(
+            'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Save Role'),
+            'class' => 'save',
+            'data_attr'  => array(
+                'widget-button' => array('event' => 'save', 'related' => '#role-edit-form')
+            )
+        ));
+
+        $this->addChild('deleteButton', 'Mage_Adminhtml_Block_Widget_Button', array(
+            'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Delete Role'),
+            'onclick'   => 'deleteConfirm(\'' . Mage::helper('Mage_Adminhtml_Helper_Data')->__('Are you sure you want to do this?') . '\', \'' . $this->getUrl('*/*/delete', array('rid' => $this->getRequest()->getParam('rid'))) . '\')',
+            'class' => 'delete'
+        ));
+        return parent::_prepareLayout();
+    }
+
+    public function getBackButtonHtml()
+    {
+        return $this->getChildHtml('backButton');
+    }
+
+    public function getResetButtonHtml()
+    {
+        return $this->getChildHtml('resetButton');
+    }
+
+    public function getSaveButtonHtml()
+    {
+        return $this->getChildHtml('saveButton');
+    }
+
+    public function getDeleteButtonHtml()
+    {
+        if( intval($this->getRequest()->getParam('rid')) == 0 ) {
+            return;
+        }
+        return $this->getChildHtml('deleteButton');
+    }
+
+    public function getUser()
+    {
+        return Mage::registry('user_data');
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Editroles.php b/app/code/core/Mage/Adminhtml/Block/Api/Editroles.php
new file mode 100644
index 00000000000..756f5d88845
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Editroles.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Adminhtml_Block_Api_Editroles extends Mage_Adminhtml_Block_Widget_Tabs {
+    protected function _construct()
+    {
+        parent::_construct();
+        $this->setId('role_info_tabs');
+        $this->setDestElementId('role-edit-form');
+        $this->setTitle(Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Information'));
+    }
+
+    protected function _beforeToHtml()
+    {
+        $roleId = $this->getRequest()->getParam('rid', false);
+        $role = Mage::getModel('Mage_Api_Model_Roles')
+           ->load($roleId);
+
+        $this->addTab('info', array(
+            'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Info'),
+            'title'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Info'),
+            'content'   => $this->getLayout()->createBlock(
+                'Mage_Adminhtml_Block_Api_Tab_Roleinfo'
+            )->setRole($role)->toHtml(),
+            'active'    => true
+        ));
+
+        $this->addTab('account', array(
+            'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Resources'),
+            'title'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Resources'),
+            'content'   => $this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_Tab_Rolesedit')->toHtml(),
+        ));
+
+        if( intval($roleId) > 0 ) {
+            $this->addTab('roles', array(
+                'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Users'),
+                'title'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Users'),
+                'content'   => $this->getLayout()->createBlock(
+                    'Mage_Adminhtml_Block_Api_Tab_Rolesusers',
+                    'role.users.grid'
+                )->toHtml(),
+            ));
+        }
+        return parent::_beforeToHtml();
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Grid/Role.php b/app/code/core/Mage/Adminhtml/Block/Api/Grid/Role.php
new file mode 100644
index 00000000000..66f3f11a7d7
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Grid/Role.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * roles grid
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Api_Grid_Role extends Mage_Adminhtml_Block_Widget_Grid
+{
+    protected function _construct()
+    {
+        parent::_construct();
+        $this->setId('roleGrid');
+        $this->setSaveParametersInSession(true);
+        $this->setDefaultSort('role_id');
+        $this->setDefaultDir('asc');
+        $this->setUseAjax(true);
+    }
+
+    protected function _prepareCollection()
+    {
+        $collection =  Mage::getModel('Mage_Api_Model_Roles')->getCollection();
+        $this->setCollection($collection);
+
+        return parent::_prepareCollection();
+    }
+
+    protected function _prepareColumns()
+    {
+
+        $this->addColumn('role_id', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('ID'),
+            'index'     =>'role_id',
+            'align'     => 'right',
+            'width'    => '50px'
+        ));
+
+        $this->addColumn('role_name', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Name'),
+            'index'     =>'role_name'
+        ));
+
+        return parent::_prepareColumns();
+    }
+
+    public function getGridUrl()
+    {
+        return $this->getUrl('*/*/roleGrid', array('_current'=>true));
+    }
+
+    public function getRowUrl($row)
+    {
+        return $this->getUrl('*/*/editrole', array('rid' => $row->getRoleId()));
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Role.php b/app/code/core/Mage/Adminhtml/Block/Api/Role.php
new file mode 100644
index 00000000000..0132077acd0
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Role.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Adminhtml permissioms role block
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Adminhtml_Block_Api_Role extends Mage_Adminhtml_Block_Widget_Grid_Container
+{
+
+    protected function _construct()
+    {
+        $this->_controller = 'api_role';
+        $this->_headerText = Mage::helper('Mage_Adminhtml_Helper_Data')->__('Roles');
+        $this->_addButtonLabel = Mage::helper('Mage_Adminhtml_Helper_Data')->__('Add New Role');
+        parent::_construct();
+    }
+
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Role/Grid/User.php b/app/code/core/Mage/Adminhtml/Block/Api/Role/Grid/User.php
new file mode 100644
index 00000000000..f220af82959
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Role/Grid/User.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Acl role user grid
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Api_Role_Grid_User extends Mage_Adminhtml_Block_Widget_Grid
+{
+
+    protected function _construct()
+    {
+        parent::_construct();
+        $this->setDefaultSort('role_user_id');
+        $this->setDefaultDir('asc');
+        $this->setId('roleUserGrid');
+        $this->setDefaultFilter(array('in_role_users'=>1));
+        $this->setUseAjax(true);
+    }
+
+    protected function _addColumnFilterToCollection($column)
+    {
+        if ($column->getId() == 'in_role_users') {
+            $inRoleIds = $this->_getUsers();
+            if (empty($inRoleIds)) {
+                $inRoleIds = 0;
+            }
+            if ($column->getFilter()->getValue()) {
+                $this->getCollection()->addFieldToFilter('user_id', array('in'=>$inRoleIds));
+            }
+            else {
+                if($inRoleIds) {
+                    $this->getCollection()->addFieldToFilter('user_id', array('nin'=>$inRoleIds));
+                }
+            }
+        }
+        else {
+            parent::_addColumnFilterToCollection($column);
+        }
+        return $this;
+    }
+
+    protected function _prepareCollection()
+    {
+        $roleId = $this->getRequest()->getParam('rid');
+        Mage::register('RID', $roleId);
+        $collection = Mage::getModel('Mage_Api_Model_Roles')->getUsersCollection();
+        $this->setCollection($collection);
+        return parent::_prepareCollection();
+    }
+
+    protected function _prepareColumns()
+    {
+        $this->addColumn('in_role_users', array(
+            'header_css_class' => 'a-center',
+            'type'      => 'checkbox',
+            'name'      => 'in_role_users',
+            'values'    => $this->_getUsers(),
+            'align'     => 'center',
+            'index'     => 'user_id'
+        ));
+
+        $this->addColumn('role_user_id', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('User ID'),
+            'width'     =>5,
+            'align'     =>'left',
+            'sortable'  =>true,
+            'index'     =>'user_id'
+        ));
+
+        $this->addColumn('role_user_username', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Name'),
+            'align'     =>'left',
+            'index'     =>'username'
+        ));
+
+        $this->addColumn('role_user_firstname', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('First Name'),
+            'align'     =>'left',
+            'index'     =>'firstname'
+        ));
+
+        $this->addColumn('role_user_lastname', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('Last Name'),
+            'align'     =>'left',
+            'index'     =>'lastname'
+        ));
+
+        $this->addColumn('role_user_email', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('Email'),
+            'width'     =>40,
+            'align'     =>'left',
+            'index'     =>'email'
+        ));
+
+        $this->addColumn('role_user_is_active', array(
+            'header'    => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Status'),
+            'index'     => 'is_active',
+            'align'     =>'left',
+            'type'      => 'options',
+            'options'   => array('1' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Active'), '0' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Inactive')),
+        ));
+
+       /*
+        $this->addColumn('grid_actions',
+            array(
+                'header'=>Mage::helper('Mage_Adminhtml_Helper_Data')->__('Actions'),
+                'width'=>5,
+                'sortable'=>false,
+                'filter'    =>false,
+                'type' => 'action',
+                'actions'   => array(
+                                    array(
+                                        'caption' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Remove'),
+                                        'onClick' => 'role.deleteFromRole($role_id);'
+                                    )
+                                )
+            )
+        );
+        */
+
+        return parent::_prepareColumns();
+    }
+
+    public function getGridUrl()
+    {
+        $roleId = $this->getRequest()->getParam('rid');
+        return $this->getUrl('*/*/editrolegrid', array('rid' => $roleId));
+    }
+
+    protected function _getUsers($json=false)
+    {
+        if ( $this->getRequest()->getParam('in_role_user') != "" ) {
+            return $this->getRequest()->getParam('in_role_user');
+        }
+        $roleId = ( $this->getRequest()->getParam('rid') > 0 ) ? $this->getRequest()->getParam('rid') : Mage::registry('RID');
+        $users  = Mage::getModel('Mage_Api_Model_Roles')->setId($roleId)->getRoleUsers();
+        if (sizeof($users) > 0) {
+            if ( $json ) {
+                $jsonUsers = Array();
+                foreach($users as $usrid) $jsonUsers[$usrid] = 0;
+                return Mage::helper('Mage_Core_Helper_Data')->jsonEncode((object)$jsonUsers);
+            } else {
+                return array_values($users);
+            }
+        } else {
+            if ( $json ) {
+                return '{}';
+            } else {
+                return array();
+            }
+        }
+    }
+
+}
+
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Roles.php b/app/code/core/Mage/Adminhtml/Block/Api/Roles.php
new file mode 100644
index 00000000000..f199067242d
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Roles.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * user roles block
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Api_Roles extends Mage_Adminhtml_Block_Template
+{
+
+    protected $_template = 'api/roles.phtml';
+
+    public function getAddNewUrl()
+    {
+        return $this->getUrl('*/*/editrole');
+    }
+
+    public function getGridHtml()
+    {
+        return $this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_Grid_Role')->toHtml();
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Tab/Roleinfo.php b/app/code/core/Mage/Adminhtml/Block/Api/Tab/Roleinfo.php
new file mode 100644
index 00000000000..ed57e4098fc
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Tab/Roleinfo.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Adminhtml_Block_Api_Tab_Roleinfo extends Mage_Adminhtml_Block_Widget_Form
+{
+    public function _beforeToHtml() {
+        $this->_initForm();
+
+        return parent::_beforeToHtml();
+    }
+
+    protected function _initForm()
+    {
+        $roleId = $this->getRequest()->getParam('rid');
+
+        $form = new Varien_Data_Form();
+
+        $fieldset = $form->addFieldset('base_fieldset', array('legend'=>Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Information')));
+
+        $fieldset->addField('role_name', 'text',
+            array(
+                'name'  => 'rolename',
+                'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Name'),
+                'id'    => 'role_name',
+                'class' => 'required-entry',
+                'required' => true,
+            )
+        );
+
+        $fieldset->addField('role_id', 'hidden',
+            array(
+                'name'  => 'role_id',
+                'id'    => 'role_id',
+            )
+        );
+
+        $fieldset->addField('in_role_user', 'hidden',
+            array(
+                'name'  => 'in_role_user',
+                'id'    => 'in_role_userz',
+            )
+        );
+
+        $fieldset->addField('in_role_user_old', 'hidden', array('name' => 'in_role_user_old'));
+
+        $form->setValues($this->getRole()->getData());
+        $this->setForm($form);
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesedit.php b/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesedit.php
new file mode 100644
index 00000000000..2acc4d1ec69
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesedit.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.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Adminhtml_Block_Api_Tab_Rolesedit extends Mage_Adminhtml_Block_Widget_Form {
+
+    protected $_template = 'api/rolesedit.phtml';
+
+
+    protected function _construct() {
+        parent::_construct();
+
+        $rid = Mage::app()->getRequest()->getParam('rid', false);
+
+        $resources = Mage::getModel('Mage_Api_Model_Roles')->getResourcesList();
+
+        $rules_set = Mage::getResourceModel('Mage_Api_Model_Resource_Rules_Collection')->getByRoles($rid)->load();
+
+        $selrids = array();
+
+        foreach ($rules_set->getItems() as $item) {
+            if (array_key_exists(strtolower($item->getResource_id()), $resources)
+                && $item->getApiPermission() == 'allow')
+            {
+                $resources[$item->getResource_id()]['checked'] = true;
+                array_push($selrids, $item->getResource_id());
+            }
+        }
+
+        $this->setSelectedResources($selrids);
+
+
+        //->assign('resources', $resources);
+        //->assign('checkedResources', join(',', $selrids));
+    }
+
+    public function getEverythingAllowed()
+    {
+        return in_array('all', $this->getSelectedResources());
+    }
+
+    public function getResTreeJson()
+    {
+        $rid = Mage::app()->getRequest()->getParam('rid', false);
+        $resources = Mage::getModel('Mage_Api_Model_Roles')->getResourcesTree();
+
+        $rootArray = $this->_getNodeJson($resources,1);
+
+        $json = Mage::helper('Mage_Core_Helper_Data')->jsonEncode(isset($rootArray['children']) ? $rootArray['children'] : array());
+
+        return $json;
+    }
+
+    protected function _sortTree($a, $b)
+    {
+        return $a['sort_order']<$b['sort_order'] ? -1 : ($a['sort_order']>$b['sort_order'] ? 1 : 0);
+    }
+
+
+    protected function _getNodeJson($node, $level=0)
+    {
+        $item = array();
+        $selres = $this->getSelectedResources();
+
+        if ($level != 0) {
+            $item['text']= (string)$node->title;
+            $item['sort_order']= isset($node->sort_order) ? (string)$node->sort_order : 0;
+            $item['id']  = (string)$node->attributes()->aclpath;
+
+            if (in_array($item['id'], $selres))
+                $item['checked'] = true;
+        }
+        if (isset($node->children)) {
+            $children = $node->children->children();
+        } else {
+            $children = $node->children();
+        }
+        if (empty($children)) {
+            return $item;
+        }
+
+        if ($children) {
+            $item['children'] = array();
+            //$item['cls'] = 'fiche-node';
+            foreach ($children as $child) {
+                if ($child->getName()!='title' && $child->getName()!='sort_order' && $child->attributes()->module) {
+                    if ($level != 0) {
+                        $item['children'][] = $this->_getNodeJson($child, $level+1);
+                    } else {
+                        $item = $this->_getNodeJson($child, $level+1);
+                    }
+                }
+            }
+            if (!empty($item['children'])) {
+                usort($item['children'], array($this, '_sortTree'));
+            }
+        }
+        return $item;
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesusers.php b/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesusers.php
new file mode 100644
index 00000000000..bacf853a403
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/Tab/Rolesusers.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Adminhtml_Block_Api_Tab_Rolesusers extends Mage_Adminhtml_Block_Widget_Tabs {
+
+    protected function _construct()
+    {
+        parent::_construct();
+
+        $roleId = $this->getRequest()->getParam('rid', false);
+
+        $users = Mage::getModel('Mage_Api_Model_User')->getCollection()->load();
+        $this->setTemplate('api/rolesusers.phtml')
+            ->assign('users', $users->getItems())
+            ->assign('roleId', $roleId);
+    }
+
+    protected function _prepareLayout()
+    {
+        $this->setChild(
+            'userGrid',
+            $this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_Role_Grid_User', 'roleUsersGrid')
+        );
+        return parent::_prepareLayout();
+    }
+
+    protected function _getGridHtml()
+    {
+        return $this->getChildHtml('userGrid');
+    }
+}
diff --git a/app/code/core/Mage/Core/Block/Template/Zend.php b/app/code/core/Mage/Adminhtml/Block/Api/User.php
similarity index 57%
rename from app/code/core/Mage/Core/Block/Template/Zend.php
rename to app/code/core/Mage/Adminhtml/Block/Api/User.php
index 0c005e426c6..54f560c56e1 100644
--- a/app/code/core/Mage/Core/Block/Template/Zend.php
+++ b/app/code/core/Mage/Adminhtml/Block/Api/User.php
@@ -19,56 +19,37 @@
  * needs please refer to http://www.magentocommerce.com for more information.
  *
  * @category    Mage
- * @package     Mage_Core
+ * @package     Mage_Adminhtml
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-
 /**
- * Zend html block
+ * Adminhtml permissions user block
  *
  * @category   Mage
- * @package    Mage_Core
+ * @package    Mage_Adminhtml
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Core_Block_Template_Zend extends Mage_Core_Block_Template
+class Mage_Adminhtml_Block_Api_User extends Mage_Adminhtml_Block_Widget_Grid_Container
 {
 
-    protected $_view = null;
-
-    /**
-     * Class constructor. Base html block
-     *
-     * @param      none
-     * @return     void
-     */
-    function _construct()
+    protected function _construct()
     {
+        $this->_controller = 'api_user';
+        $this->_headerText = Mage::helper('Mage_Adminhtml_Helper_Data')->__('Users');
+        $this->_addButtonLabel = Mage::helper('Mage_Adminhtml_Helper_Data')->__('Add New User');
         parent::_construct();
-        $this->_view = new Zend_View();
-    }
-
-    public function assign($key, $value=null)
-    {
-        if (is_array($key) && is_null($value)) {
-            foreach ($key as $k=>$v) {
-                $this->assign($k, $v);
-            }
-        } elseif (!is_null($value)) {
-            $this->_view->assign($key, $value);
-        }
-        return $this;
     }
 
-    public function setScriptPath($dir)
-    {
-        $this->_view->setScriptPath($dir.DS);
-    }
-
-    public function fetchView($fileName)
+    /**
+     * Prepare output HTML
+     *
+     * @return string
+     */
+    protected function _toHtml()
     {
-        return $this->_view->render($fileName);
+        Mage::dispatchEvent('api_user_html_before', array('block' => $this));
+        return parent::_toHtml();
     }
-
 }
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit.php b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit.php
new file mode 100644
index 00000000000..104e6a116b8
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Adminhtml permissions user edit page
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Api_User_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
+{
+
+    protected function _construct()
+    {
+        $this->_objectId = 'user_id';
+        $this->_controller = 'api_user';
+
+        parent::_construct();
+
+        $this->_updateButton('save', 'label', Mage::helper('Mage_Adminhtml_Helper_Data')->__('Save User'));
+        $this->_updateButton('delete', 'label', Mage::helper('Mage_Adminhtml_Helper_Data')->__('Delete User'));
+    }
+
+    public function getHeaderText()
+    {
+        if (Mage::registry('api_user')->getId()) {
+            return Mage::helper('Mage_Adminhtml_Helper_Data')->__("Edit User '%s'", $this->escapeHtml(Mage::registry('api_user')->getUsername()));
+        }
+        else {
+            return Mage::helper('Mage_Adminhtml_Helper_Data')->__('New User');
+        }
+    }
+
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Form.php b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Form.php
new file mode 100644
index 00000000000..ce33093e613
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Form.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Adminhtml permissions user edit form
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Api_User_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
+{
+
+    protected function _prepareForm()
+    {
+        $form = new Varien_Data_Form(array('id' => 'edit_form', 'action' => $this->getData('action'), 'method' => 'post'));
+        $form->setUseContainer(true);
+        $this->setForm($form);
+        return parent::_prepareForm();
+    }
+
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php
new file mode 100644
index 00000000000..4ef7f8cf40c
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Main.php
@@ -0,0 +1,153 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Cms page edit form main tab
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Adminhtml_Block_Api_User_Edit_Tab_Main extends Mage_Adminhtml_Block_Widget_Form
+{
+
+    protected function _prepareForm()
+    {
+        $model = Mage::registry('api_user');
+
+        $form = new Varien_Data_Form();
+
+        $form->setHtmlIdPrefix('user_');
+
+        $fieldset = $form->addFieldset('base_fieldset', array('legend'=>Mage::helper('Mage_Adminhtml_Helper_Data')->__('Account Information')));
+
+        if ($model->getUserId()) {
+            $fieldset->addField('user_id', 'hidden', array(
+                'name' => 'user_id',
+            ));
+        } else {
+            if (! $model->hasData('is_active')) {
+                $model->setIsActive(1);
+            }
+        }
+
+        $fieldset->addField('username', 'text', array(
+            'name'  => 'username',
+            'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Name'),
+            'id'    => 'username',
+            'title' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Name'),
+            'required' => true,
+        ));
+
+        $fieldset->addField('firstname', 'text', array(
+            'name'  => 'firstname',
+            'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('First Name'),
+            'id'    => 'firstname',
+            'title' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('First Name'),
+            'required' => true,
+        ));
+
+        $fieldset->addField('lastname', 'text', array(
+            'name'  => 'lastname',
+            'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Last Name'),
+            'id'    => 'lastname',
+            'title' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Last Name'),
+            'required' => true,
+        ));
+
+        $fieldset->addField('email', 'text', array(
+            'name'  => 'email',
+            'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Email'),
+            'id'    => 'customer_email',
+            'title' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Email'),
+            'class' => 'required-entry validate-email',
+            'required' => true,
+        ));
+
+        if ($model->getUserId()) {
+            $fieldset->addField('password', 'password', array(
+                'name'  => 'new_api_key',
+                'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('New API Key'),
+                'id'    => 'new_pass',
+                'title' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('New API Key'),
+                'class' => 'input-text validate-password',
+            ));
+
+            $fieldset->addField('confirmation', 'password', array(
+                'name'  => 'api_key_confirmation',
+                'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('API Key Confirmation'),
+                'id'    => 'confirmation',
+                'class' => 'input-text validate-cpassword',
+            ));
+        }
+        else {
+           $fieldset->addField('password', 'password', array(
+                'name'  => 'api_key',
+                'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('API Key'),
+                'id'    => 'customer_pass',
+                'title' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('API Key'),
+                'class' => 'input-text required-entry validate-password',
+                'required' => true,
+            ));
+           $fieldset->addField('confirmation', 'password', array(
+                'name'  => 'api_key_confirmation',
+                'label' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('API Key Confirmation'),
+                'id'    => 'confirmation',
+                'title' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('API Key Confirmation'),
+                'class' => 'input-text required-entry validate-cpassword',
+                'required' => true,
+            ));
+        }
+
+        if (Mage::getSingleton('Mage_Backend_Model_Auth_Session')->getUser()->getId() != $model->getUserId()) {
+            $fieldset->addField('is_active', 'select', array(
+                'name'  	=> 'is_active',
+                'label' 	=> Mage::helper('Mage_Adminhtml_Helper_Data')->__('This account is'),
+                'id'    	=> 'is_active',
+                'title' 	=> Mage::helper('Mage_Adminhtml_Helper_Data')->__('Account status'),
+                'class' 	=> 'input-select',
+                'style'		=> 'width: 80px',
+                'options'	=> array('1' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Active'), '0' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Inactive')),
+            ));
+        }
+
+        $fieldset->addField('user_roles', 'hidden', array(
+            'name' => 'user_roles',
+            'id'   => '_user_roles',
+        ));
+
+        $data = $model->getData();
+
+        unset($data['password']);
+
+        $form->setValues($data);
+
+        $this->setForm($form);
+
+        return parent::_prepareForm();
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Roles.php b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Roles.php
new file mode 100644
index 00000000000..3dddfc46177
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tab/Roles.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.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Adminhtml_Block_Api_User_Edit_Tab_Roles extends Mage_Adminhtml_Block_Widget_Grid
+{
+
+    protected function _construct()
+    {
+        parent::_construct();
+        $this->setId('permissionsUserRolesGrid');
+        $this->setDefaultSort('sort_order');
+        $this->setDefaultDir('asc');
+        //$this->setDefaultFilter(array('assigned_user_role'=>1));
+        $this->setTitle(Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Roles Information'));
+        $this->setUseAjax(true);
+    }
+
+    protected function _addColumnFilterToCollection($column)
+    {
+        if ($column->getId() == 'assigned_user_role') {
+            $userRoles = $this->_getSelectedRoles();
+            if (empty($userRoles)) {
+                $userRoles = 0;
+            }
+            if ($column->getFilter()->getValue()) {
+                $this->getCollection()->addFieldToFilter('role_id', array('in'=>$userRoles));
+            }
+            else {
+                if($userRoles) {
+                    $this->getCollection()->addFieldToFilter('role_id', array('nin'=>$userRoles));
+                }
+            }
+        }
+        else {
+            parent::_addColumnFilterToCollection($column);
+        }
+        return $this;
+    }
+
+    protected function _prepareCollection()
+    {
+        $collection = Mage::getResourceModel('Mage_Api_Model_Resource_Role_Collection');
+        $collection->setRolesFilter();
+        $this->setCollection($collection);
+        return parent::_prepareCollection();
+    }
+
+    protected function _prepareColumns()
+    {
+
+        $this->addColumn('assigned_user_role', array(
+            'header_css_class' => 'a-center',
+            'header'    => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Assigned'),
+            'type'      => 'radio',
+            'html_name' => 'roles[]',
+            'values'    => $this->_getSelectedRoles(),
+            'align'     => 'center',
+            'index'     => 'role_id'
+        ));
+
+        /*$this->addColumn('role_id', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role ID'),
+            'index'     =>'role_id',
+            'align'     => 'right',
+            'width'    => '50px'
+        ));*/
+
+        $this->addColumn('role_name', array(
+            'header'    =>Mage::helper('Mage_Adminhtml_Helper_Data')->__('Role Name'),
+            'index'     =>'role_name'
+        ));
+
+        return parent::_prepareColumns();
+    }
+
+    public function getGridUrl()
+    {
+        return $this->getUrl('*/*/rolesGrid', array('user_id' => Mage::registry('api_user')->getUserId()));
+    }
+
+    protected function _getSelectedRoles($json=false)
+    {
+        if ( $this->getRequest()->getParam('user_roles') != "" ) {
+            return $this->getRequest()->getParam('user_roles');
+        }
+        $uRoles = Mage::registry('api_user')->getRoles();
+        if ($json) {
+            $jsonRoles = Array();
+            foreach($uRoles as $urid) $jsonRoles[$urid] = 0;
+            return Mage::helper('Mage_Core_Helper_Data')->jsonEncode((object)$jsonRoles);
+        } else {
+            return $uRoles;
+        }
+    }
+
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tabs.php b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tabs.php
new file mode 100644
index 00000000000..14851aa8436
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/User/Edit/Tabs.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.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Admin page left menu
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Api_User_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
+{
+
+    protected function _construct()
+    {
+        parent::_construct();
+        $this->setId('page_tabs');
+        $this->setDestElementId('edit_form');
+        $this->setTitle(Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Information'));
+    }
+
+    protected function _beforeToHtml()
+    {
+        $this->addTab('main_section', array(
+            'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Info'),
+            'title'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Info'),
+            'content'   => $this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_User_Edit_Tab_Main')->toHtml(),
+            'active'    => true
+        ));
+
+        $this->addTab('roles_section', array(
+            'label'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Role'),
+            'title'     => Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Role'),
+            'content'   => $this->getLayout()->createBlock(
+                'Mage_Adminhtml_Block_Api_User_Edit_Tab_Roles',
+                'user.roles.grid'
+            )->toHtml(),
+        ));
+        return parent::_beforeToHtml();
+    }
+
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Api/User/Grid.php b/app/code/core/Mage/Adminhtml/Block/Api/User/Grid.php
new file mode 100644
index 00000000000..0e635df6722
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/Block/Api/User/Grid.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Adminhtml permissions user grid
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Block_Api_User_Grid extends Mage_Adminhtml_Block_Widget_Grid
+{
+
+    protected function _construct()
+    {
+        parent::_construct();
+        $this->setId('permissionsUserGrid');
+        $this->setDefaultSort('username');
+        $this->setDefaultDir('asc');
+        $this->setUseAjax(true);
+    }
+
+    protected function _prepareCollection()
+    {
+        $collection = Mage::getResourceModel('Mage_Api_Model_Resource_User_Collection');
+        $this->setCollection($collection);
+        return parent::_prepareCollection();
+    }
+
+    protected function _prepareColumns()
+    {
+        $this->addColumn('user_id', array(
+            'header'    => Mage::helper('Mage_Adminhtml_Helper_Data')->__('ID'),
+            'width'     => 5,
+            'align'     => 'right',
+            'sortable'  => true,
+            'index'     => 'user_id'
+        ));
+
+        $this->addColumn('username', array(
+            'header'    => Mage::helper('Mage_Adminhtml_Helper_Data')->__('User Name'),
+            'index'     => 'username'
+        ));
+
+        $this->addColumn('firstname', array(
+            'header'    => Mage::helper('Mage_Adminhtml_Helper_Data')->__('First Name'),
+            'index'     => 'firstname'
+        ));
+
+        $this->addColumn('lastname', array(
+            'header'    => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Last Name'),
+            'index'     => 'lastname'
+        ));
+
+        $this->addColumn('email', array(
+            'header'    => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Email'),
+            'width'     => 40,
+            'align'     => 'left',
+            'index'     => 'email'
+        ));
+
+        $this->addColumn('is_active', array(
+            'header'    => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Status'),
+            'index'     => 'is_active',
+            'type'      => 'options',
+            'options'   => array('1' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Active'), '0' => Mage::helper('Mage_Adminhtml_Helper_Data')->__('Inactive')),
+        ));
+
+        return parent::_prepareColumns();
+    }
+
+    public function getRowUrl($row)
+    {
+        return $this->getUrl('*/*/edit', array('user_id' => $row->getId()));
+    }
+
+    public function getGridUrl()
+    {
+        //$uid = $this->getRequest()->getParam('user_id');
+        return $this->getUrl('*/*/roleGrid', array());
+    }
+
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php
index 78ad8b75d2d..00cb782c93b 100644
--- a/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php
+++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Category/Tree.php
@@ -149,7 +149,7 @@ class Mage_Adminhtml_Block_Catalog_Category_Tree extends Mage_Adminhtml_Block_Ca
                 }
             }
             $categoryById[$category->getId()]['is_active'] = $category->getIsActive();
-            $categoryById[$category->getId()]['name'] = $category->getName();
+            $categoryById[$category->getId()]['label'] = $category->getName();
             $categoryById[$category->getParentId()]['children'][] = &$categoryById[$category->getId()];
         }
 
diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php
index 586e53d870c..fae5ad7042f 100644
--- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php
+++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Option.php
@@ -154,7 +154,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Option extends Mage_
 
     public function getTypeSelectHtml()
     {
-        $select = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+        $select = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setData(array(
                 'id' => $this->getFieldId().'_{{id}}_type',
                 'class' => 'select select-product-option-type required-option-select'
@@ -167,7 +167,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Option extends Mage_
 
     public function getRequireSelectHtml()
     {
-        $select = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+        $select = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setData(array(
                 'id' => $this->getFieldId().'_{{id}}_is_require',
                 'class' => 'select'
diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Type/Abstract.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Type/Abstract.php
index f23fc2bc472..7724605a743 100644
--- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Type/Abstract.php
+++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Options/Type/Abstract.php
@@ -39,7 +39,7 @@ class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Options_Type_Abstract extend
     protected function _prepareLayout()
     {
         $this->setChild('option_price_type',
-            $this->getLayout()->addBlock('Mage_Adminhtml_Block_Html_Select', '', $this->getNameInLayout())
+            $this->getLayout()->addBlock('Mage_Core_Block_Html_Select', '', $this->getNameInLayout())
                 ->setData(array(
                     'id' => 'product_option_{{option_id}}_price_type',
                     'class' => 'select product-option-price-type'
diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Group.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Group.php
deleted file mode 100644
index bf7f14eafc8..00000000000
--- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Group.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.
- *
- * @category    Mage
- * @package     Mage_Adminhtml
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Product in category grid
- *
- * @category   Mage
- * @package    Mage_Adminhtml
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Group extends Mage_Adminhtml_Block_Widget_Grid
-    implements Mage_Adminhtml_Block_Widget_Tab_Interface
-{
-    protected function _construct()
-    {
-        parent::_construct();
-        $this->setId('super_product_grid');
-        $this->setDefaultSort('entity_id');
-        $this->setSkipGenerateContent(true);
-        $this->setUseAjax(true);
-        if ($this->_getProduct() && $this->_getProduct()->getId()) {
-            $this->setDefaultFilter(array('in_products'=>1));
-        }
-    }
-
-    public function getTabUrl()
-    {
-        return $this->getUrl('*/*/superGroup', array('_current'=>true));
-    }
-
-    public function getTabClass()
-    {
-        return 'ajax';
-    }
-
-    /**
-     * Retrieve currently edited product model
-     *
-     * @return Mage_Catalog_Model_Product
-     */
-    protected function _getProduct()
-    {
-        return Mage::registry('current_product');
-    }
-
-    protected function _addColumnFilterToCollection($column)
-    {
-        // Set custom filter for in product flag
-        if ($column->getId() == 'in_products') {
-            $productIds = $this->_getSelectedProducts();
-            if (empty($productIds)) {
-                $productIds = 0;
-            }
-            if ($column->getFilter()->getValue()) {
-                $this->getCollection()->addFieldToFilter('entity_id', array('in'=>$productIds));
-            }
-            else {
-                $this->getCollection()->addFieldToFilter('entity_id', array('nin'=>$productIds));
-            }
-        }
-        else {
-            parent::_addColumnFilterToCollection($column);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Prepare collection
-     *
-     * @return Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Group
-     */
-    protected function _prepareCollection()
-    {
-        $allowProductTypes = array();
-        $allowProductTypeNodes = Mage::getConfig()
-            ->getNode('global/catalog/product/type/grouped/allow_product_types')->children();
-        foreach ($allowProductTypeNodes as $type) {
-            $allowProductTypes[] = $type->getName();
-        }
-
-        $collection = Mage::getModel('Mage_Catalog_Model_Product_Link')->useGroupedLinks()
-            ->getProductCollection()
-            ->setProduct($this->_getProduct())
-            ->addAttributeToSelect('*')
-            ->addFilterByRequiredOptions()
-            ->addAttributeToFilter('type_id', $allowProductTypes);
-
-        if ($this->getIsReadonly() === true) {
-            $collection->addFieldToFilter('entity_id', array('in' => $this->_getSelectedProducts()));
-        }
-        $this->setCollection($collection);
-        return parent::_prepareCollection();
-    }
-
-    protected function _prepareColumns()
-    {
-        $this->addColumn('in_products', array(
-            'header_css_class' => 'a-center',
-            'type'      => 'checkbox',
-            'name'      => 'in_products',
-            'values'    => $this->_getSelectedProducts(),
-            'align'     => 'center',
-            'index'     => 'entity_id'
-        ));
-
-        $this->addColumn('entity_id', array(
-            'header'    => Mage::helper('Mage_Catalog_Helper_Data')->__('ID'),
-            'sortable'  => true,
-            'width'     => '60px',
-            'index'     => 'entity_id'
-        ));
-        $this->addColumn('name', array(
-            'header'    => Mage::helper('Mage_Catalog_Helper_Data')->__('Name'),
-            'index'     => 'name'
-        ));
-        $this->addColumn('sku', array(
-            'header'    => Mage::helper('Mage_Catalog_Helper_Data')->__('SKU'),
-            'width'     => '80px',
-            'index'     => 'sku'
-        ));
-        $this->addColumn('price', array(
-            'header'    => Mage::helper('Mage_Catalog_Helper_Data')->__('Price'),
-            'type'      => 'currency',
-            'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE),
-            'index'     => 'price'
-        ));
-
-        $this->addColumn('qty', array(
-            'header'    => Mage::helper('Mage_Catalog_Helper_Data')->__('Default Qty'),
-            'name'      => 'qty',
-            'type'      => 'number',
-            'validate_class' => 'validate-number',
-            'index'     => 'qty',
-            'width'     => '1',
-            'editable'  => true
-        ));
-
-        $this->addColumn('position', array(
-            'header'    => Mage::helper('Mage_Catalog_Helper_Data')->__('Position'),
-            'name'      => 'position',
-            'type'      => 'number',
-            'validate_class' => 'validate-number',
-            'index'     => 'position',
-            'width'     => '1',
-            'editable'  => true,
-            'edit_only' => !$this->_getProduct()->getId()
-        ));
-
-        return parent::_prepareColumns();
-    }
-
-    /**
-     * Get Grid Url
-     *
-     * @return string
-     */
-    public function getGridUrl()
-    {
-        return $this->_getData('grid_url')
-            ? $this->_getData('grid_url') : $this->getUrl('*/*/superGroupGridOnly', array('_current'=>true));
-    }
-
-    /**
-     * Retrieve selected grouped products
-     *
-     * @return array
-     */
-    protected function _getSelectedProducts()
-    {
-        $products = $this->getProductsGrouped();
-        if (!is_array($products)) {
-            $products = array_keys($this->getSelectedGroupedProducts());
-        }
-        return $products;
-    }
-
-    /**
-     * Retrieve grouped products
-     *
-     * @return array
-     */
-    public function getSelectedGroupedProducts()
-    {
-        $associatedProducts = Mage::registry('current_product')->getTypeInstance()
-            ->getAssociatedProducts(Mage::registry('current_product'));
-        $products = array();
-        foreach ($associatedProducts as $product) {
-            $products[$product->getId()] = array(
-                'qty'       => $product->getQty(),
-                'position'  => $product->getPosition()
-            );
-        }
-        return $products;
-    }
-
-    public function getTabLabel()
-    {
-        return Mage::helper('Mage_Catalog_Helper_Data')->__('Associated Products');
-    }
-    public function getTabTitle()
-    {
-        return Mage::helper('Mage_Catalog_Helper_Data')->__('Associated Products');
-    }
-    public function canShowTab()
-    {
-        return true;
-    }
-    public function isHidden()
-    {
-        return false;
-    }
-}
diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Frontend/Product/Watermark.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Frontend/Product/Watermark.php
index 223400b1163..b94eff85227 100644
--- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Frontend/Product/Watermark.php
+++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Frontend/Product/Watermark.php
@@ -31,7 +31,9 @@
  * @package    Mage_Adminhtml
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Adminhtml_Block_Catalog_Product_Frontend_Product_Watermark extends Mage_Adminhtml_Block_Abstract implements Varien_Data_Form_Element_Renderer_Interface
+class Mage_Adminhtml_Block_Catalog_Product_Frontend_Product_Watermark
+    extends Mage_Core_Block_Template
+    implements Varien_Data_Form_Element_Renderer_Interface
 {
     const XML_PATH_IMAGE_TYPES = 'global/catalog/product/media/image_types';
 
diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php
index 9cdbb7bb09e..3bee6f60ffb 100644
--- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php
+++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Helper/Form/Category.php
@@ -76,11 +76,46 @@ class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Category extends Varien_D
     {
         /** @var $coreHelper Mage_Core_Helper_Data */
         $coreHelper = Mage::helper('Mage_Core_Helper_Data');
+        $treeOptions = $coreHelper->escapeHtml($coreHelper->jsonEncode(array(
+            'jstree' => array(
+                'plugins' => array('themes', 'html_data', 'ui', 'hotkeys'),
+                'themes' => array(
+                    'theme' => 'default',
+                    'dots' => false,
+                    'icons' => false,
+                ),
+            )
+        )));
+
         return parent::getElementHtml() . "\n"
+            . '<input id="' . $this->getHtmlId() . '-suggest" />' . "\n"
+            . '<script id="' . $this->getHtmlId() . '-template" type="text/x-jquery-tmpl">'
+            . '{{if $data.allShown()}}'
+                . '{{if typeof nested === "undefined"}}'
+                . '<div style="display:none;" data-mage-init="' . $treeOptions . '">{{/if}}'
+                . '<ul>{{each items}}'
+                . '<li><a href="#" {{html optionData($value)}}>${$value.label}</a>'
+                . '{{if $value.children && $value.children.length}}'
+                . '{{html renderTreeLevel($value.children)}}'
+                . '{{/if}}'
+                . '</li>{{/each}}</ul>'
+                . '{{if typeof nested === "undefined"}}</div>{{/if}}'
+            . '{{else}}'
+                . '<ul data-mage-init="{&quot;menu&quot;:[]}">'
+                . '{{each items}}'
+                . '<li {{html optionData($value)}}><a href="#"><span class="category-label">${$value.label}<span>'
+                . '<span class="category-path">${$value.path}<span></a></li>'
+                . '{{/each}}</ul>'
+            . '{{/if}}'
+            . '</script>' . "\n"
             . '<script>//<![CDATA[' . "\n"
-            . 'jQuery(' . $coreHelper->jsonEncode('#' . $this->getHtmlId()) . ').categorySelector('
-            . $coreHelper->jsonEncode($this->_getSelectorOptions()) . ')' . "\n"
-            . '//]]></script>';
+            . 'jQuery(' . $coreHelper->jsonEncode('#' . $this->getHtmlId() . '-suggest') . ').treeSuggest('
+            . $coreHelper->jsonEncode($this->_getSelectorOptions()) . ');' . "\n"
+            . '//]]></script>'
+            . '<button title="' . $coreHelper->__('New Category') . '" type="button"'
+            . ' onclick="jQuery(\'#new-category\').dialog(\'open\')">'
+            . '<span><span><span>' . $coreHelper->__('New Category') . '</span></span></span>'
+            . '</button>';
     }
 
     /**
@@ -91,7 +126,12 @@ class Mage_Adminhtml_Block_Catalog_Product_Helper_Form_Category extends Varien_D
     protected function _getSelectorOptions()
     {
         return array(
-            'url' => Mage::helper('Mage_Backend_Helper_Data')->getUrl('adminhtml/catalog_category/suggestCategories'),
+            'source' => Mage::helper('Mage_Backend_Helper_Data')
+                ->getUrl('adminhtml/catalog_category/suggestCategories'),
+            'valueField' => '#' . $this->getHtmlId(),
+            'template' => '#' . $this->getHtmlId() . '-template',
+            'control' => 'jstree',
+            'className' => 'category-select'
         );
     }
 }
diff --git a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Options/Ajax.php b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Options/Ajax.php
index c7d8b7fbc85..171985da8a1 100644
--- a/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Options/Ajax.php
+++ b/app/code/core/Mage/Adminhtml/Block/Catalog/Product/Options/Ajax.php
@@ -31,7 +31,7 @@
  * @package    Mage_Adminhtml
  * @author     Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Adminhtml_Block_Catalog_Product_Options_Ajax extends Mage_Backend_Block_Abstract
+class Mage_Adminhtml_Block_Catalog_Product_Options_Ajax extends Mage_Core_Block_Template
 {
     /**
      * Return product custom options in JSON format
diff --git a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Newpass.php b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Newpass.php
index b9b92e25849..bb570115e48 100644
--- a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Newpass.php
+++ b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Newpass.php
@@ -31,7 +31,9 @@
  * @package    Mage_Adminhtml
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Adminhtml_Block_Customer_Edit_Renderer_Newpass extends Mage_Adminhtml_Block_Abstract implements Varien_Data_Form_Element_Renderer_Interface
+class Mage_Adminhtml_Block_Customer_Edit_Renderer_Newpass
+    extends Mage_Core_Block_Template
+    implements Varien_Data_Form_Element_Renderer_Interface
 {
 
     public function render(Varien_Data_Form_Element_Abstract $element)
diff --git a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Region.php b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Region.php
index b8b99879cf5..7a011f5e6ff 100644
--- a/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Region.php
+++ b/app/code/core/Mage/Adminhtml/Block/Customer/Edit/Renderer/Region.php
@@ -30,7 +30,7 @@
  * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Mage_Adminhtml_Block_Customer_Edit_Renderer_Region
-    extends Mage_Adminhtml_Block_Abstract
+    extends Mage_Core_Block_Template
     implements Varien_Data_Form_Element_Renderer_Interface
 {
     /**
diff --git a/app/code/core/Mage/Adminhtml/Block/Html/Date.php b/app/code/core/Mage/Adminhtml/Block/Html/Date.php
deleted file mode 100644
index 63927e368da..00000000000
--- a/app/code/core/Mage/Adminhtml/Block/Html/Date.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.
- *
- * @category    Mage
- * @package     Mage_Adminhtml
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-
-/**
- * Adminhtml HTML select element block
- *
- * @category   Mage
- * @package    Mage_Core
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Mage_Adminhtml_Block_Html_Date extends Mage_Core_Block_Html_Date
-{
-
-    /**
-     * @param Mage_Core_Controller_Request_Http $request
-     * @param Mage_Core_Model_Layout $layout
-     * @param Mage_Core_Model_Event_Manager $eventManager
-     * @param Mage_Backend_Model_Url $urlBuilder
-     * @param Mage_Core_Model_Translate $translator
-     * @param Mage_Core_Model_Cache $cache
-     * @param Mage_Core_Model_Design_Package $designPackage
-     * @param Mage_Core_Model_Session $session
-     * @param Mage_Core_Model_Store_Config $storeConfig
-     * @param Mage_Core_Controller_Varien_Front $frontController
-     * @param Mage_Core_Model_Factory_Helper $helperFactory
-     * @param Magento_Filesystem $filesystem
-     * @param array $data
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        Mage_Core_Controller_Request_Http $request,
-        Mage_Core_Model_Layout $layout,
-        Mage_Core_Model_Event_Manager $eventManager,
-        Mage_Backend_Model_Url $urlBuilder,
-        Mage_Core_Model_Translate $translator,
-        Mage_Core_Model_Cache $cache,
-        Mage_Core_Model_Design_Package $designPackage,
-        Mage_Core_Model_Session $session,
-        Mage_Core_Model_Store_Config $storeConfig,
-        Mage_Core_Controller_Varien_Front $frontController,
-        Mage_Core_Model_Factory_Helper $helperFactory,
-        Magento_Filesystem $filesystem,
-        array $data = array()
-    ) {
-        parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
-        );
-    }
-}
diff --git a/app/code/core/Mage/Adminhtml/Block/Html/Select.php b/app/code/core/Mage/Adminhtml/Block/Html/Select.php
deleted file mode 100644
index 7f41c1c581d..00000000000
--- a/app/code/core/Mage/Adminhtml/Block/Html/Select.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.
- *
- * @category    Mage
- * @package     Mage_Adminhtml
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Adminhtml HTML select element block
- *
- * @category    Mage
- * @package     Mage_Core
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Mage_Adminhtml_Block_Html_Select extends Mage_Core_Block_Html_Select
-{
-    /**
-     * @param Mage_Core_Controller_Request_Http $request
-     * @param Mage_Core_Model_Layout $layout
-     * @param Mage_Core_Model_Event_Manager $eventManager
-     * @param Mage_Backend_Model_Url $urlBuilder
-     * @param Mage_Core_Model_Translate $translator
-     * @param Mage_Core_Model_Cache $cache
-     * @param Mage_Core_Model_Design_Package $designPackage
-     * @param Mage_Core_Model_Session $session
-     * @param Mage_Core_Model_Store_Config $storeConfig
-     * @param Mage_Core_Controller_Varien_Front $frontController
-     * @param Mage_Core_Model_Factory_Helper $helperFactory
-     * @param array $data
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        Mage_Core_Controller_Request_Http $request,
-        Mage_Core_Model_Layout $layout,
-        Mage_Core_Model_Event_Manager $eventManager,
-        Mage_Backend_Model_Url $urlBuilder,
-        Mage_Core_Model_Translate $translator,
-        Mage_Core_Model_Cache $cache,
-        Mage_Core_Model_Design_Package $designPackage,
-        Mage_Core_Model_Session $session,
-        Mage_Core_Model_Store_Config $storeConfig,
-        Mage_Core_Controller_Varien_Front $frontController,
-        Mage_Core_Model_Factory_Helper $helperFactory,
-        array $data = array()
-    ) {
-        parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $data
-        );
-    }
-}
diff --git a/app/code/core/Mage/Adminhtml/Block/Messages.php b/app/code/core/Mage/Adminhtml/Block/Messages.php
deleted file mode 100644
index 84d07a3a1da..00000000000
--- a/app/code/core/Mage/Adminhtml/Block/Messages.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.
- *
- * @category    Mage
- * @package     Mage_Adminhtml
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-
-/**
- * Adminhtml messages block
- *
- * @category   Mage
- * @package    Mage_Adminhtml
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Mage_Adminhtml_Block_Messages extends Mage_Core_Block_Messages
-{
-    /**
-     * @param Mage_Core_Controller_Request_Http $request
-     * @param Mage_Core_Model_Layout $layout
-     * @param Mage_Core_Model_Event_Manager $eventManager
-     * @param Mage_Backend_Model_Url $urlBuilder
-     * @param Mage_Core_Model_Translate $translator
-     * @param Mage_Core_Model_Cache $cache
-     * @param Mage_Core_Model_Design_Package $designPackage
-     * @param Mage_Core_Model_Session $session
-     * @param Mage_Core_Model_Store_Config $storeConfig
-     * @param Mage_Core_Controller_Varien_Front $frontController
-     * @param Mage_Core_Model_Factory_Helper $helperFactory
-     * @param Magento_Filesystem $filesystem
-     * @param array $data
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        Mage_Core_Controller_Request_Http $request,
-        Mage_Core_Model_Layout $layout,
-        Mage_Core_Model_Event_Manager $eventManager,
-        Mage_Backend_Model_Url $urlBuilder,
-        Mage_Core_Model_Translate $translator,
-        Mage_Core_Model_Cache $cache,
-        Mage_Core_Model_Design_Package $designPackage,
-        Mage_Core_Model_Session $session,
-        Mage_Core_Model_Store_Config $storeConfig,
-        Mage_Core_Controller_Varien_Front $frontController,
-        Mage_Core_Model_Factory_Helper $helperFactory,
-        Magento_Filesystem $filesystem,
-        array $data = array()
-    ) {
-        parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
-    }
-}
diff --git a/app/code/core/Mage/Adminhtml/Block/Notification/Baseurl.php b/app/code/core/Mage/Adminhtml/Block/Notification/Baseurl.php
index db427839100..c220ca7c681 100644
--- a/app/code/core/Mage/Adminhtml/Block/Notification/Baseurl.php
+++ b/app/code/core/Mage/Adminhtml/Block/Notification/Baseurl.php
@@ -36,13 +36,15 @@ class Mage_Adminhtml_Block_Notification_Baseurl extends Mage_Adminhtml_Block_Tem
         $defaultUnsecure= (string) Mage::getConfig()->getNode('default/'.Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL);
         $defaultSecure  = (string) Mage::getConfig()->getNode('default/'.Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL);
 
-        if ($defaultSecure == '{{base_url}}' || $defaultUnsecure == '{{base_url}}') {
+        if ($defaultSecure == Mage_Core_Model_Store::BASE_URL_PLACEHOLDER
+            || $defaultUnsecure == Mage_Core_Model_Store::BASE_URL_PLACEHOLDER
+        ) {
             return $this->getUrl('adminhtml/system_config/edit', array('section'=>'web'));
         }
 
         $configData = Mage::getModel('Mage_Core_Model_Config_Data');
         $dataCollection = $configData->getCollection()
-            ->addValueFilter('{{base_url}}');
+            ->addValueFilter(Mage_Core_Model_Store::BASE_URL_PLACEHOLDER);
 
         $url = false;
         foreach ($dataCollection as $data) {
diff --git a/app/code/core/Mage/Adminhtml/Block/Page/Footer.php b/app/code/core/Mage/Adminhtml/Block/Page/Footer.php
index e478fdffe24..7005c3ddbbc 100644
--- a/app/code/core/Mage/Adminhtml/Block/Page/Footer.php
+++ b/app/code/core/Mage/Adminhtml/Block/Page/Footer.php
@@ -67,7 +67,7 @@ class Mage_Adminhtml_Block_Page_Footer extends Mage_Adminhtml_Block_Template
         $html    = Mage::app()->loadCache($cacheId);
 
         if (!$html) {
-            $html = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+            $html = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
                 ->setName('locale')
                 ->setId('interface_locale')
                 ->setTitle(Mage::helper('Mage_Page_Helper_Data')->__('Interface Language'))
diff --git a/app/code/core/Mage/Adminhtml/Block/Page/Head.php b/app/code/core/Mage/Adminhtml/Block/Page/Head.php
index 2ea53cbc569..547514f11c1 100644
--- a/app/code/core/Mage/Adminhtml/Block/Page/Head.php
+++ b/app/code/core/Mage/Adminhtml/Block/Page/Head.php
@@ -47,6 +47,8 @@ class Mage_Adminhtml_Block_Page_Head extends Mage_Page_Block_Html_Head
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param array $data
      *
@@ -64,11 +66,13 @@ class Mage_Adminhtml_Block_Page_Head extends Mage_Page_Block_Html_Head
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
     }
 
diff --git a/app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Labels.php b/app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Labels.php
index 06288f4a741..2b3c08e6335 100644
--- a/app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Labels.php
+++ b/app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Labels.php
@@ -36,6 +36,8 @@ class Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_Labels
     protected $_app;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -47,6 +49,8 @@ class Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_Labels
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_App $app
      * @param array $data
@@ -65,13 +69,15 @@ class Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_Labels
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_App $app,
         array $data = array()
     ) {
         $this->_app = $app;
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
     }
 
diff --git a/app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Main/Renderer/Checkbox.php b/app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Main/Renderer/Checkbox.php
index 9066114ea7e..8e103aeca0c 100644
--- a/app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Main/Renderer/Checkbox.php
+++ b/app/code/core/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/Main/Renderer/Checkbox.php
@@ -32,7 +32,7 @@
  * @author     Magento Core Team <core@magentocommerce.com>
  */
 class Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_Main_Renderer_Checkbox
-    extends Mage_Adminhtml_Block_Abstract
+    extends Mage_Core_Block_Template
     implements Varien_Data_Form_Element_Renderer_Interface
 {
     /**
diff --git a/app/code/core/Mage/Adminhtml/Block/Promo/Widget/Chooser/Daterange.php b/app/code/core/Mage/Adminhtml/Block/Promo/Widget/Chooser/Daterange.php
index 3573522dc49..0030bce0a18 100644
--- a/app/code/core/Mage/Adminhtml/Block/Promo/Widget/Chooser/Daterange.php
+++ b/app/code/core/Mage/Adminhtml/Block/Promo/Widget/Chooser/Daterange.php
@@ -28,7 +28,7 @@
  * Date range promo widget chooser
  * Currently works without localized format
  */
-class Mage_Adminhtml_Block_Promo_Widget_Chooser_Daterange extends Mage_Adminhtml_Block_Abstract
+class Mage_Adminhtml_Block_Promo_Widget_Chooser_Daterange extends Mage_Core_Block_Template
 {
     /**
      * HTML ID of the element that will obtain the joined chosen values
diff --git a/app/code/core/Mage/Adminhtml/Block/Rating/Edit/Tab/Form.php b/app/code/core/Mage/Adminhtml/Block/Rating/Edit/Tab/Form.php
index b1305f78967..fc4d93df92d 100644
--- a/app/code/core/Mage/Adminhtml/Block/Rating/Edit/Tab/Form.php
+++ b/app/code/core/Mage/Adminhtml/Block/Rating/Edit/Tab/Form.php
@@ -42,6 +42,8 @@ class Mage_Adminhtml_Block_Rating_Edit_Tab_Form extends Mage_Backend_Block_Widge
     protected $_app;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -53,6 +55,8 @@ class Mage_Adminhtml_Block_Rating_Edit_Tab_Form extends Mage_Backend_Block_Widge
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_App $app
      * @param array $data
@@ -71,13 +75,15 @@ class Mage_Adminhtml_Block_Rating_Edit_Tab_Form extends Mage_Backend_Block_Widge
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_App $app,
         array $data = array()
     ) {
         $this->_app = $app;
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
     }
 
diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Messages.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Messages.php
index d650589a44f..034f003835a 100644
--- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Messages.php
+++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/Create/Messages.php
@@ -31,7 +31,7 @@
  * @package    Mage_Adminhtml
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Adminhtml_Block_Sales_Order_Create_Messages extends Mage_Adminhtml_Block_Messages
+class Mage_Adminhtml_Block_Sales_Order_Create_Messages extends Mage_Core_Block_Messages
 {
 
     public function _prepareLayout()
diff --git a/app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Messages.php b/app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Messages.php
index 649fbf39db9..4fad233aa85 100644
--- a/app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Messages.php
+++ b/app/code/core/Mage/Adminhtml/Block/Sales/Order/View/Messages.php
@@ -31,7 +31,7 @@
  * @package    Mage_Adminhtml
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Adminhtml_Block_Sales_Order_View_Messages extends Mage_Adminhtml_Block_Messages
+class Mage_Adminhtml_Block_Sales_Order_View_Messages extends Mage_Core_Block_Messages
 {
 
     protected function _getOrder()
diff --git a/app/code/core/Mage/Adminhtml/Block/System/Currency/Rate/Services.php b/app/code/core/Mage/Adminhtml/Block/System/Currency/Rate/Services.php
index d29e500b04c..f1e276eafe4 100644
--- a/app/code/core/Mage/Adminhtml/Block/System/Currency/Rate/Services.php
+++ b/app/code/core/Mage/Adminhtml/Block/System/Currency/Rate/Services.php
@@ -44,7 +44,7 @@ class Mage_Adminhtml_Block_System_Currency_Rate_Services extends Mage_Adminhtml_
     protected function _prepareLayout()
     {
         $this->setChild('import_services',
-            $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+            $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setOptions(Mage::getModel('Mage_Backend_Model_Config_Source_Currency_Service')->toOptionArray(0))
             ->setId('rate_services')
             ->setName('rate_services')
diff --git a/app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php b/app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php
index 1f6840ff299..2ada9fa34bf 100644
--- a/app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php
+++ b/app/code/core/Mage/Adminhtml/Block/System/Email/Template/Edit.php
@@ -61,6 +61,8 @@ class Mage_Adminhtml_Block_System_Email_Template_Edit extends Mage_Adminhtml_Blo
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_Registry $registry
      * @param Mage_Backend_Model_Menu_Config $menuConfig
@@ -81,6 +83,8 @@ class Mage_Adminhtml_Block_System_Email_Template_Edit extends Mage_Adminhtml_Blo
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_Registry $registry,
         Mage_Backend_Model_Menu_Config $menuConfig,
@@ -89,7 +93,8 @@ class Mage_Adminhtml_Block_System_Email_Template_Edit extends Mage_Adminhtml_Blo
     )
     {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache,
-            $designPackage, $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $designPackage, $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
+        );
         $this->_registryManager = $registry;
         $this->_menuConfig = $menuConfig;
         $this->_configStructure = $configStructure;
diff --git a/app/code/core/Mage/Adminhtml/Model/Extension.php b/app/code/core/Mage/Adminhtml/Model/Extension.php
deleted file mode 100644
index f28c0b5c32a..00000000000
--- a/app/code/core/Mage/Adminhtml/Model/Extension.php
+++ /dev/null
@@ -1,402 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Mage
- * @package     Mage_Adminhtml
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-class Mage_Adminhtml_Model_Extension extends Varien_Object
-{
-    protected $_roles;
-
-    /**
-     * @var Magento_Filesystem
-     */
-    protected $_filesystem;
-
-    /**
-     * Constructor
-     *
-     * @param Magento_Filesystem $filesystem
-     * @param array $data
-     */
-    public function __construct(Magento_Filesystem $filesystem, array $data = array())
-    {
-        $this->_filesystem = $filesystem;
-        $this->_filesystem->setIsAllowCreateDirectories(true);
-        $this->_filesystem->setWorkingDirectory($this->getRoleDir('mage'));
-        parent::__construct($data);
-    }
-
-    public function getPear()
-    {
-        return Varien_Pear::getInstance();
-    }
-
-    public function generatePackageXml()
-    {
-        Mage::getSingleton('Mage_Adminhtml_Model_Session')
-            ->setLocalExtensionPackageFormData($this->getData());
-
-        Varien_Pear::$reloadOnRegistryUpdate = false;
-        $pkg = new Varien_Pear_Package;
-        #$pkg->getPear()->runHtmlConsole(array('command'=>'list-channels'));
-        $pfm = $pkg->getPfm();
-        $pfm->setOptions(array(
-            'packagedirectory'=>'.',
-            'baseinstalldir'=>'.',
-            'simpleoutput'=>true,
-        ));
-
-        $this->_setPackage($pfm);
-        $this->_setRelease($pfm);
-        $this->_setMaintainers($pfm);
-        $this->_setDependencies($pfm);
-        $this->_setContents($pfm);
-#echo "<pre>".print_r($pfm,1)."</pre>";
-        if (!$pfm->validate(PEAR_VALIDATE_NORMAL)) {
-            //echo "<pre>".print_r($this->getData(),1)."</pre>";
-            //echo "TEST:";
-            //echo "<pre>".print_r($pfm->getValidationWarnings(), 1)."</pre>";
-            $message = $pfm->getValidationWarnings();
-            //$message = $message[0]['message'];
-             throw Mage::exception('Mage_Adminhtml', Mage::helper('Mage_Adminhtml_Helper_Data')->__($message[0]['message']));
-
-            return $this;
-        }
-
-        $this->setPackageXml($pfm->getDefaultGenerator()->toXml(PEAR_VALIDATE_NORMAL));
-        return $this;
-    }
-
-    protected function _setPackage($pfm)
-    {
-        $pfm->setPackageType('php');
-        $pfm->setChannel($this->getData('channel'));
-
-    $pfm->setLicense($this->getData('license'), $this->getData('license_uri'));
-
-        $pfm->setPackage($this->getData('name'));
-        $pfm->setSummary($this->getData('summary'));
-        $pfm->setDescription($this->getData('description'));
-    }
-
-    protected function _setRelease($pfm)
-    {
-        $pfm->addRelease();
-        $pfm->setDate(date('Y-m-d'));
-
-        $pfm->setAPIVersion($this->getData('api_version'));
-        $pfm->setReleaseVersion($this->getData('release_version'));
-        $pfm->setAPIStability($this->getData('api_stability'));
-        $pfm->setReleaseStability($this->getData('release_stability'));
-        $pfm->setNotes($this->getData('notes'));
-    }
-
-    protected function _setMaintainers($pfm)
-    {
-        $maintainers = $this->getData('maintainers');
-        foreach ($maintainers['role'] as $i=>$role) {
-            if (0===$i) {
-                continue;
-            }
-            $handle = $maintainers['handle'][$i];
-            $name = $maintainers['name'][$i];
-            $email = $maintainers['email'][$i];
-            $active = !empty($maintainers['active'][$i]) ? 'yes' : 'no';
-            $pfm->addMaintainer($role, $handle, $name, $email, $active);
-        }
-    }
-
-    protected function _setDependencies($pfm)
-    {
-        $pfm->clearDeps();
-        $exclude = $this->getData('depends_php_exclude')!=='' ? explode(',', $this->getData('depends_php_exclude')) : false;
-        $pfm->setPhpDep($this->getData('depends_php_min'), $this->getData('depends_php_max'), $exclude);
-        $pfm->setPearinstallerDep('1.6.2');
-
-        foreach ($this->getData('depends') as $deptype=>$deps) {
-            foreach ($deps['type'] as $i=>$type) {
-                if (0===$i) {
-                    continue;
-                }
-                $name = $deps['name'][$i];
-                $min = !empty($deps['min'][$i]) ? $deps['min'][$i] : false;
-                $max = !empty($deps['max'][$i]) ? $deps['max'][$i] : false;
-                $recommended = !empty($deps['recommended'][$i]) ? $deps['recommended'][$i] : false;
-                $exclude = !empty($deps['exclude'][$i]) ? explode(',', $deps['exclude'][$i]) : false;
-                if ($deptype!=='extension') {
-                    $channel = !empty($deps['channel'][$i]) ? $deps['channel'][$i] : 'connect.magentocommerce.com/core';
-                }
-                switch ($deptype) {
-                    case 'package':
-                        if ($type==='conflicts') {
-                            $pfm->addConflictingPackageDepWithChannel(
-                                $name, $channel, false, $min, $max, $recommended, $exclude);
-                        } else {
-                            $pfm->addPackageDepWithChannel(
-                                $type, $name, $channel, $min, $max, $recommended, $exclude);
-                        }
-                        break;
-
-                    case 'subpackage':
-                        if ($type==='conflicts') {
-                            Mage::throwException(Mage::helper('Mage_Adminhtml_Helper_Data')->__("Subpackage cannot be conflicting."));
-                        }
-                        $pfm->addSubpackageDepWithChannel(
-                            $type, $name, $channel, $min, $max, $recommended, $exclude);
-                        break;
-
-                    case 'extension':
-                        $pfm->addExtensionDep(
-                            $type, $name, $min, $max, $recommended, $exclude);
-                        break;
-                }
-            }
-        }
-    }
-
-    protected function _setContents($pfm)
-    {
-        $pfm->clearContents();
-        $contents = $this->getData('contents');
-        $usesRoles = array();
-        foreach ($contents['role'] as $i=>$role) {
-            if (0===$i) {
-                continue;
-            }
-
-            $usesRoles[$role] = 1;
-
-            $roleDir = $this->getRoleDir($role).DS;
-            $fullPath = $roleDir.$contents['path'][$i];
-
-            switch ($contents['type'][$i]) {
-                case 'file':
-                    if (!$this->_filesystem->isFile($fullPath)) {
-                        Mage::throwException(Mage::helper('Mage_Adminhtml_Helper_Data')->__("Invalid file: %s", $fullPath));
-                    }
-                    $pfm->addFile('/', $contents['path'][$i],
-                        array('role' => $role, 'md5sum' => $this->_filesystem->getFileMd5($fullPath)));
-                    break;
-
-                case 'dir':
-                    if (!$this->_filesystem->isDirectory($fullPath)) {
-                        Mage::throwException(Mage::helper('Mage_Adminhtml_Helper_Data')->__("Invalid directory: %s", $fullPath));
-                    }
-                    $path = $contents['path'][$i];
-                    $include = $contents['include'][$i];
-                    $ignore = $contents['ignore'][$i];
-                    $this->_addDir($pfm, $role, $roleDir, $path, $include, $ignore);
-                    break;
-            }
-        }
-
-        $pearRoles = $this->getRoles();
-#echo "<pre>".print_r($usesRoles,1)."</pre>";
-        foreach ($usesRoles as $role=>$dummy) {
-            if (empty($pearRoles[$role]['package'])) {
-                continue;
-            }
-            $pfm->addUsesrole($role, $pearRoles[$role]['package']);
-        }
-    }
-
-    protected function _addDir($pfm, $role, $roleDir, $path, $include, $ignore)
-    {
-        $roleDirLen = strlen($roleDir);
-        $entries = $this->_filesystem->getNestedKeys($roleDir . $path . DS);
-        if (!empty($entries)) {
-            foreach ($entries as $entry) {
-                $filePath = substr($entry, $roleDirLen);
-                if (!empty($include) && !preg_match($include, $filePath)) {
-                    continue;
-                }
-                if (!empty($ignore) && preg_match($ignore, $filePath)) {
-                    continue;
-                }
-                if ($this->_filesystem->isFile($entry)) {
-                    $pfm->addFile('/', $filePath,
-                        array('role' => $role, 'md5sum' => $this->_filesystem->getFileMd5($entry)));
-                }
-            }
-        }
-    }
-
-    public function getRoles()
-    {
-        if (!$this->_roles) {
-            $frontend = $this->getPear()->getFrontend();
-            $config = $this->getPear()->getConfig();
-            $pearMage = new PEAR_Command_Mage($frontend, $config);
-            $this->_roles = $pearMage->getRoles();
-        }
-        return $this->_roles;
-    }
-
-    public function getRoleDir($role)
-    {
-        $roles = $this->getRoles();
-        return Varien_Pear::getInstance()->getConfig()->get($roles[$role]['dir_config']);
-    }
-
-    public function getMaintainerRoles()
-    {
-        return array(
-            'lead'=>'Lead',
-            'developer'=>'Developer',
-            'contributor'=>'Contributor',
-            'helper'=>'Helper'
-        );
-    }
-
-    public function savePackage()
-    {
-        if ($this->getData('file_name') != '') {
-            $fileName = $this->getData('file_name');
-            $this->unsetData('file_name');
-        } else {
-            $fileName = $this->getName();
-        }
-
-        if (!preg_match('/^[a-z0-9]+[a-z0-9\-\_\.]*([\/\\\\]{1}[a-z0-9]+[a-z0-9\-\_\.]*)*$/i', $fileName)) {
-            return false;
-        }
-
-        if (!$this->getPackageXml()) {
-            $this->generatePackageXml();
-        }
-        if (!$this->getPackageXml()) {
-            return false;
-        }
-
-        $pear = Varien_Pear::getInstance();
-        $dir = Mage::getBaseDir('var').DS.'pear';
-        try {
-            $this->_filesystem->write($dir.DS.'package.xml', $this->getPackageXml());
-        } catch (Magento_Filesystem_Exception $e) {
-            return false;
-        }
-
-        $pkgver = $this->getName().'-'.$this->getReleaseVersion();
-        $this->unsPackageXml();
-        $this->unsRoles();
-        $xml = Mage::helper('Mage_Core_Helper_Data')->assocToXml($this->getData());
-        $xml = new Varien_Simplexml_Element($xml->asXML());
-
-        try {
-            $this->_filesystem->write($dir . DS . $fileName . '.xml', $xml->asNiceXml());
-        } catch (Magento_Filesystem_Exception $e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public function createPackage()
-    {
-        $pear = Varien_Pear::getInstance();
-        $dir = Mage::getBaseDir('var').DS.'pear';
-        if (!Mage::getConfig()->createDirIfNotExists($dir)) {
-            return false;
-        }
-        $curDir = getcwd();
-        chdir($dir);
-        $result = $pear->run('mage-package', array(), array('package.xml'));
-        chdir($curDir);
-        if ($result instanceof PEAR_Error) {
-            return $result;
-        }
-        return true;
-    }
-
-
-    public function getStabilityOptions()
-    {
-        return array(
-            'devel'=>'Development',
-            'alpha'=>'Alpha',
-            'beta'=>'Beta',
-            'stable'=>'Stable',
-        );
-    }
-
-    public function getKnownChannels()
-    {
-        /*
-        $pear = Varien_Pear::getInstance();
-        $pear->run('list-channels');
-        $output = $pear->getOutput();
-        $pear->getFrontend()->clear();
-
-        $data = $output[0]['output']['data'];
-        $arr = array();
-        foreach ($data as $channel) {
-            $arr[$channel[0]] = $channel[1].' ('.$channel[0].')';
-        }
-        */
-        $arr = array(
-            'connect.magentocommerce.com/core' => 'Magento Core Team',
-            'connect.magentocommerce.com/community' => 'Magento Community',
-            #'pear.php.net' => 'PEAR',
-            #'pear.phpunit.de' => 'PHPUnit',
-        );
-        return $arr;
-    }
-
-    public function loadLocal($package, $options=array())
-    {
-        $pear = $this->getPear();
-
-        $pear->getFrontend()->clear();
-
-        $result = $pear->run('info', $options, array($package));
-        if ($result instanceof PEAR_Error) {
-            Mage::throwException($result->message);
-            break;
-        }
-
-        $output = $pear->getOutput();
-        $pkg = new PEAR_PackageFile_v2;
-        $pkg->fromArray($output[0]['output']['raw']);
-
-        return $pkg;
-    }
-
-    public function loadRemote($package, $options=array())
-    {
-        $pear = $this->getPear();
-
-        $pear->getFrontend()->clear();
-
-        $result = $pear->run('remote-info', $options, array($package));
-        if ($result instanceof PEAR_Error) {
-            Mage::throwException($result->message);
-            break;
-        }
-
-        $output = $pear->getOutput();
-        $this->setData($output[0]['output']);
-
-        return $this;
-    }
-}
diff --git a/app/code/core/Mage/Adminhtml/controllers/Api/RoleController.php b/app/code/core/Mage/Adminhtml/controllers/Api/RoleController.php
new file mode 100644
index 00000000000..8b5823da1a9
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/controllers/Api/RoleController.php
@@ -0,0 +1,217 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Adminhtml roles controller
+ *
+ * @category   Mage
+ * @package    Mage_Adminhtml
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Adminhtml_Api_RoleController extends Mage_Adminhtml_Controller_Action
+{
+
+    protected function _initAction()
+    {
+        $this->loadLayout();
+        $this->_setActiveMenu('Mage_Api::system_legacy_api_roles');
+        $this->_addBreadcrumb($this->__('Web services'), $this->__('Web services'));
+        $this->_addBreadcrumb($this->__('Permissions'), $this->__('Permissions'));
+        $this->_addBreadcrumb($this->__('Roles'), $this->__('Roles'));
+        return $this;
+    }
+
+    public function indexAction()
+    {
+        $this->_title($this->__('System'))
+             ->_title($this->__('Web Services'))
+             ->_title($this->__('Roles'));
+
+        $this->_initAction();
+
+        $this->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_Roles'));
+
+        $this->renderLayout();
+    }
+
+    public function roleGridAction()
+    {
+        $this->getResponse()
+            ->setBody($this->getLayout()
+            ->createBlock('Mage_Adminhtml_Block_Api_Grid_Role')
+            ->toHtml()
+        );
+    }
+
+    public function editRoleAction()
+    {
+        $this->_title($this->__('System'))
+             ->_title($this->__('Web Services'))
+             ->_title($this->__('Roles'));
+
+        $this->_initAction();
+
+        $roleId = $this->getRequest()->getParam('rid');
+        if( intval($roleId) > 0 ) {
+            $breadCrumb = $this->__('Edit Role');
+            $breadCrumbTitle = $this->__('Edit Role');
+            $this->_title($this->__('Edit Role'));
+        } else {
+            $breadCrumb = $this->__('Add New Role');
+            $breadCrumbTitle = $this->__('Add New Role');
+            $this->_title($this->__('New Role'));
+        }
+        $this->_addBreadcrumb($breadCrumb, $breadCrumbTitle);
+
+        $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+
+        $this->_addLeft(
+            $this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_Editroles')
+        );
+        $resources = Mage::getModel('Mage_Api_Model_Roles')->getResourcesList();
+        $this->_addContent(
+            $this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_Buttons')
+                ->setRoleId($roleId)
+                ->setRoleInfo(Mage::getModel('Mage_Api_Model_Roles')->load($roleId))
+                ->setTemplate('api/roleinfo.phtml')
+        );
+        $this->_addJs(
+            $this->getLayout()
+                ->createBlock('Mage_Adminhtml_Block_Template')
+                ->setTemplate('api/role_users_grid_js.phtml')
+        );
+        $this->renderLayout();
+    }
+
+    public function deleteAction()
+    {
+        $rid = $this->getRequest()->getParam('rid', false);
+
+        try {
+            Mage::getModel('Mage_Api_Model_Roles')->load($rid)->delete();
+            Mage::getSingleton('Mage_Adminhtml_Model_Session')->addSuccess($this->__('The role has been deleted.'));
+        } catch (Exception $e) {
+            Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($this->__('An error occurred while deleting this role.'));
+        }
+
+        $this->_redirect("*/*/");
+    }
+
+    public function saveRoleAction()
+    {
+
+        $rid        = $this->getRequest()->getParam('role_id', false);
+        $role = Mage::getModel('Mage_Api_Model_Roles')->load($rid);
+        if (!$role->getId() && $rid) {
+            Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($this->__('This Role no longer exists'));
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        $resource   = explode(',', $this->getRequest()->getParam('resource', false));
+        $roleUsers  = $this->getRequest()->getParam('in_role_user', null);
+        parse_str($roleUsers, $roleUsers);
+        $roleUsers = array_keys($roleUsers);
+
+        $oldRoleUsers = $this->getRequest()->getParam('in_role_user_old');
+        parse_str($oldRoleUsers, $oldRoleUsers);
+        $oldRoleUsers = array_keys($oldRoleUsers);
+
+        $isAll = $this->getRequest()->getParam('all');
+        if ($isAll) {
+            $resource = array("all");
+        }
+
+        try {
+            $role = $role
+                    ->setName($this->getRequest()->getParam('rolename', false))
+                    ->setPid($this->getRequest()->getParam('parent_id', false))
+                    ->setRoleType('G')
+                    ->save();
+
+            Mage::getModel('Mage_Api_Model_Rules')
+                ->setRoleId($role->getId())
+                ->setResources($resource)
+                ->saveRel();
+
+            foreach($oldRoleUsers as $oUid) {
+                $this->_deleteUserFromRole($oUid, $role->getId());
+            }
+
+            foreach ($roleUsers as $nRuid) {
+                $this->_addUserToRole($nRuid, $role->getId());
+            }
+
+            $rid = $role->getId();
+            Mage::getSingleton('Mage_Adminhtml_Model_Session')->addSuccess($this->__('The role has been saved.'));
+        } catch (Exception $e) {
+            Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($this->__('An error occurred while saving this role.'));
+        }
+
+        //$this->getResponse()->setRedirect($this->getUrl("*/*/editrole/rid/$rid"));
+        $this->_redirect('*/*/editrole', array('rid' => $rid));
+        return;
+    }
+
+    public function editrolegridAction()
+    {
+        $this->getResponse()->setBody(
+            $this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_Role_Grid_User')->toHtml()
+        );
+    }
+
+    protected function _deleteUserFromRole($userId, $roleId)
+    {
+        try {
+            Mage::getModel('Mage_Api_Model_User')
+                ->setRoleId($roleId)
+                ->setUserId($userId)
+                ->deleteFromRole();
+        } catch (Exception $e) {
+            throw $e;
+            return false;
+        }
+        return true;
+    }
+
+    protected function _addUserToRole($userId, $roleId)
+    {
+        $user = Mage::getModel('Mage_Api_Model_User')->load($userId);
+        $user->setRoleId($roleId)->setUserId($userId);
+
+        if( $user->roleUserExists() === true ) {
+            return false;
+        } else {
+            $user->add();
+            return true;
+        }
+    }
+
+    protected function _isAllowed()
+    {
+        return Mage::getSingleton('Mage_Core_Model_Authorization')->isAllowed('Mage_Api::roles');
+    }
+}
diff --git a/app/code/core/Mage/Adminhtml/controllers/Api/UserController.php b/app/code/core/Mage/Adminhtml/controllers/Api/UserController.php
new file mode 100644
index 00000000000..8c06e6269a9
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/controllers/Api/UserController.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.
+ *
+ * @category    Mage
+ * @package     Mage_Adminhtml
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Adminhtml_Api_UserController extends Mage_Adminhtml_Controller_Action
+{
+
+    protected function _initAction()
+    {
+        $this->loadLayout()
+            ->_setActiveMenu('Mage_Api::system_legacy_api_users')
+            ->_addBreadcrumb($this->__('Web Services'), $this->__('Web Services'))
+            ->_addBreadcrumb($this->__('Permissions'), $this->__('Permissions'))
+            ->_addBreadcrumb($this->__('Users'), $this->__('Users'))
+        ;
+        return $this;
+    }
+
+    public function indexAction()
+    {
+        $this->_title($this->__('System'))
+             ->_title($this->__('Web Services'))
+             ->_title($this->__('Users'));
+
+        $this->_initAction()
+            ->_addContent($this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_User'))
+            ->renderLayout();
+    }
+
+    public function newAction()
+    {
+        $this->_forward('edit');
+    }
+
+    public function editAction()
+    {
+        $this->_title($this->__('System'))
+             ->_title($this->__('Web Services'))
+             ->_title($this->__('Users'));
+
+        $id = $this->getRequest()->getParam('user_id');
+        $model = Mage::getModel('Mage_Api_Model_User');
+
+        if ($id) {
+            $model->load($id);
+            if (! $model->getId()) {
+                Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($this->__('This user no longer exists.'));
+                $this->_redirect('*/*/');
+                return;
+            }
+        }
+
+        $this->_title($model->getId() ? $model->getName() : $this->__('New User'));
+
+        // Restore previously entered form data from session
+        $data = Mage::getSingleton('Mage_Adminhtml_Model_Session')->getUserData(true);
+        if (!empty($data)) {
+            $model->setData($data);
+        }
+
+        Mage::register('api_user', $model);
+
+        $this->_initAction()
+            ->_addBreadcrumb($id ? $this->__('Edit User') : $this->__('New User'), $id ? $this->__('Edit User') : $this->__('New User'))
+            ->_addContent($this->getLayout()
+                ->createBlock('Mage_Adminhtml_Block_Api_User_Edit')
+                ->setData('action', $this->getUrl('*/api_user/save')))
+            ->_addLeft($this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_User_Edit_Tabs'));
+
+        $this->_addJs($this->getLayout()
+            ->createBlock('Mage_Adminhtml_Block_Template')
+            ->setTemplate('api/user_roles_grid_js.phtml')
+        );
+        $this->renderLayout();
+    }
+
+    public function saveAction()
+    {
+        if ($data = $this->getRequest()->getPost()) {
+            $id = $this->getRequest()->getPost('user_id', false);
+            $model = Mage::getModel('Mage_Api_Model_User')->load($id);
+            if (!$model->getId() && $id) {
+                Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($this->__('This user no longer exists.'));
+                $this->_redirect('*/*/');
+                return;
+            }
+            $model->setData($data);
+            try {
+                $model->save();
+                if ( $uRoles = $this->getRequest()->getParam('roles', false) ) {
+                    /*parse_str($uRoles, $uRoles);
+                    $uRoles = array_keys($uRoles);*/
+                    if ( 1 == sizeof($uRoles) ) {
+                        $model->setRoleIds($uRoles)
+                            ->setRoleUserId($model->getUserId())
+                            ->saveRelations();
+                    } else if ( sizeof($uRoles) > 1 ) {
+                        //@FIXME: stupid fix of previous multi-roles logic.
+                        //@TODO:  make proper DB upgrade in the future revisions.
+                        $rs = array();
+                        $rs[0] = $uRoles[0];
+                        $model->setRoleIds( $rs )->setRoleUserId( $model->getUserId() )->saveRelations();
+                    }
+                }
+                Mage::getSingleton('Mage_Adminhtml_Model_Session')->addSuccess($this->__('The user has been saved.'));
+                Mage::getSingleton('Mage_Adminhtml_Model_Session')->setUserData(false);
+                $this->_redirect('*/*/edit', array('user_id' => $model->getUserId()));
+                return;
+            } catch (Exception $e) {
+                Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($e->getMessage());
+                Mage::getSingleton('Mage_Adminhtml_Model_Session')->setUserData($data);
+                $this->_redirect('*/*/edit', array('user_id' => $model->getUserId()));
+                return;
+            }
+        }
+        $this->_redirect('*/*/');
+    }
+
+    public function deleteAction()
+    {
+        if ($id = $this->getRequest()->getParam('user_id')) {
+
+            try {
+                $model = Mage::getModel('Mage_Api_Model_User')->load($id);
+                $model->delete();
+                Mage::getSingleton('Mage_Adminhtml_Model_Session')->addSuccess($this->__('The user has been deleted.'));
+                $this->_redirect('*/*/');
+                return;
+            }
+            catch (Exception $e) {
+                Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($e->getMessage());
+                $this->_redirect('*/*/edit', array('user_id' => $this->getRequest()->getParam('user_id')));
+                return;
+            }
+        }
+        Mage::getSingleton('Mage_Adminhtml_Model_Session')->addError($this->__('Unable to find a user to delete.'));
+        $this->_redirect('*/*/');
+    }
+
+    public function rolesGridAction()
+    {
+        $id = $this->getRequest()->getParam('user_id');
+        $model = Mage::getModel('Mage_Api_Model_User');
+
+        if ($id) {
+            $model->load($id);
+        }
+
+        Mage::register('api_user', $model);
+        $this->getResponse()->setBody(
+            $this->getLayout()->createBlock('Mage_Adminhtml_Block_Api_User_Edit_Tab_Roles')->toHtml()
+        );
+    }
+
+    public function roleGridAction()
+    {
+        $this->getResponse()
+            ->setBody($this->getLayout()
+            ->createBlock('Mage_Adminhtml_Block_Api_User_Grid')
+            ->toHtml()
+        );
+    }
+
+    protected function _isAllowed()
+    {
+        return Mage::getSingleton('Mage_Core_Model_Authorization')->isAllowed('Mage_Api::users');
+    }
+
+}
diff --git a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
index 52548bc6ee6..fa08d7763b7 100644
--- a/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
+++ b/app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
@@ -444,27 +444,21 @@ class Mage_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller
     }
 
     /**
-     * Get associated grouped products grid and serializer block
+     * Get associated grouped products grid
      */
     public function superGroupAction()
     {
-        $this->_initProduct();
-        $this->loadLayout();
-        $this->getLayout()->getBlock('catalog.product.edit.tab.super.group')
-            ->setProductsGrouped($this->getRequest()->getPost('products_grouped', null));
+        $this->loadLayout(false);
         $this->renderLayout();
     }
 
     /**
-     * Get associated grouped products grid only
-     *
+     * Get associated grouped products grid popup
      */
-    public function superGroupGridOnlyAction()
+    public function superGroupPopupAction()
     {
         $this->_initProduct();
-        $this->loadLayout();
-        $this->getLayout()->getBlock('catalog.product.edit.tab.super.group')
-            ->setProductsGrouped($this->getRequest()->getPost('products_grouped', null));
+        $this->loadLayout(false);
         $this->renderLayout();
     }
 
@@ -693,7 +687,7 @@ class Mage_Adminhtml_Catalog_ProductController extends Mage_Adminhtml_Controller
         }
         if (isset($links['grouped']) && !$product->getGroupedReadonly()) {
             $product->setGroupedLinkData(
-                Mage::helper('Mage_Adminhtml_Helper_Js')->decodeGridSerializedInput($links['grouped'])
+                Mage::helper('Mage_Core_Helper_Data')->jsonDecode($links['grouped'])
             );
         }
 
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/api/role_users_grid_js.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/api/role_users_grid_js.phtml
new file mode 100644
index 00000000000..11fb8f6d2b0
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/api/role_users_grid_js.phtml
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     default_default
+ * @copyright   Copyright (c) 2013 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">
+<!--
+<?php $myBlock = $this->getLayout()->getBlock('roleUsersGrid'); ?>
+<?php if( is_object($myBlock) && $myBlock->getJsObjectName() ): ?>
+    var checkBoxes = $H({});
+    var warning = false;
+    var inRoleUsers = $H(<?php echo $myBlock->_getUsers(true) ?>);
+    if (inRoleUsers.size() > 0) warning = true;
+    $('in_role_user').value = inRoleUsers.toQueryString();
+
+    function registerUserRole(grid, element, checked){
+        if(checked){
+            inRoleUsers.set(element.value, 0);
+        } else {
+            inRoleUsers.unset(element.value);
+        }
+        $('in_role_user').value = inRoleUsers.toQueryString();
+        grid.reloadParams = {'in_role_user[]':inRoleUsers.keys()};
+    }
+
+    function roleUsersRowClick(grid, event){
+        var trElement = Event.findElement(event, 'tr');
+        var isInput   = Event.element(event).tagName == 'INPUT';
+        if(trElement){
+            var checkbox = Element.getElementsBySelector(trElement, 'input');
+            if(checkbox[0]){
+                var checked = isInput ? checkbox[0].checked : !checkbox[0].checked;
+                if (warning && checkBoxes.size() > 0) {
+                    if ( !confirm("<?php echo $this->__('Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?') ?>") ) {
+                        checkbox[0].checked = false;
+                        checkBoxes.each(function(elem) {
+                            if (elem.value.status == 1) {
+                                elem.value.object.checked = true;
+                            }
+                        });
+                        return false;
+                    }
+                    warning = false;
+                }
+                <?php echo $myBlock->getJsObjectName() ?>.setCheckboxChecked(checkbox[0], checked);
+            }
+        }
+    }
+
+    function roleUsersRowInit(grid, row){
+        var checkbox = $(row).getElementsByClassName('checkbox')[0];
+        if (checkbox) {
+            checkBoxes.set(checkbox.value, {'status' : ((checkbox.checked) ? 1 : 0), 'object' : checkbox});
+        }
+    }
+
+    function myhandler(obj)
+    {
+        if (checkBoxes.size() > 0) {
+            if ( !confirm("<?php echo $this->__('Warning!\r\nThis action will remove those users from already assigned roles\r\nAre you sure?') ?>") ) {
+                obj.checked = false;
+                checkBoxes.each(function(elem) {
+                    if (elem.value.status == 1) {
+                        elem.value.object.checked = true;
+                    }
+                });
+                return false;
+            }
+            warning = false;
+        }
+        checkBoxes.each(function(elem) {
+            <?php echo $myBlock->getJsObjectName() ?>.setCheckboxChecked(elem.value.object, obj.checked);
+        });
+    }
+
+<?php echo $myBlock->getJsObjectName() ?>.rowClickCallback = roleUsersRowClick;
+<?php echo $myBlock->getJsObjectName() ?>.initRowCallback = roleUsersRowInit;
+<?php echo $myBlock->getJsObjectName() ?>.checkboxCheckCallback = registerUserRole;
+<?php echo $myBlock->getJsObjectName() ?>.checkCheckboxes = myhandler;
+<?php echo $myBlock->getJsObjectName() ?>.rows.each(function(row){roleUsersRowInit(<?php echo $myBlock->getJsObjectName() ?>, row)});
+    $('in_role_user_old').value = $('in_role_user').value;
+<?php endif; ?>
+//-->
+</script>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/api/roleinfo.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/api/roleinfo.phtml
new file mode 100644
index 00000000000..1d64e04c554
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/api/roleinfo.phtml
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     default_default
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/** @var $this Mage_Adminhtml_Block_Api_Tab_Roleinfo */
+
+?>
+<div class="content-header">
+    <table cellspacing="0">
+        <tr>
+            <td style="width:50%;"><h3 class="icon-head head-permissions-role"><?php echo ($this->getRoleId() > 0 ) ? ($this->__('Edit Role') . " '{$this->escapeHtml($this->getRoleInfo()->getRoleName())}'") : $this->__('Add New Role') ?></h3></td>
+            <td class="form-buttons">
+            <?php echo $this->getBackButtonHtml() ?>
+            <?php echo $this->getResetButtonHtml() ?>
+            <?php echo $this->getDeleteButtonHtml() ?>
+            <?php echo $this->getSaveButtonHtml() ?>
+            </td>
+        </tr>
+    </table>
+</div>
+<form action="<?php echo $this->getUrl('*/*/saverole') ?>" method="post" id="role-edit-form">
+    <?php echo $this->getBlockHtml('formkey')?>
+</form>
+<script type="text/javascript">
+    jQuery('#role-edit-form').form().validation();
+</script>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/_files/frontend/default/demo/theme.xml b/app/code/core/Mage/Adminhtml/view/adminhtml/api/roles.phtml
similarity index 61%
rename from dev/tests/integration/testsuite/Mage/Core/Block/_files/frontend/default/demo/theme.xml
rename to app/code/core/Mage/Adminhtml/view/adminhtml/api/roles.phtml
index 454f1534ae8..422ad419ad8 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/_files/frontend/default/demo/theme.xml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/api/roles.phtml
@@ -1,4 +1,4 @@
-<!--
+<?php
 /**
  * Magento
  *
@@ -18,21 +18,20 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Magento
- * @package     Design
- * @subpackage  integration_tests
+ * @category    design
+ * @package     default_default
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
--->
-<design>
-    <package code="default">
-        <title>Default</title>
-        <theme version="2.0.0.0" code="demo">
-            <title>Default</title>
-            <requirements>
-                <magento_version from="2.0.0.0-dev1" to="*"/>
-            </requirements>
-        </theme>
-    </package>
-</design>
+?>
+<div class="content-header">
+    <table cellspacing="0">
+        <tr>
+            <td style="width:50%;"><h3 class="icon-head head-permissions-role"><?php echo $this->__('Roles') ?></h3></td>
+            <td class="form-buttons">
+            <button class="scalable add" onclick="window.location='<?php echo $this->getAddNewUrl() ?>'"><span><span><span><?php echo $this->__('Add New Role') ?></span></span></span></button>
+            </td>
+        </tr>
+    </table>
+</div>
+<?php echo $this->getGridHtml() ?>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/api/rolesedit.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/api/rolesedit.phtml
new file mode 100644
index 00000000000..03cc092e539
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/api/rolesedit.phtml
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     default_default
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<div class="entry-edit">
+    <div class="entry-edit-head">
+        <h4 class="icon-head head-edit-form fieldset-legend"><?php echo $this->__('Roles Resources') ?></h4>
+    </div>
+    <input type="hidden" name="resource" id="role_resources" value="">
+    <fieldset id="role_resources">
+
+        <span class="field-row">
+            <label for="all"><?php echo $this->__('Resource Access') ?></label>
+            <select id="all" name="all" onchange="$('resources_container').toggle()" class="select">
+                <option value="0" <?php echo ($this->getEverythingAllowed()?'':'selected="selected"'); ?>><?php echo $this->__('Custom') ?></option>
+                <option value="1" <?php echo ($this->getEverythingAllowed()?'selected="selected"':''); ?>><?php echo $this->__('All') ?></option>
+            </select>
+        </span>
+
+        <span class="field-row" id="resources_container">
+            <label><?php echo $this->__('Resources') ?></label>
+            <div class="f-left">
+                <div class="tree x-tree" id="resource-tree"></div>
+            </div>
+        </span>
+
+    </fieldset>
+</div>
+<!-- Draw Resources Tree -->
+<script type="text/javascript">
+<?php if($this->getEverythingAllowed()): ?>
+    $('resources_container').hide();
+<?php endif; ?>
+Ext.EventManager.onDocumentReady(function() {
+    var tree = new Ext.tree.TreePanel('resource-tree', {
+        animate:false,
+        loader: false,
+        enableDD:false,
+        containerScroll: true,
+        rootUIProvider: Ext.tree.CheckboxNodeUI,
+        selModel: new Ext.tree.CheckNodeMultiSelectionModel(),
+        rootVisible: false
+    });
+
+    tree.on('check', checkHandler, tree);
+
+    // set the root node
+    var root = new Ext.tree.TreeNode({
+        text: 'root',
+        draggable:false,
+        checked:'false',
+        id:'__root__',
+        uiProvider: Ext.tree.CheckboxNodeUI
+    });
+
+    tree.setRootNode(root);
+    bildResourcesTree(root, <?php echo $this->getResTreeJson() ?>);
+    tree.addListener('click', resourceClick.createDelegate(this));
+
+    // render the tree
+    tree.render();
+    // root.expand();
+    tree.expandAll();
+
+    $('role_resources').value = tree.getChecked().join(',');
+});
+
+function resourceClick(node, e){
+    node.getUI().check(!node.getUI().checked());
+    varienElementMethods.setHasChanges(Event.element(e), e);
+};
+
+function bildResourcesTree(parent, config){
+    if (!config) return null;
+
+    if (parent && config && config.length){
+        for (var i = 0; i < config.length; i++){
+            config[i].uiProvider = Ext.tree.CheckboxNodeUI;
+            var node = new Ext.tree.TreeNode(config[i]);
+            parent.appendChild(node);
+            if(config[i].children){
+                bildResourcesTree(node, config[i].children);
+            }
+        }
+    }
+}
+
+function checkHandler(node)
+{
+    if ( node.attributes.checked && node.parentNode ) {
+        var n = node.parentNode;
+        this.removeListener('check', checkHandler);
+        do {
+            if (!n || n.attributes.id == 'admin' || n.attributes.id == '__root__') {
+                break;
+            } else {
+                n.ui.check(true);
+            }
+        } while (n = n.parentNode );
+        this.on('check', checkHandler);
+    }
+    if ( !node.isLeaf() && node.hasChildNodes() ) {
+        this.removeListener('check', checkHandler);
+        processChildren(node, node.attributes.checked);
+        this.on('check', checkHandler);
+    }
+    $('role_resources').value = this.getChecked().join(',');
+}
+
+function processChildren(node, state)
+{
+    if ( !node.hasChildNodes() ) return false;
+    for(var i = 0; i < node.childNodes.length; i++ ) {
+        node.childNodes[i].ui.check(state);
+        if ( node.childNodes[i].hasChildNodes() ) {
+            processChildren(node.childNodes[i], state);
+        }
+    }
+    return true;
+}
+</script>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/_files/frontend/default/demo/Mage_Core/dummy.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/api/rolesusers.phtml
similarity index 83%
rename from dev/tests/integration/testsuite/Mage/Core/Block/_files/frontend/default/demo/Mage_Core/dummy.phtml
rename to app/code/core/Mage/Adminhtml/view/adminhtml/api/rolesusers.phtml
index d66d2b3fc0e..38fd74195f7 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/_files/frontend/default/demo/Mage_Core/dummy.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/api/rolesusers.phtml
@@ -18,11 +18,11 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Magento
- * @package     Mage_Core
- * @subpackage  integration_tests
+ * @category    design
+ * @package     default_default
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 ?>
-<?php echo '1234567890' ?>
+<h4 class="icon-head head-edit-form fieldset-legend"><?php echo $this->__('Role Users') ?></h4>
+<?php echo $this->_getGridHtml() ?>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/api/user_roles_grid_js.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/api/user_roles_grid_js.phtml
new file mode 100644
index 00000000000..a632e48c7bf
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/api/user_roles_grid_js.phtml
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     default_default
+ * @copyright   Copyright (c) 2013 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">
+<!--
+<?php $myBlock = $this->getLayout()->getBlock('user.roles.grid'); ?>
+<?php if( is_object($myBlock) && $myBlock->getJsObjectName()): ?>
+    var radioBoxes = $H({});
+    var warning = false;
+    var userRoles = $H(<?php echo $myBlock->_getSelectedRoles(true) ?>);
+    if (userRoles.size() > 0) warning = true;
+    $('user_user_roles').value = userRoles.toQueryString();
+
+    function registerUserRole(grid, element, checked){
+        if(checked){
+            userRoles.each(function(o){userRoles.remove(o[0]);});
+            userRoles[element.value] = 0;
+        } else {
+            userRoles.remove(element.value);
+        }
+        $('user_user_roles').value = userRoles.toQueryString();
+        grid.reloadParams = {'user_roles[]':userRoles.keys()};
+    }
+
+    function roleRowClick(grid, event){
+        var trElement = Event.findElement(event, 'tr');
+        var isInput   = Event.element(event).tagName == 'INPUT';
+        if(trElement){
+            var checkbox = Element.getElementsBySelector(trElement, 'input');
+            if(checkbox[0] && !checkbox[0].checked){
+                var checked = isInput ? checkbox[0].checked : !checkbox[0].checked;
+                if (checked && warning && radioBoxes.size() > 0) {
+                    if ( !confirm("<?php echo $this->__('Warning!\r\nThis action will remove this user from already assigned role\r\nAre you sure?') ?>") ) {
+                        checkbox[0].checked = false;
+                        for(i in radioBoxes) {
+                            if( radioBoxes[i].status == 1) {
+                                radioBoxes[i].object.checked = true;
+                            }
+                        }
+                        return false;
+                    }
+                    warning = false;
+                }
+                <?php echo $myBlock->getJsObjectName() ?>.setCheckboxChecked(checkbox[0], checked);
+            }
+        }
+    }
+
+    function rolesRowInit(grid, row){
+        var checkbox = $(row).getElementsByClassName('radio')[0];
+        if (checkbox) {
+            radioBoxes[checkbox.value] = {'status' : ((checkbox.checked) ? 1 : 0), 'object' : checkbox};
+        }
+    }
+
+<?php echo $myBlock->getJsObjectName() ?>.rowClickCallback = roleRowClick;
+<?php echo $myBlock->getJsObjectName() ?>.initRowCallback = rolesRowInit;
+<?php echo $myBlock->getJsObjectName() ?>.checkboxCheckCallback = registerUserRole;
+<?php echo $myBlock->getJsObjectName() ?>.rows.each(function(row){rolesRowInit(<?php echo $myBlock->getJsObjectName() ?>, row)});
+<?php endif; ?>
+//-->
+</script>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/api/userinfo.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/api/userinfo.phtml
new file mode 100644
index 00000000000..d1cafe10be5
--- /dev/null
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/api/userinfo.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.
+ *
+ * @category    design
+ * @package     default_default
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<div class="content-header">
+    <table cellspacing="0">
+        <tr>
+            <td style="width:50%;">
+                <h3>
+                  <?php if($this->getUser()->getUserId()): ?>
+                  <?php $_userName = $this->getUser()->getFirstname() . ' ' . $this->getUser()->getLastname() ?>
+                  <?php echo $this->__("Edit User '%s'", $_userName) ?>
+                  <?php else: ?>
+                  <?php echo $this->__('Add New User') ?>
+                  <?php endif; ?>
+                </h3>
+            </td>
+            <td class="form-buttons">
+            <?php echo $this->getBackButtonHtml() ?>
+            <?php echo $this->getResetButtonHtml() ?>
+            <?php echo $this->getDeleteButtonHtml() ?>
+            <?php echo $this->getSaveButtonHtml() ?>
+   </table>
+</div>
+<form action="<?php echo $this->getUrl('*/*/saveuser') ?>" method="post" id="user-edit-form">
+    <?php echo $this->getBlockHtml('formkey')?>
+</form>
+<script type="text/javascript">
+    jQuery('#user-edit-form').form().validation();
+</script>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/_files/adminhtml/default/basic/Mage_Core/dummy.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/api/usernroles.phtml
similarity index 72%
rename from dev/tests/integration/testsuite/Mage/Core/Block/_files/adminhtml/default/basic/Mage_Core/dummy.phtml
rename to app/code/core/Mage/Adminhtml/view/adminhtml/api/usernroles.phtml
index d66d2b3fc0e..ede0536cc52 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/_files/adminhtml/default/basic/Mage_Core/dummy.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/api/usernroles.phtml
@@ -18,11 +18,14 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Magento
- * @package     Mage_Core
- * @subpackage  integration_tests
+ * @category    design
+ * @package     default_default
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 ?>
-<?php echo '1234567890' ?>
+<div id="roles">
+    <li class="add"><a href="<?php echo $this->getUrl('*/*/edituser') ?>"><?php echo $this->__('Add New User') ?></a></li>
+    <li class="add"><a href="<?php echo $this->getUrl('*/*/editroles') ?>"><?php echo $this->__('Add New Role') ?></a></li>
+</div>
+<div class="clear"></div>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml
index ea6d1a69908..341c97801ef 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog.xml
@@ -52,6 +52,12 @@
             <action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/jquery.fileupload-fp.js</file></action>
             <action method="addCss"><file>Mage_Adminhtml::catalog/category-selector.css</file></action>
             <action method="addJs"><file>Mage_Adminhtml::catalog/category-selector.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::json2.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::mage/backend/suggest.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::mage/backend/multisuggest.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::jquery/jstree/jquery.hotkeys.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::jquery/jstree/jquery.jstree.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::mage/backend/tree-suggest.js</file></action>
             <action method="addJs"><file>Mage_Adminhtml::catalog/type-switcher.js</file></action>
             <action method="addJs"><file>Mage_Adminhtml::catalog/product-variation.js</file></action>
             <action method="addJs"><file>Mage_Adminhtml::catalog/base-image-uploader.js</file></action>
@@ -100,6 +106,12 @@
             <action method="addJs"><file>Mage_Adminhtml::jquery/fileUploader/jquery.fileupload-fp.js</file></action>
             <action method="addCss"><file>Mage_Adminhtml::catalog/category-selector.css</file></action>
             <action method="addJs"><file>Mage_Adminhtml::catalog/category-selector.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::json2.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::mage/backend/suggest.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::mage/backend/multisuggest.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::jquery/jstree/jquery.hotkeys.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::jquery/jstree/jquery.jstree.js</file></action>
+            <action method="addJs"><file>Mage_Adminhtml::mage/backend/tree-suggest.js</file></action>
             <action method="addJs"><file>Mage_Adminhtml::catalog/type-switcher.js</file></action>
             <action method="addJs"><file>Mage_Adminhtml::catalog/product-variation.js</file></action>
             <action method="addJs"><file>Mage_Adminhtml::catalog/base-image-uploader.js</file></action>
@@ -377,36 +389,186 @@ Layout handle for virtual products
 Layout handle for grouped products
 -->
     <adminhtml_catalog_product_grouped>
-        <reference name="product_tabs">
-            <action method="addTab"><name>super</name><block>Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Group</block></action>
+        <update handle="adminhtml_catalog_product_grouped_grid"/>
+        <update handle="adminhtml_catalog_product_grouped_grid_popup"/>
+        <reference name="product-type-tabs">
+            <block type="Mage_Catalog_Block_Product_Grouped_AssociatedProducts" name="catalog.product.edit.grouped.container" template="Mage_Catalog::product/grouped/container.phtml">
+                <block type="Mage_Core_Block_Template" name="catalog.product.edit.tab.super.container" template="Mage_Catalog::product/grouped/grouped.phtml">
+                    <block type="Mage_Core_Block_Template" name="catalog.product.edit.tab.super.grid.container" as="catalog.product.group.grid.container"/>
+                    <block type="Mage_Core_Block_Template" name="catalog.product.edit.tab.super.grid.popup.container" as="catalog.product.group.grid.popup.container"/>
+                    </block>
+            </block>
         </reference>
     </adminhtml_catalog_product_grouped>
 
-    <adminhtml_catalog_product_supergroup>
-        <container name="root" label="Root" output="1">
-            <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Group" name="catalog.product.edit.tab.super.group" />
-            <block type="Mage_Adminhtml_Block_Widget_Grid_Serializer" name="grouped_grid_serializer">
-                <reference name="grouped_grid_serializer">
-                    <action method="initSerializerBlock">
-                        <grid_block_name>catalog.product.edit.tab.super.group</grid_block_name>
-                        <data_callback>getSelectedGroupedProducts</data_callback>
-                        <hidden_input_name>links[grouped]</hidden_input_name>
-                        <reload_param_name>products_grouped</reload_param_name>
-                    </action>
-                    <action method="addColumnInputName">
+    <adminhtml_catalog_product_grouped_grid>
+        <reference name="catalog.product.edit.tab.super.grid.container">
+            <block type="Mage_Catalog_Block_Product_Grouped_AssociatedProducts_Grid" name="catalog.product.edit.tab.super.group" as="catalog.product.group.grid">
+                <arguments>
+                    <id>grouped_grid</id>
+                    <dataSource type="object">Mage_Catalog_Model_Resource_Product_Type_Grouped_AssociatedProductsCollection</dataSource>
+                    <use_ajax>1</use_ajax>
+                    <default_sort>id</default_sort>
+                    <default_dir>DESC</default_dir>
+                    <save_parameters_in_session>0</save_parameters_in_session>
+                    <pager_visibility>0</pager_visibility>
+                    <grid_url type="url">
+                        <path>*/*/superGroup</path>
+                        <params>
+                            <_current>1</_current>
+                        </params>
+                    </grid_url>
+                </arguments>
+                <block type="Mage_Backend_Block_Widget_Grid_ColumnSet" name="catalog.product.edit.tab.super.group.columnSet" as="grid.columnSet">
+                    <arguments>
+                        <id>grouped_grid</id>
+                        <filter_visibility>0</filter_visibility>
+                    </arguments>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="info">
+                        <arguments>
+                            <type>grip</type>
+                            <index>entity_id</index>
+                            <width>5px</width>
+                            <sortable>0</sortable>
+                            <inline_css>ui-icon ui-icon-grip-dotted-vertical</inline_css>
+                        </arguments>
+                    </block>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="name">
+                        <arguments>
+                            <header translate="true" module="Mage_Sales">Name</header>
+                            <type>text</type>
+                            <index>name</index>
+                            <editable>1</editable>
+                            <sortable>0</sortable>
+                        </arguments>
+                    </block>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="sku">
+                        <arguments>
+                            <header translate="true" module="Mage_Sales">SKU</header>
+                            <type>text</type>
+                            <index>sku</index>
+                            <width>80px</width>
+                            <sortable>0</sortable>
+                        </arguments>
+                    </block>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="price">
+                        <arguments>
+                            <header translate="true" module="Mage_Sales">Price</header>
+                            <type>currency</type>
+                            <index>price</index>
+                            <width>110px</width>
+                            <align>right</align>
+                            <sortable>0</sortable>
+                        </arguments>
+                    </block>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="qty">
+                        <arguments>
+                            <header translate="true" module="Mage_Sales">Default Qty</header>
+                            <type>number</type>
+                            <index>qty</index>
+                            <width>110px</width>
+                            <align>right</align>
+                            <editable>1</editable>
+                            <sortable>0</sortable>
+                        </arguments>
+                    </block>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="delete">
+                        <arguments>
+                            <header translate="true" module="Mage_Sales">Delete</header>
+                            <type>button</type>
+                            <button_type>button</button_type>
+                            <column_css_class>product-delete</column_css_class>
+                            <width>60px</width>
+                            <renderer>Mage_Backend_Block_Widget_Grid_Column_Renderer_Button</renderer>
+                            <align>right</align>
+                            <sortable>0</sortable>
+                        </arguments>
+                    </block>
+                </block>
+                <action method="setGridData">
+                    <hidden_input_name>links[grouped]</hidden_input_name>
+                    <fields_to_save>
                         <input_name>qty</input_name>
-                        <input_name>position</input_name>
-                    </action>
-                </reference>
+                        <input_name2>position</input_name2>
+                    </fields_to_save>
+                </action>
             </block>
-        </container>
+        </reference>
+    </adminhtml_catalog_product_grouped_grid>
+
+    <adminhtml_catalog_product_grouped_grid_popup>
+        <reference name="catalog.product.edit.tab.super.grid.popup.container">
+            <block type="Mage_Backend_Block_Widget_Grid" name="catalog.product.edit.tab.super.group.popup" as="catalog.product.group.grid.popup">
+                <arguments>
+                    <id>grouped_grid_popup</id>
+                    <dataSource type="object">Mage_Catalog_Model_Resource_Product_Type_Grouped_AssociatedProductsCollection</dataSource>
+                    <use_ajax>1</use_ajax>
+                    <default_sort>id</default_sort>
+                    <default_dir>ASC</default_dir>
+                    <save_parameters_in_session>1</save_parameters_in_session>
+                    <grid_url type="url">
+                        <path>*/*/superGroupPopup</path>
+                        <params>
+                            <_current>1</_current>
+                        </params>
+                    </grid_url>
+                </arguments>
+                <block type="Mage_Backend_Block_Widget_Grid_ColumnSet" name="catalog.product.edit.tab.super.group.popup.columnSet" as="grid.columnSet">
+                    <arguments>
+                        <id>grouped_grid_popup</id>
+                    </arguments>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="in_products">
+                        <arguments>
+                            <type>checkbox</type>
+                            <header_css_class>a-center</header_css_class>
+                            <column_css_class>selected-products</column_css_class>
+                            <width>60px</width>
+                            <align>center</align>
+                            <index>entity_id</index>
+                        </arguments>
+                    </block>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="name">
+                        <arguments>
+                            <header translate="true" module="Mage_Sales">Name</header>
+                            <column_css_class>associated-product-name</column_css_class>
+                            <type>text</type>
+                            <index>name</index>
+                            <editable>1</editable>
+                        </arguments>
+                    </block>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="sku">
+                        <arguments>
+                            <header translate="true" module="Mage_Sales">SKU</header>
+                            <column_css_class>associated-product-sku</column_css_class>
+                            <type>text</type>
+                            <index>sku</index>
+                            <width>80px</width>
+                        </arguments>
+                    </block>
+                    <block type="Mage_Backend_Block_Widget_Grid_Column" as="price">
+                        <arguments>
+                            <header translate="true" module="Mage_Sales">Price</header>
+                            <column_css_class>associated-product-price</column_css_class>
+                            <type>currency</type>
+                            <index>price</index>
+                            <width>110px</width>
+                            <align>right</align>
+                        </arguments>
+                    </block>
+                </block>
+            </block>
+        </reference>
+    </adminhtml_catalog_product_grouped_grid_popup>
+
+    <adminhtml_catalog_product_supergroup>
+        <update handle="adminhtml_catalog_product_grouped"/>
+        <container output="1" name="catalog.product.edit.tab.super.grid.container" label="grid"></container>
     </adminhtml_catalog_product_supergroup>
 
-    <adminhtml_catalog_product_supergroupgridonly>
-        <container name="root" label="Root" output="1">
-            <block type="Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Group" name="catalog.product.edit.tab.super.group" />
-        </container>
-    </adminhtml_catalog_product_supergroupgridonly>
+    <adminhtml_catalog_product_supergrouppopup>
+        <update handle="adminhtml_catalog_product_grouped"/>
+        <container output="1" name="catalog.product.edit.tab.super.grid.popup.container" label="grid"></container>
+    </adminhtml_catalog_product_supergrouppopup>
 
     <adminhtml_catalog_product_variationsmatrix>
         <container name="root" label="Root" output="1">
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product-variation.js b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product-variation.js
index 1b8f4f993b9..7a7050a6097 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product-variation.js
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product-variation.js
@@ -27,7 +27,7 @@
         _create: function () {
             this.element.sortable({
                 axis: 'y',
-                handle: '.entry-edit-head',
+                handle: '.ui-icon-grip-dotted-vertical',
                 update: function () {
                     $(this).find('[name$="[position]"]').each(function (index) {
                         $(this).val(index);
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product.js b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product.js
index e5df89f39bd..ee4e2f5743a 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product.js
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product.js
@@ -315,579 +315,6 @@ Product.Attributes.prototype = {
     }
 };
 
-Product.Configurable = Class.create();
-Product.Configurable.prototype = {
-    initialize : function(attributes, links, idPrefix, grid, readonly) {
-        this.templatesSyntax = new RegExp(
-                '(^|.|\\r|\\n)(\'{{\\s*(\\w+)\\s*}}\')', "");
-        this.attributes = attributes; // Attributes
-        this.idPrefix = idPrefix; // Container id prefix
-        this.links = $H(links); // Associated products
-        this.newProducts = []; // For product that's created through Create
-                                // Empty and Copy from Configurable
-        this.readonly = readonly;
-
-        /* Generation templates */
-        this.addAttributeTemplate = new Template(
-                $(idPrefix + 'attribute_template').innerHTML.replace(/__id__/g,
-                        "'{{html_id}}'").replace(/ template no-display/g, ''),
-                this.templatesSyntax);
-        this.addValueTemplate = new Template(
-                $(idPrefix + 'value_template').innerHTML.replace(/__id__/g,
-                        "'{{html_id}}'").replace(/ template no-display/g, ''),
-                this.templatesSyntax);
-        this.pricingValueTemplate = new Template(
-                $(idPrefix + 'simple_pricing').innerHTML, this.templatesSyntax);
-        this.pricingValueViewTemplate = new Template(
-                $(idPrefix + 'simple_pricing_view').innerHTML,
-                this.templatesSyntax);
-
-        this.container = $(idPrefix + 'attributes');
-
-        /* Listeners */
-        this.onLabelUpdate = this.updateLabel.bindAsEventListener(this); // Update
-                                                                            // attribute
-                                                                            // label
-        this.onValuePriceUpdate = this.updateValuePrice
-                .bindAsEventListener(this); // Update pricing value
-        this.onValueTypeUpdate = this.updateValueType.bindAsEventListener(this); // Update
-                                                                                    // pricing
-                                                                                    // type
-        this.onValueDefaultUpdate = this.updateValueUseDefault
-                .bindAsEventListener(this);
-
-        /* Grid initialization and attributes initialization */
-        this.createAttributes(); // Creation of default attributes
-
-        this.grid = grid;
-        this.grid.rowClickCallback = this.rowClick.bind(this);
-        this.grid.initRowCallback = this.rowInit.bind(this);
-        this.grid.checkboxCheckCallback = this.registerProduct.bind(this); // Associate/Unassociate
-                                                                            // simple
-                                                                            // product
-
-        this.grid.rows.each( function(row) {
-            this.rowInit(this.grid, row);
-        }.bind(this));
-        this.updateGrid();
-    },
-    createAttributes : function() {
-        this.attributes.each( function(attribute, index) {
-            // var li = Builder.node('li', {className:'attribute'});
-                var li = $(document.createElement('LI'));
-                li.className = 'attribute';
-
-                li.id = this.idPrefix + '_attribute_' + index;
-                attribute.html_id = li.id;
-                if (attribute && attribute.label && attribute.label.blank()) {
-                    attribute.label = '&nbsp;'
-                }
-                var label_readonly = '';
-                var use_default_checked = '';
-                if (attribute.use_default == '1') {
-                    use_default_checked = ' checked="checked"';
-                    label_readonly = ' readonly="readonly"';
-                }
-
-                var template = this.addAttributeTemplate.evaluate(attribute);
-                template = template.replace(
-                        new RegExp(' readonly="label"', 'ig'), label_readonly);
-                template = template.replace(new RegExp(
-                        ' checked="use_default"', 'ig'), use_default_checked);
-                li.update(template);
-                li.attributeObject = attribute;
-
-                this.container.appendChild(li);
-                li.attributeValues = li.down('.attribute-values');
-
-                if (attribute.values) {
-                    attribute.values.each( function(value) {
-                        this.createValueRow(li, value); // Add pricing values
-                        }.bind(this));
-                }
-
-                /* Observe label change */
-                Event.observe(li.down('.attribute-label'), 'change',
-                        this.onLabelUpdate);
-                Event.observe(li.down('.attribute-label'), 'keyup',
-                        this.onLabelUpdate);
-                Event.observe(li.down('.attribute-use-default-label'),
-                        'change', this.onLabelUpdate);
-            }.bind(this));
-        if (!this.readonly) {
-            // Creation of sortable for attributes sorting
-            Sortable.create(this.container, {
-                handle :'attribute-name-container',
-                onUpdate :this.updatePositions.bind(this)
-            });
-        }
-        this.updateSaveInput();
-    },
-
-    updateLabel : function(event) {
-        var li = Event.findElement(event, 'LI');
-        var labelEl = li.down('.attribute-label');
-        var defEl = li.down('.attribute-use-default-label');
-
-        li.attributeObject.label = labelEl.value;
-        if (defEl.checked) {
-            labelEl.readOnly = true;
-            li.attributeObject.use_default = 1;
-        } else {
-            labelEl.readOnly = false;
-            li.attributeObject.use_default = 0;
-        }
-
-        this.updateSaveInput();
-    },
-    updatePositions : function(param) {
-        this.container.childElements().each( function(row, index) {
-            row.attributeObject.position = index;
-        });
-        this.updateSaveInput();
-    },
-    addNewProduct : function(productId, attributes) {
-        if (this.checkAttributes(attributes)) {
-            this.links.set(productId, this.cloneAttributes(attributes));
-        } else {
-            this.newProducts.push(productId);
-        }
-
-        this.updateGrid();
-        this.updateValues();
-        this.grid.reload(null);
-    },
-    createEmptyProduct : function() {
-        this.createPopup(this.createEmptyUrl)
-    },
-    createNewProduct : function() {
-        this.createPopup(this.createNormalUrl);
-    },
-    createPopup : function(url) {
-        if (this.win && !this.win.closed) {
-            this.win.close();
-        }
-
-        this.win = window.open(url, '',
-                'width=1000,height=700,resizable=1,scrollbars=1');
-        this.win.focus();
-    },
-    registerProduct : function(grid, element, checked) {
-        if (checked) {
-            if (element.linkAttributes) {
-                this.links.set(element.value, element.linkAttributes);
-            }
-        } else {
-            this.links.unset(element.value);
-        }
-        this.updateGrid();
-        this.grid.rows.each( function(row) {
-            this.revalidateRow(this.grid, row);
-        }.bind(this));
-        this.updateValues();
-    },
-    updateProduct : function(productId, attributes) {
-        var isAssociated = false;
-
-        if (typeof this.links.get(productId) != 'undefined') {
-            isAssociated = true;
-            this.links.unset(productId);
-        }
-
-        if (isAssociated && this.checkAttributes(attributes)) {
-            this.links.set(productId, this.cloneAttributes(attributes));
-        } else if (isAssociated) {
-            this.newProducts.push(productId);
-        }
-
-        this.updateGrid();
-        this.updateValues();
-        this.grid.reload(null);
-    },
-    cloneAttributes : function(attributes) {
-        var newObj = [];
-        for ( var i = 0, length = attributes.length; i < length; i++) {
-            newObj[i] = Object.clone(attributes[i]);
-        }
-        return newObj;
-    },
-    rowClick : function(grid, event) {
-        var trElement = Event.findElement(event, 'tr');
-        var isInput = Event.element(event).tagName.toUpperCase() == 'INPUT';
-
-        if ($(Event.findElement(event, 'td')).down('a')) {
-            return;
-        }
-
-        if (trElement) {
-            var checkbox = $(trElement).down('input');
-            if (checkbox && !checkbox.disabled) {
-                var checked = isInput ? checkbox.checked : !checkbox.checked;
-                grid.setCheckboxChecked(checkbox, checked);
-            }
-        }
-    },
-    rowInit : function(grid, row) {
-        var checkbox = $(row).down('.checkbox');
-        var input = $(row).down('.value-json');
-        if (checkbox && input) {
-            checkbox.linkAttributes = input.value.evalJSON();
-            if (!checkbox.checked) {
-                if (!this.checkAttributes(checkbox.linkAttributes)) {
-                    $(row).addClassName('invalid');
-                    checkbox.disable();
-                } else {
-                    $(row).removeClassName('invalid');
-                    checkbox.enable();
-                }
-            }
-        }
-    },
-    revalidateRow : function(grid, row) {
-        var checkbox = $(row).down('.checkbox');
-        if (checkbox) {
-            if (!checkbox.checked) {
-                if (!this.checkAttributes(checkbox.linkAttributes)) {
-                    $(row).addClassName('invalid');
-                    checkbox.disable();
-                } else {
-                    $(row).removeClassName('invalid');
-                    checkbox.enable();
-                }
-            }
-        }
-    },
-    checkAttributes : function(attributes) {
-        var result = true;
-        this.links
-                .each( function(pair) {
-                    var fail = false;
-                    for ( var i = 0; i < pair.value.length && !fail; i++) {
-                        for ( var j = 0; j < attributes.length && !fail; j++) {
-                            if (pair.value[i].attribute_id == attributes[j].attribute_id
-                                    && pair.value[i].value_index != attributes[j].value_index) {
-                                fail = true;
-                            }
-                        }
-                    }
-                    if (!fail) {
-                        result = false;
-                    }
-                });
-        return result;
-    },
-    updateGrid : function() {
-        this.grid.reloadParams = {
-            'attributes[]': this.attributes.map(function(el) { return el.attribute_id; }),
-            'products[]' :this.links.keys().size() ? this.links.keys() : [ 0 ],
-            'new_products[]' :this.newProducts
-        };
-    },
-    updateValues : function() {
-        var uniqueAttributeValues = $H( {});
-        /* Collect unique attributes */
-        this.links.each( function(pair) {
-            for ( var i = 0, length = pair.value.length; i < length; i++) {
-                var attribute = pair.value[i];
-                if (uniqueAttributeValues.keys()
-                        .indexOf(attribute.attribute_id) == -1) {
-                    uniqueAttributeValues.set(attribute.attribute_id, $H( {}));
-                }
-                uniqueAttributeValues.get(attribute.attribute_id).set(
-                        attribute.value_index, attribute);
-            }
-        });
-        /* Updating attributes value container */
-        this.container
-                .childElements()
-                .each(
-                        function(row) {
-                            var attribute = row.attributeObject;
-                            for ( var i = 0, length = attribute.values.length; i < length; i++) {
-                                if (uniqueAttributeValues.keys().indexOf(
-                                        attribute.attribute_id) == -1
-                                        || uniqueAttributeValues
-                                                .get(attribute.attribute_id)
-                                                .keys()
-                                                .indexOf(
-                                                        attribute.values[i].value_index) == -1) {
-                                    row.attributeValues
-                                            .childElements()
-                                            .each(
-                                                    function(elem) {
-                                                        if (elem.valueObject.value_index == attribute.values[i].value_index) {
-                                                            elem.remove();
-                                                        }
-                                                    });
-                                    attribute.values[i] = undefined;
-
-                                } else {
-                                    uniqueAttributeValues.get(
-                                            attribute.attribute_id).unset(
-                                            attribute.values[i].value_index);
-                                }
-                            }
-                            attribute.values = attribute.values.compact();
-                            if (uniqueAttributeValues
-                                    .get(attribute.attribute_id)) {
-                                uniqueAttributeValues.get(
-                                        attribute.attribute_id).each(
-                                        function(pair) {
-                                            attribute.values.push(pair.value);
-                                            this
-                                                    .createValueRow(row,
-                                                            pair.value);
-                                        }.bind(this));
-                            }
-                        }.bind(this));
-        this.updateSaveInput();
-        this.updateSimpleForm();
-    },
-    createValueRow : function(container, value) {
-        var templateVariables = $H( {});
-        if (!this.valueAutoIndex) {
-            this.valueAutoIndex = 1;
-        }
-        templateVariables.set('html_id', container.id + '_'
-                + this.valueAutoIndex);
-        templateVariables.update(value);
-        var pricingValue = parseFloat(templateVariables.get('pricing_value'));
-        if (!isNaN(pricingValue)) {
-            templateVariables.set('pricing_value', pricingValue);
-        } else {
-            templateVariables.unset('pricing_value');
-        }
-        this.valueAutoIndex++;
-
-        // var li = $(Builder.node('li', {className:'attribute-value'}));
-        var li = $(document.createElement('LI'));
-        li.className = 'attribute-value';
-        li.id = templateVariables.get('html_id');
-        li.update(this.addValueTemplate.evaluate(templateVariables));
-        li.valueObject = value;
-        if (typeof li.valueObject.is_percent == 'undefined') {
-            li.valueObject.is_percent = 0;
-        }
-
-        if (typeof li.valueObject.pricing_value == 'undefined') {
-            li.valueObject.pricing_value = '';
-        }
-
-        container.attributeValues.appendChild(li);
-
-        var priceField = li.down('.attribute-price');
-        var priceTypeField = li.down('.attribute-price-type');
-
-        if (priceTypeField != undefined && priceTypeField.options != undefined) {
-            if (parseInt(value.is_percent)) {
-                priceTypeField.options[1].selected = !(priceTypeField.options[0].selected = false);
-            } else {
-                priceTypeField.options[1].selected = !(priceTypeField.options[0].selected = true);
-            }
-        }
-
-        Event.observe(priceField, 'keyup', this.onValuePriceUpdate);
-        Event.observe(priceField, 'change', this.onValuePriceUpdate);
-        Event.observe(priceTypeField, 'change', this.onValueTypeUpdate);
-        var useDefaultEl = li.down('.attribute-use-default-value');
-        if (useDefaultEl) {
-            if (li.valueObject.use_default_value) {
-                useDefaultEl.checked = true;
-                this.updateUseDefaultRow(useDefaultEl, li);
-            }
-            Event.observe(useDefaultEl, 'change', this.onValueDefaultUpdate);
-        }
-    },
-    updateValuePrice : function(event) {
-        var li = Event.findElement(event, 'LI');
-        li.valueObject.pricing_value = (Event.element(event).value.blank() ? null
-                : Event.element(event).value);
-        this.updateSimpleForm();
-        this.updateSaveInput();
-    },
-    updateValueType : function(event) {
-        var li = Event.findElement(event, 'LI');
-        li.valueObject.is_percent = (Event.element(event).value.blank() ? null
-                : Event.element(event).value);
-        this.updateSimpleForm();
-        this.updateSaveInput();
-    },
-    updateValueUseDefault : function(event) {
-        var li = Event.findElement(event, 'LI');
-        var useDefaultEl = Event.element(event);
-        li.valueObject.use_default_value = useDefaultEl.checked;
-        this.updateUseDefaultRow(useDefaultEl, li);
-    },
-    updateUseDefaultRow : function(useDefaultEl, li) {
-        var priceField = li.down('.attribute-price');
-        var priceTypeField = li.down('.attribute-price-type');
-        if (useDefaultEl.checked) {
-            priceField.disabled = true;
-            priceTypeField.disabled = true;
-        } else {
-            priceField.disabled = false;
-            priceTypeField.disabled = false;
-        }
-        this.updateSimpleForm();
-        this.updateSaveInput();
-    },
-    updateSaveInput : function() {
-        $(this.idPrefix + 'save_attributes').value = Object.toJSON(this.attributes);
-    },
-    initializeAdvicesForSimpleForm : function() {
-        if ($(this.idPrefix + 'simple_form').advicesInited) {
-            return;
-        }
-
-        $(this.idPrefix + 'simple_form').select('td.value').each( function(td) {
-            var adviceContainer = $(Builder.node('div'));
-            td.appendChild(adviceContainer);
-            td.select('input', 'select').each( function(element) {
-                element.advaiceContainer = adviceContainer;
-            });
-        });
-        $(this.idPrefix + 'simple_form').advicesInited = true;
-    },
-    checkCreationUniqueAttributes : function() {
-        var attributes = [];
-        this.attributes
-                .each( function(attribute) {
-                    attributes
-                            .push( {
-                                attribute_id :attribute.attribute_id,
-                                value_index :$('simple_product_' + attribute.attribute_code).value
-                            });
-                }.bind(this));
-
-        return this.checkAttributes(attributes);
-    },
-    getAttributeByCode : function(attributeCode) {
-        var attribute = null;
-        this.attributes.each( function(item) {
-            if (item.attribute_code == attributeCode) {
-                attribute = item;
-                throw $break;
-            }
-        });
-        return attribute;
-    },
-    getAttributeById : function(attributeId) {
-        var attribute = null;
-        this.attributes.each( function(item) {
-            if (item.attribute_id == attributeId) {
-                attribute = item;
-                throw $break;
-            }
-        });
-        return attribute;
-    },
-    getValueByIndex : function(attribute, valueIndex) {
-        var result = null;
-        attribute.values.each( function(value) {
-            if (value.value_index == valueIndex) {
-                result = value;
-                throw $break;
-            }
-        });
-        return result;
-    },
-    showPricing : function(select, attributeCode) {
-        var attribute = this.getAttributeByCode(attributeCode);
-        if (!attribute) {
-            return;
-        }
-
-        select = $(select);
-        if (select.value
-                && !$('simple_product_' + attributeCode + '_pricing_container')) {
-            Element
-                    .insert(
-                            select,
-                            {
-                                after :'<div class="left"></div> <div id="simple_product_' + attributeCode + '_pricing_container" class="left"></div>'
-                            });
-            var newContainer = select.next('div');
-            select.parentNode.removeChild(select);
-            newContainer.appendChild(select);
-            // Fix visualization bug
-            $(this.idPrefix + 'simple_form').down('.form-list').style.width = '100%';
-        }
-
-        var container = $('simple_product_' + attributeCode + '_pricing_container');
-
-        if (select.value) {
-            var value = this.getValueByIndex(attribute, select.value);
-            if (!value) {
-                if (!container.down('.attribute-price')) {
-                    if (value == null) {
-                        value = {};
-                    }
-                    container.update(this.pricingValueTemplate.evaluate(value));
-                    var priceValueField = container.down('.attribute-price');
-                    var priceTypeField = container
-                            .down('.attribute-price-type');
-
-                    priceValueField.attributeCode = attributeCode;
-                    priceValueField.priceField = priceValueField;
-                    priceValueField.typeField = priceTypeField;
-
-                    priceTypeField.attributeCode = attributeCode;
-                    priceTypeField.priceField = priceValueField;
-                    priceTypeField.typeField = priceTypeField;
-
-                    Event.observe(priceValueField, 'change',
-                            this.updateSimplePricing.bindAsEventListener(this));
-                    Event.observe(priceValueField, 'keyup',
-                            this.updateSimplePricing.bindAsEventListener(this));
-                    Event.observe(priceTypeField, 'change',
-                            this.updateSimplePricing.bindAsEventListener(this));
-
-                    $('simple_product_' + attributeCode + '_pricing_value').value = null;
-                    $('simple_product_' + attributeCode + '_pricing_type').value = null;
-                }
-            } else if (!isNaN(parseFloat(value.pricing_value))) {
-                container.update(this.pricingValueViewTemplate.evaluate( {
-                    'value' :(parseFloat(value.pricing_value) > 0 ? '+' : '')
-                            + parseFloat(value.pricing_value)
-                            + (parseInt(value.is_percent) > 0 ? '%' : '')
-                }));
-                $('simple_product_' + attributeCode + '_pricing_value').value = value.pricing_value;
-                $('simple_product_' + attributeCode + '_pricing_type').value = value.is_percent;
-            } else {
-                container.update('');
-                $('simple_product_' + attributeCode + '_pricing_value').value = null;
-                $('simple_product_' + attributeCode + '_pricing_type').value = null;
-            }
-        } else if (container) {
-            container.update('');
-            $('simple_product_' + attributeCode + '_pricing_value').value = null;
-            $('simple_product_' + attributeCode + '_pricing_type').value = null;
-        }
-    },
-    updateSimplePricing : function(evt) {
-        var element = Event.element(evt);
-        if (!element.priceField.value.blank()) {
-            $('simple_product_' + element.attributeCode + '_pricing_value').value = element.priceField.value;
-            $('simple_product_' + element.attributeCode + '_pricing_type').value = element.typeField.value;
-        } else {
-            $('simple_product_' + element.attributeCode + '_pricing_value').value = null;
-            $('simple_product_' + element.attributeCode + '_pricing_type').value = null;
-        }
-    },
-    updateSimpleForm : function() {
-        this.attributes.each( function(attribute) {
-            if ($('simple_product_' + attribute.attribute_code)) {
-                this.showPricing(
-                        $('simple_product_' + attribute.attribute_code),
-                        attribute.attribute_code);
-            }
-        }.bind(this));
-    },
-    showNoticeMessage : function() {
-        $('assign_product_warrning').show();
-    }
-}
-
 var onInitDisableFieldsList = [];
 
 function toogleFieldEditMode(toogleIdentifier, fieldContainer) {
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/composite/fieldset/grouped.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/composite/fieldset/grouped.phtml
index a48249c31dd..a9760647a36 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/composite/fieldset/grouped.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/composite/fieldset/grouped.phtml
@@ -44,7 +44,7 @@
             <col />
             <col width="1" />
             <thead>
-                <tr "class="headings">
+                <tr class="headings">
                     <th><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('ID') ?></th>
                     <th><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('SKU') ?></th>
                     <th><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Product Name') ?></th>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml
index 0f9f54be33f..d12e65c8294 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit.phtml
@@ -52,34 +52,6 @@
     <?php echo $this->getChildHtml('product-type-tabs') ?>
 </form>
 <script type="text/javascript">
-    var productTemplateSyntax = /(^|.|\r|\n)({{(\w+)}})/;
-    jQuery('#product-edit-form').mage('form')
-        .mage('validation', {validationUrl: '<?php echo $this->getValidationUrl() ?>'});
-    function setSettings(urlTemplate, setElement, typeElement) {
-        var template = new Template(urlTemplate, productTemplateSyntax);
-        setLocation(template.evaluate({attribute_set:$F(setElement),type:$F(typeElement)}));
-    }
-
-    function setSuperSettings(urlTemplate, attributesClass, validateField) {
-        var attributesFields = $$('.' + attributesClass);
-        var attributes = Form.serializeElements(attributesFields, true).attribute;
-        if (typeof attributes == 'string') {
-            attributes = [attributes];
-        }
-
-        if (!attributes) {
-            $(validateField).value = 'no-attributes';
-        } else {
-            $(validateField).value = 'has-attributes';
-        }
-
-        var template = new Template(urlTemplate, productTemplateSyntax);
-        var url = template.evaluate({
-            attributes: encode_base64(attributes.join(',')).replace(new RegExp('/', 'g'), '%2F').replace(new RegExp('=', 'g'), '%3D')
-        });
-        jQuery('#product-edit-form').attr('action', url + '&active_tab=configurable').submit();
-    }
-
     function checkMaxLength(Object, MaxLen)
     {
         if (Object.value.length > MaxLen-1) {
@@ -89,6 +61,10 @@
     }
 
 jQuery(function($) {
+    $('#product-edit-form')
+        .mage('form')
+        .mage('validation', {validationUrl: '<?php echo $this->getValidationUrl() ?>'});
+
     <?php if ($this->getSelectedTabId()): ?>
     if($('#<?php echo $this->getSelectedTabId() ?>').length) {
         $('#<?php echo $this->getSelectedTabId() ?>').trigger('click');
@@ -96,7 +72,8 @@ jQuery(function($) {
     <?php endif; ?>
 
     $('#product_info_tabs').on('tabsbeforeactivate', function (event, ui) {
-        $('#config_super_product')[$(ui.newPanel).find('#attribute-name-container').length ? 'show' : 'hide']();
+        var action = $(ui.newPanel).find('#attribute-name-container').length ? 'show' : 'hide';
+        $('#config_super_product, #grouped_product_container')[action]();
     });
 
     var masks = <?php echo $this->helper('Mage_Core_Helper_Data')->jsonEncode($this->getFieldsAutogenerationMasks())?>;
@@ -172,27 +149,30 @@ jQuery(function($) {
 
     new Autogenerator(masks).bindAll();
 
-    var data = <?php echo $this->getTypeSwitcherData();?>;
-    new TypeSwitcher(data).bindAll();
+    new TypeSwitcher(<?php echo $this->getTypeSwitcherData();?>).bindAll();
 
     $('.widget-button-save .item-default, #save-split-button-duplicate-button[onclick=""]').parent().hide();
     var $form = $('#product-edit-form'),
-        fieldSelector = '.required-entry, .required-option-select';
-    $form.on('focus change keyup click', fieldSelector + ',:checkbox,button', function () {
-        var disabled = false;
-        $.each($form.find(fieldSelector), function () {
-            if (!$.trim($(this).val()) && !$(this).closest('.ignore-validate').length
-                && $(this).is('input, select, textarea') && !$(this).prop('disabled')
-            ) {
-                disabled = true;
-                return false;
-            }
-        });
-        $('.widget-button-save, .widget-button-save > *').toggleClass('disabled', disabled).prop('disabled', disabled);
-    });
-
+        fieldSelector = '.required-entry, .required-option-select',
+        updateSaveSplitButtonAvailability = function () {
+            var disabled = false;
+            $.each($form.find(fieldSelector), function () {
+                if (!$.trim($(this).val()) && !$(this).closest('.ignore-validate').length
+                    && $(this).is('input, select, textarea') && !$(this).prop('disabled')
+                ) {
+                    disabled = true;
+                    return false;
+                }
+            });
+            $('.widget-button-save, .widget-button-save > *').toggleClass('disabled', disabled).prop('disabled', disabled);
+        };
+    $form.on('focus change keyup click', fieldSelector + ',:checkbox,button', updateSaveSplitButtonAvailability);
     $(window).load(function() {
-        $('#name').focus().val($('#name').val());
+        if ($.trim($('#name').val()) == '') {
+            $('#name').focus();
+        } else {
+            updateSaveSplitButtonAvailability();
+        }
     });
 });
 </script>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/options.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/options.phtml
index 7b77b65c6a4..e1bf3bf7e7b 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/options.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/options.phtml
@@ -25,7 +25,7 @@
  */
 ?>
 <div class="entry-edit custom-options product-custom-options">
-    <div id="dynamic-price-warrning" style="display:none">
+    <div id="dynamic-price-warning" style="display:none">
         <ul class="messages">
             <li class="error-msg">
                 <ul>
@@ -53,8 +53,8 @@
 varienWindowOnload(true);
 //show error message
 if ($('price_type')) {
-    if ($('price_type').value == '0' && $('dynamic-price-warrning')) {
-        $('dynamic-price-warrning').show();
+    if ($('price_type').value == '0' && $('dynamic-price-warning')) {
+        $('dynamic-price-warning').show();
     }
 }
 </script>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/attribute-js-template.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/attribute-js-template.phtml
index 5b8eb223ed8..3cd2bbdaa9e 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/attribute-js-template.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/attribute-js-template.phtml
@@ -38,8 +38,8 @@
         <input value="${attribute.code}" type="hidden"
             name="product[configurable_attributes_data][${attribute.id}][code]"/>
 
-        <div class="entry-edit-head" style="cursor: move;">
-            <span class="ui-icon ui-icon-arrowthick-2-n-s" style="float:left"></span>
+        <div class="entry-edit-head">
+            <span class="ui-icon ui-icon-grip-dotted-vertical" style="float:left"></span>
             <h4 class="icon-head head-edit-form fieldset-legend">
                 <input value="${attribute.label}"
                     name="product[configurable_attributes_data][${attribute.id}][label]"
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/attribute-template.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/attribute-template.phtml
index e3a9e1837d7..c8ce5544266 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/attribute-template.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/attribute-template.phtml
@@ -48,8 +48,8 @@ $id = $this->escapeHtml($attribute['attribute_id']);
     <input value="<?php echo $this->escapeHtml($attribute['position']); ?>" type="hidden"
         name="product[configurable_attributes_data][<?php echo $id ?>][position]"/>
 
-    <div class="entry-edit-head" style="cursor: move;">
-        <span class="ui-icon ui-icon-arrowthick-2-n-s" style="float:left;"></span>
+    <div class="entry-edit-head">
+        <span class="ui-icon ui-icon-grip-dotted-vertical" style="float:left"></span>
         <h4 class="icon-head head-edit-form fieldset-legend">
             <input value="<?php echo $this->escapeHtml($attribute['label']); ?>"
                 name="product[configurable_attributes_data][<?php echo $id ?>][label]"
@@ -62,7 +62,7 @@ $id = $this->escapeHtml($attribute['attribute_id']);
                     name="product[configurable_attributes_data][<?php echo $id ?>][use_default]"
                     id="attribute-<?php echo $id ?>"/>
                 <?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Use default')?>
-                </label>
+            </label>
         </h4>
         <span class="ui-icon ui-icon-circle-close remove"></span>
         <span class="ui-icon ui-icon-circle-triangle-s toggle"></span>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml
index d01eefba207..1f69e3ab83d 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/edit/super/config.phtml
@@ -73,18 +73,25 @@ jQuery(function($) {
     $('#attributes-container').variationsAttributes();
 
     $("#<?php echo $this->getId()?>-checkbox").on('click change', function() {
-        var $fieldset = $("#<?php echo $this->getId()?> > fieldset");
+        var $fieldset = $("#<?php echo $this->getId()?> > fieldset"),
+            stockAvailabilityField = $('#quantity_and_stock_status'),
+            qtyField = $('#qty');
         if ($(this).is(':checked')) {
             $fieldset.show();
             $('#change-attribute-set-button').attr('disabled', true).addClass('disabled');
             $variationsContainer.find("input[name='attributes[]']").removeAttr('disabled');
-            $('#qty').attr('disabled', true);
+            qtyField.prop('disabled', true).trigger('change');
+            stockAvailabilityField.prop('disabled', false);
             $.each($('#attributes-container').variationsAttributes('getAttributes'), function() {
                 $('#attribute-' + this.code + '-container select').attr('disabled', true);
             })
         } else {
             $('#change-attribute-set-button').removeAttr('disabled').removeClass('disabled');
-            $('#qty').removeAttr('disabled');
+            qtyField.prop('disabled', false).trigger('change');
+            if (qtyField.val() == '') {
+                stockAvailabilityField.val(0).trigger('change');
+                stockAvailabilityField.prop('disabled', true);
+            }
             $variationsContainer.find('.entry-edit').remove();
             $.each($('#attributes-container').variationsAttributes('getAttributes'), function() {
                 $('#attribute-' + this.code + '-container select').removeAttr('disabled');
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/tab/inventory.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/tab/inventory.phtml
index 21fbab07086..b1ff06f43a5 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/tab/inventory.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/product/tab/inventory.phtml
@@ -55,7 +55,7 @@
             <?php endif; ?>
         </tr>
 
-<?php if (!$this->getProduct()->isComposite() || $this->getProduct()->isConfigurable()): ?>
+<?php if (!$this->getProduct()->isComposite()): ?>
         <tr>
             <td class="label"><label for="inventory_qty"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Qty') ?></label></td>
             <td class="value">
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/type-switcher.js b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/type-switcher.js
index 24ead0511be..3fb0020093c 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/type-switcher.js
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/catalog/type-switcher.js
@@ -65,11 +65,15 @@
             this.$is_virtual.on('change click', function() {
                 if ($(this).is(':checked')) {
                     $type.val(self.baseType.virtual).trigger('change');
-                    self.$weight.addClass('ignore-validate').attr('disabled', 'disabled');
+                    if ($type.val() != 'bundle') { // @TODO move this check to Mage_Bundle after refactoring as widget
+                        self.$weight.addClass('ignore-validate').prop('disabled', true);
+                    }
                     self.$tab.show();
                 } else {
                     $type.val(self.baseType.real).trigger('change');
-                    self.$weight.removeClass('ignore-validate').removeAttr('disabled', 'disabled');
+                    if ($type.val() != 'bundle') { // @TODO move this check to Mage_Bundle after refactoring as widget
+                        self.$weight.removeClass('ignore-validate').prop('disabled', false);
+                    }
                     self.$tab.hide();
                 }
             }).trigger('change');
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/main.xml b/app/code/core/Mage/Adminhtml/view/adminhtml/main.xml
index 313d4fe971f..ff9a18fb391 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/main.xml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/main.xml
@@ -60,7 +60,6 @@ Supported layout update handles (special):
                 <action method="addJs"><file>jquery/jquery-ui.custom.min.js</file></action>
                 <action method="addJs"><file>head.load.min.js</file></action>
                 <action method="addJs"><file>mage/mage.js</file></action>
-                <action method="addJs"><file>mage/backend/button.js</file></action>
                 <action method="addJs"><file>jquery/jquery.tmpl.min.js</file></action>
                 <action method="addJs"><file>mage/translate.js</file></action>
                 <action method="addJs"><file>mage/backend/bootstrap.js</file></action>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/page/js/components.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/page/js/components.phtml
index d846a9742ed..c52ecf8b104 100644
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/page/js/components.phtml
+++ b/app/code/core/Mage/Adminhtml/view/adminhtml/page/js/components.phtml
@@ -34,6 +34,8 @@
 <script type="text/javascript">
     (function($) {
         "use strict";
+        $.mage.isDevMode(<?php echo Mage::getIsDeveloperMode() ?>);
+
         /**
          * Declaration of resources needed for defined components
          */
@@ -45,6 +47,9 @@
             button: [
                 '<?php echo $this->getViewFileUrl('mage/backend/button.js') ?>'
             ],
+            actionLink: [
+                '<?php echo $this->getViewFileUrl('mage/backend/action-link.js') ?>'
+            ],
             validation: [
                 '<?php echo $this->getViewFileUrl('jquery/jquery.validate.js') ?>',
                 '<?php echo $this->getViewFileUrl('mage/translate.js') ?>',
@@ -62,8 +67,28 @@
             ],
             floatingHeader: [
                 '<?php echo $this->getViewFileUrl('mage/backend/floating-header.js') ?>',
+            ],
+            suggest: [
+                '<?php echo $this->getViewFileUrl('jquery/jquery.tmpl.min.js') ?>',
+                '<?php echo $this->getViewFileUrl('json2.js') ?>',
+                '<?php echo $this->getViewFileUrl('mage/backend/suggest.js') ?>'
             ]
-        }).load('loader');
+        })
+        /**
+         * Declaration of resources for components (based on previously defined components)
+         */
+        .extend('multisuggest', 'suggest',
+            '<?php echo $this->getViewFileUrl('mage/backend/multisuggest.js') ?>'
+        )
+        .extend('treeSuggest', 'multisuggest', [
+            '<?php echo $this->getViewFileUrl('jquery/jstree/jquery.hotkeys.js') ?>',
+            '<?php echo $this->getViewFileUrl('jquery/jstree/jquery.jstree.js') ?>',
+            '<?php echo $this->getViewFileUrl('mage/backend/tree-suggest.js') ?>'
+        ])
+        /**
+         * Load resources in advance for components which needed to be instantiated without delay.
+         */
+        .load('loader');
     })(jQuery);
 </script>
 <?php echo $this->getChildHtml() ?>
diff --git a/app/code/core/Mage/Adminhtml/view/adminhtml/resetforgottenpassword.phtml b/app/code/core/Mage/Adminhtml/view/adminhtml/resetforgottenpassword.phtml
deleted file mode 100644
index dbfd8971a10..00000000000
--- a/app/code/core/Mage/Adminhtml/view/adminhtml/resetforgottenpassword.phtml
+++ /dev/null
@@ -1,89 +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.
- *
- * @category    design
- * @package     default_default
- * @copyright   Copyright (c) 2013 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 lang="en">
-    <head>
-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-        <title><?php echo Mage::helper('Mage_Adminhtml_Helper_Data')->__('Reset a Password'); ?></title>
-        <link type="text/css" rel="stylesheet" href="<?php echo $this->getViewFileUrl('reset.css'); ?>" media="all" />
-        <link type="text/css" rel="stylesheet" href="<?php echo $this->getViewFileUrl('boxes.css'); ?>" media="all" />
-        <link rel="icon" href="<?php echo $this->getViewFileUrl('Mage_Page::favicon.ico'); ?>" type="image/x-icon" />
-        <link rel="shortcut icon" href="<?php echo $this->getViewFileUrl('Mage_Page::favicon.ico'); ?>" type="image/x-icon" />
-
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('jquery/jquery.min.js') ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('mage/jquery-no-conflict.js') ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('jquery/jquery-ui.custom.min.js') ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('jquery/jquery.tmpl.min.js') ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('jquery/jquery.validate.js') ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('mage/validation.js') ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('mage/backend/validation.js') ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('mage/backend/form.js') ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('mage/translate.js') ?>"></script>
-
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('prototype/prototype.js'); ?>"></script>
-        <script type="text/javascript" src="<?php echo $this->getViewFileUrl('scriptaculous/effects.js'); ?>"></script>
-
-    <!--[if IE]> <link rel="stylesheet" href="<?php echo $this->getViewFileUrl('iestyles.css'); ?>" type="text/css" media="all" /> <![endif]-->
-    <!--[if lt IE 7]> <link rel="stylesheet" href="<?php echo $this->getViewFileUrl('below_ie7.css'); ?>" type="text/css" media="all" /> <![endif]-->
-    <!--[if IE 7]> <link rel="stylesheet" href="<?php echo $this->getViewFileUrl('ie7.css'); ?>" type="text/css" media="all" /> <![endif]-->
-    </head>
-    <body id="page-login">
-        <div class="login-container">
-            <div class="login-box">
-                <form method="post" action="<?php echo $this->getUrl('*/*/resetpasswordpost', array('_query' => array('id' => $userId, 'token' => $resetPasswordLinkToken))); ?>" id="reset-password-form">
-                    <fieldset class="login-form">
-                        <input name="form_key" type="hidden" value="<?php echo $this->getFormKey(); ?>" />
-                        <h2><?php echo Mage::helper('Mage_Adminhtml_Helper_Data')->__('Reset a Password'); ?></h2>
-                        <div id="messages">
-                            <?php echo $this->getMessagesBlock()->getGroupedHtml(); ?>
-                        </div>
-                        <div class="input-box f-left">
-                            <label for="password"><em class="required">*</em> <?php echo $this->__('New Password'); ?></label>
-                            <br />
-                            <input type="password" class="input-text required-entry validate-admin-password" name="password" id="password" />
-                        </div>
-                        <div class="input-box f-right">
-                            <label for="confirmation"><em class="required">*</em> <?php echo $this->__('Confirm New Password'); ?></label>
-                            <br />
-                            <input type="password" class="input-text required-entry validate-cpassword" name="confirmation" id="confirmation" />
-                        </div>
-                        <div class="clear"></div>
-                        <div class="form-buttons">
-                            <a class="left" href="<?php echo $this->getUrl('adminhtml', array('_nosecret' => true)) ?>">&laquo; <?php echo Mage::helper('Mage_Adminhtml_Helper_Data')->__('Back to Login'); ?></a>
-                            <button type="submit" title="<?php echo Mage::helper('Mage_Adminhtml_Helper_Data')->__('Reset Password'); ?>" class="forgot-password"><span><span><span><?php echo Mage::helper('Mage_Adminhtml_Helper_Data')->__('Reset Password'); ?></span></span></span></button>
-                        </div>
-                    </fieldset>
-                    <p class="legal"><?php echo Mage::helper('Mage_Adminhtml_Helper_Data')->__('Magento&reg is a trademark of X.commerce, Inc. Copyright &copy; %s X.commerce, Inc.', date('Y')); ?></p>
-                </form>
-                <div class="bottom"></div>
-                <script type="text/javascript">
-                    jQuery('#reset-password-form').form().validation();
-                </script>
-            </div>
-        </div>
-    </body>
-</html>
diff --git a/app/code/core/Mage/Api/Controller/Action.php b/app/code/core/Mage/Api/Controller/Action.php
new file mode 100644
index 00000000000..e378d3e5a73
--- /dev/null
+++ b/app/code/core/Mage/Api/Controller/Action.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Generic API controller
+ */
+class Mage_Api_Controller_Action extends Mage_Core_Controller_Front_Action
+{
+    /**
+     * Currently used area
+     *
+     * @var string
+     */
+    protected $_currentArea = 'frontend';
+
+    /**
+     * Use 'admin' store and prevent the session from starting
+     *
+     * @return Mage_Api_Controller_Action
+     */
+    public function preDispatch()
+    {
+        Mage::app()->setCurrentStore('admin');
+        $this->setFlag('', self::FLAG_NO_START_SESSION, 1);
+        parent::preDispatch();
+        return $this;
+    }
+
+    /**
+     * Retrieve webservice server
+     *
+     * @return Mage_Api_Model_Server
+     */
+    protected function _getServer()
+    {
+        return Mage::getSingleton('Mage_Api_Model_Server');
+    }
+}
diff --git a/app/code/core/Mage/Api/Exception.php b/app/code/core/Mage/Api/Exception.php
new file mode 100644
index 00000000000..e290bd268f8
--- /dev/null
+++ b/app/code/core/Mage/Api/Exception.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Api exception
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Exception extends Mage_Core_Exception
+{
+    protected $_customMessage = null;
+
+    public function __construct($faultCode, $customMessage=null)
+    {
+        parent::__construct($faultCode);
+        $this->_customMessage = $customMessage;
+    }
+
+    /**
+     * Custom error message, if error is not in api.
+     *
+     * @return unknown
+     */
+    public function getCustomMessage()
+    {
+        return $this->_customMessage;
+    }
+} // Class Mage_Api_Model_Resource_Exception End
diff --git a/app/code/core/Mage/Api/Helper/Data.php b/app/code/core/Mage/Api/Helper/Data.php
new file mode 100644
index 00000000000..a7bd732c3de
--- /dev/null
+++ b/app/code/core/Mage/Api/Helper/Data.php
@@ -0,0 +1,359 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Web service api main helper
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Helper_Data extends Mage_Core_Helper_Abstract
+{
+    /**
+     * Go thru a WSI args array and turns it to correct state.
+     *
+     * @param Object $obj - Link to Object
+     * @return Object
+     */
+    public function wsiArrayUnpacker(&$obj)
+    {
+        if (is_object($obj)) {
+
+            $modifiedKeys = $this->clearWsiFootprints($obj);
+
+            foreach ($obj as $key => $value) {
+                if (is_object($value)) {
+                    $this->wsiArrayUnpacker($value);
+                }
+                if (is_array($value)) {
+                    foreach ($value as &$val) {
+                        if (is_object($val)) {
+                            $this->wsiArrayUnpacker($val);
+                        }
+                    }
+                }
+            }
+
+            foreach ($modifiedKeys as $arrKey) {
+                $this->associativeArrayUnpack($obj->$arrKey);
+            }
+        }
+    }
+
+    /**
+     * Go thru an object parameters and unpak associative object to array.
+     *
+     * @param Object $obj - Link to Object
+     * @return Object
+     */
+    public function v2AssociativeArrayUnpacker(&$obj)
+    {
+        if (is_object($obj)
+            && property_exists($obj, 'key')
+            && property_exists($obj, 'value')
+        ) {
+            if (count(array_keys(get_object_vars($obj))) == 2) {
+                $obj = array($obj->key => $obj->value);
+                return true;
+            }
+        } elseif (is_array($obj)) {
+            $arr = array();
+            $needReplacement = true;
+            foreach ($obj as $key => &$value) {
+                $isAssoc = $this->v2AssociativeArrayUnpacker($value);
+                if ($isAssoc) {
+                    foreach ($value as $aKey => $aVal) {
+                        $arr[$aKey] = $aVal;
+                    }
+                } else {
+                    $needReplacement = false;
+                }
+            }
+            if ($needReplacement) {
+                $obj = $arr;
+            }
+        } elseif (is_object($obj)) {
+            $objectKeys = array_keys(get_object_vars($obj));
+
+            foreach ($objectKeys as $key) {
+                $this->v2AssociativeArrayUnpacker($obj->$key);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Go thru mixed and turns it to a correct look.
+     *
+     * @param Mixed $mixed A link to variable that may contain associative array.
+     */
+    public function associativeArrayUnpack(&$mixed)
+    {
+        if (is_array($mixed)) {
+            $tmpArr = array();
+            foreach ($mixed as $key => $value) {
+                if (is_object($value)) {
+                    $value = get_object_vars($value);
+                    if (count($value) == 2 && isset($value['key']) && isset($value['value'])) {
+                        $tmpArr[$value['key']] = $value['value'];
+                    }
+                }
+            }
+            if (count($tmpArr)) {
+                $mixed = $tmpArr;
+            }
+        }
+
+        if (is_object($mixed)) {
+            $numOfVals = count(get_object_vars($mixed));
+            if ($numOfVals == 2 && isset($mixed->key) && isset($mixed->value)) {
+                $mixed = get_object_vars($mixed);
+                /*
+                 * Processing an associative arrays.
+                 * $mixed->key = '2'; $mixed->value = '3'; turns to array(2 => '3');
+                 */
+                $mixed = array($mixed['key'] => $mixed['value']);
+            }
+        }
+    }
+
+    /**
+     * Corrects data representation.
+     *
+     * @param Object $obj - Link to Object
+     * @return Object
+     */
+    public function clearWsiFootprints(&$obj)
+    {
+        $modifiedKeys = array();
+
+        $objectKeys = array_keys(get_object_vars($obj));
+
+        foreach ($objectKeys as $key) {
+            if (is_object($obj->$key) && isset($obj->$key->complexObjectArray)) {
+                if (is_array($obj->$key->complexObjectArray)) {
+                    $obj->$key = $obj->$key->complexObjectArray;
+                } else { // for one element array
+                    $obj->$key = array($obj->$key->complexObjectArray);
+                }
+                $modifiedKeys[] = $key;
+            }
+        }
+        return $modifiedKeys;
+    }
+
+    /**
+     * For the WSI, generates an response object.
+     *
+     * @param mixed $mixed - Link to Object
+     * @return mixed
+     */
+    public function wsiArrayPacker($mixed)
+    {
+        if (is_array($mixed)) {
+            $arrKeys = array_keys($mixed);
+            $isDigit = false;
+            $isString = false;
+            foreach ($arrKeys as $key) {
+                if (is_int($key)) {
+                    $isDigit = true;
+                    break;
+                }
+            }
+            if ($isDigit) {
+                $mixed = $this->packArrayToObjec($mixed);
+            } else {
+                $mixed = (object)$mixed;
+            }
+        }
+        if (is_object($mixed) && isset($mixed->complexObjectArray)) {
+            foreach ($mixed->complexObjectArray as $k => $v) {
+                $mixed->complexObjectArray[$k] = $this->wsiArrayPacker($v);
+            }
+        }
+        return $mixed;
+    }
+
+    /**
+     * For response to the WSI, generates an object from array.
+     *
+     * @param Array $arr - Link to Object
+     * @return Object
+     */
+    public function packArrayToObjec(Array $arr)
+    {
+        $obj = new stdClass();
+        $obj->complexObjectArray = $arr;
+        return $obj;
+    }
+
+    /**
+     * Convert objects and arrays to array recursively
+     *
+     * @param  array|object $data
+     * @return void
+     */
+    public function toArray(&$data)
+    {
+        if (is_object($data)) {
+            $data = get_object_vars($data);
+        }
+        if (is_array($data)) {
+            foreach ($data as &$value) {
+                if (is_array($value) or is_object($value)) {
+                    $this->toArray($value);
+                }
+            }
+        }
+    }
+
+    /**
+     * Parse filters and format them to be applicable for collection filtration
+     *
+     * @param null|object|array $filters
+     * @param array $fieldsMap Map of field names in format: array('field_name_in_filter' => 'field_name_in_db')
+     * @return array
+     */
+    public function parseFilters($filters, $fieldsMap = null)
+    {
+        // if filters are used in SOAP they must be represented in array format to be used for collection filtration
+        if (is_object($filters)) {
+            $parsedFilters = array();
+            // parse simple filter
+            if (isset($filters->filter) && is_array($filters->filter)) {
+                foreach ($filters->filter as $field => $value) {
+                    if (is_object($value) && isset($value->key) && isset($value->value)) {
+                        $parsedFilters[$value->key] = $value->value;
+                    } else {
+                        $parsedFilters[$field] = $value;
+                    }
+                }
+            }
+            // parse complex filter
+            if (isset($filters->complex_filter) && is_array($filters->complex_filter)) {
+                if ($this->isWsiCompliant()) {
+                    // WS-I compliance mode
+                    foreach ($filters->complex_filter as $fieldName => $condition) {
+                        if (is_object($condition) && isset($condition->key) && isset($condition->value)) {
+                            $conditionName = $condition->key;
+                            $conditionValue = $condition->value;
+                            $this->formatFilterConditionValue($conditionName, $conditionValue);
+                            $parsedFilters[$fieldName] = array($conditionName => $conditionValue);
+                        }
+                    }
+                } else {
+                    // non WS-I compliance mode
+                    foreach ($filters->complex_filter as $value) {
+                        if (is_object($value) && isset($value->key) && isset($value->value)) {
+                            $fieldName = $value->key;
+                            $condition = $value->value;
+                            if (is_object($condition) && isset($condition->key) && isset($condition->value)) {
+                                $this->formatFilterConditionValue($condition->key, $condition->value);
+                                $parsedFilters[$fieldName] = array($condition->key => $condition->value);
+                            }
+                        }
+                    }
+                }
+            }
+            $filters = $parsedFilters;
+        }
+        // make sure that method result is always array
+        if (!is_array($filters)) {
+            $filters = array();
+        }
+        // apply fields mapping
+        if (isset($fieldsMap) && is_array($fieldsMap)) {
+            foreach ($filters as $field => $value) {
+                if (isset($fieldsMap[$field])) {
+                    unset($filters[$field]);
+                    $field = $fieldsMap[$field];
+                    $filters[$field] = $value;
+                }
+            }
+        }
+        return $filters;
+    }
+
+    /**
+     * Check if API is working in SOAP WS-I compliant mode.
+     *
+     * @return bool
+     */
+    public function isWsiCompliant()
+    {
+        $pathInfo = Mage::app()->getRequest()->getPathInfo();
+        $pathParts = explode('/', trim($pathInfo, '/'));
+        $controllerPosition = 1;
+        if (isset($pathParts[$controllerPosition]) && $pathParts[$controllerPosition] == 'soap_wsi') {
+            $isWsiCompliant = true;
+        } else {
+            $isWsiCompliant = false;
+        }
+        return $isWsiCompliant;
+    }
+
+    /**
+     * Convert condition value from the string into the array
+     * for the condition operators that require value to be an array.
+     * Condition value is changed by reference
+     *
+     * @param string $conditionOperator
+     * @param string $conditionValue
+     */
+    public function formatFilterConditionValue($conditionOperator, &$conditionValue)
+    {
+        if (is_string($conditionOperator) && in_array($conditionOperator, array('in', 'nin', 'finset'))
+            && is_string($conditionValue)
+        ) {
+            $delimiter = ',';
+            $conditionValue = explode($delimiter, $conditionValue);
+        }
+    }
+
+    /**
+     * Check if attribute is allowed to be used.
+     *
+     * @param string $attributeCode
+     * @param string $type
+     * @param array $ignoredAttributes
+     * @param array $attributes
+     * @return bool
+     */
+    public function isAttributeAllowed($attributeCode, $type, $ignoredAttributes, array $attributes = null)
+    {
+        if (!empty($attributes) && !(in_array($attributeCode, $attributes))) {
+            return false;
+        }
+        if (isset($ignoredAttributes['global']) && in_array($attributeCode, $ignoredAttributes['global'])) {
+            return false;
+        }
+        if (isset($ignoredAttributes[$type]) && in_array($attributeCode, $ignoredAttributes[$type])) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Acl.php b/app/code/core/Mage/Api/Model/Acl.php
new file mode 100644
index 00000000000..3fb69610582
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Acl.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Acl model
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Acl extends Zend_Acl
+{
+    /**
+     * All the group roles are prepended by G
+     *
+     */
+    const ROLE_TYPE_GROUP = 'G';
+
+    /**
+     * All the user roles are prepended by U
+     *
+     */
+    const ROLE_TYPE_USER = 'U';
+
+    /**
+     * User types for store access
+     * G - Guest customer (anonymous)
+     * C - Authenticated customer
+     * A - Authenticated admin user
+     *
+     */
+    const USER_TYPE_GUEST    = 'G';
+    const USER_TYPE_CUSTOMER = 'C';
+    const USER_TYPE_ADMIN    = 'A';
+
+    /**
+     * Permission level to deny access
+     *
+     */
+    const RULE_PERM_DENY = 0;
+
+    /**
+     * Permission level to inheric access from parent role
+     *
+     */
+    const RULE_PERM_INHERIT = 1;
+
+    /**
+     * Permission level to allow access
+     *
+     */
+    const RULE_PERM_ALLOW = 2;
+
+    /**
+     * Get role registry object or create one
+     *
+     * @return Mage_Api_Model_Acl_Role_Registry
+     */
+    protected function _getRoleRegistry()
+    {
+        if (null === $this->_roleRegistry) {
+            $this->_roleRegistry = Mage::getModel('Mage_Api_Model_Acl_Role_Registry');
+        }
+        return $this->_roleRegistry;
+    }
+
+    /**
+     * Add parent to role object
+     *
+     * @param Zend_Acl_Role $role
+     * @param Zend_Acl_Role $parent
+     * @return Mage_Api_Model_Acl
+     */
+    public function addRoleParent($role, $parent)
+    {
+        $this->_getRoleRegistry()->addParent($role, $parent);
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Acl/Resource.php b/app/code/core/Mage/Api/Model/Acl/Resource.php
new file mode 100644
index 00000000000..e771e5e9874
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Acl/Resource.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Acl resource
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Acl_Resource extends Zend_Acl_Resource
+{
+
+}
diff --git a/app/code/core/Mage/Api/Model/Acl/Role.php b/app/code/core/Mage/Api/Model/Acl/Role.php
new file mode 100644
index 00000000000..1a4bd2ff482
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Acl/Role.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * User acl role
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Acl_Role extends Mage_Api_Model_Role
+{
+}
diff --git a/app/code/core/Mage/Api/Model/Acl/Role/Generic.php b/app/code/core/Mage/Api/Model/Acl/Role/Generic.php
new file mode 100644
index 00000000000..10d240d0f42
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Acl/Role/Generic.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * User acl role
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Acl_Role_Generic extends Zend_Acl_Role
+{
+
+}
diff --git a/app/code/core/Mage/Api/Model/Acl/Role/Group.php b/app/code/core/Mage/Api/Model/Acl/Role/Group.php
new file mode 100644
index 00000000000..c30cae453e2
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Acl/Role/Group.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Acl Group model
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Acl_Role_Group extends Mage_Api_Model_Acl_Role_Generic
+{
+
+}
diff --git a/app/code/core/Mage/Api/Model/Acl/Role/Registry.php b/app/code/core/Mage/Api/Model/Acl/Role/Registry.php
new file mode 100644
index 00000000000..2da227383f1
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Acl/Role/Registry.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Acl role registry
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Acl_Role_Registry extends Zend_Acl_Role_Registry
+{
+    /**
+     * Add parent to the $role node
+     *
+     * @param Zend_Acl_Role_Interface|string $role
+     * @param array|Zend_Acl_Role_Interface|string $parents
+     * @return Mage_Auth_Model_Acl_Role_Registry
+     */
+    function addParent($role, $parents)
+    {
+        try {
+            if ($role instanceof Zend_Acl_Role_Interface) {
+                $roleId = $role->getRoleId();
+            } else {
+                $roleId = $role;
+                $role = $this->get($role);
+            }
+        } catch (Zend_Acl_Role_Registry_Exception $e) {
+            throw new Zend_Acl_Role_Registry_Exception("Child Role id '$roleId' does not exist");
+        }
+
+        if (!is_array($parents)) {
+            $parents = array($parents);
+        }
+        foreach ($parents as $parent) {
+            try {
+                if ($parent instanceof Zend_Acl_Role_Interface) {
+                    $roleParentId = $parent->getRoleId();
+                } else {
+                    $roleParentId = $parent;
+                }
+                $roleParent = $this->get($roleParentId);
+            } catch (Zend_Acl_Role_Registry_Exception $e) {
+                throw new Zend_Acl_Role_Registry_Exception("Parent Role id '$roleParentId' does not exist");
+            }
+            $this->_roles[$roleId]['parents'][$roleParentId] = $roleParent;
+            $this->_roles[$roleParentId]['children'][$roleId] = $role;
+        }
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Acl/Role/User.php b/app/code/core/Mage/Api/Model/Acl/Role/User.php
new file mode 100644
index 00000000000..3833e18fd04
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Acl/Role/User.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * User acl role
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Acl_Role_User extends Mage_Api_Model_Acl_Role_Generic
+{
+
+}
diff --git a/app/code/core/Mage/Api/Model/Config.php b/app/code/core/Mage/Api/Model/Config.php
new file mode 100644
index 00000000000..2abff6da50e
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Config.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Webservice api config model
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Config extends Varien_Simplexml_Config
+{
+    const CACHE_TAG         = 'config_api';
+
+    /**
+     * Constructor
+     *
+     * @see Varien_Simplexml_Config
+     */
+    public function __construct($sourceData=null)
+    {
+        $this->setCacheId('config_api');
+        $this->setCacheTags(array(self::CACHE_TAG));
+
+        parent::__construct($sourceData);
+        $this->_construct();
+    }
+
+    /**
+     * Init configuration for webservices api
+     *
+     * @return Mage_Api_Model_Config
+     */
+    protected function _construct()
+    {
+        if (Mage::app()->useCache('config_api')) {
+            if ($this->loadCache()) {
+                return $this;
+            }
+        }
+
+        $config = Mage::getConfig()->loadModulesConfiguration('api.xml');
+        $this->setXml($config->getNode('api'));
+
+        if (Mage::app()->useCache('config_api')) {
+            $this->saveCache();
+        }
+        return $this;
+    }
+
+    /**
+     * Retrieve adapter aliases from config.
+     *
+     * @return array
+     */
+    public function getAdapterAliases()
+    {
+        $aliases = array();
+
+        foreach ($this->getNode('adapter_aliases')->children() as $alias => $adapter) {
+            $aliases[$alias] = array(
+                (string) $adapter->suggest_class, // model class name
+                (string) $adapter->suggest_method // model method name
+            );
+        }
+        return $aliases;
+    }
+
+    /**
+     * Retrieve all adapters
+     *
+     * @return array
+     */
+    public function getAdapters()
+    {
+        $adapters = array();
+        foreach ($this->getNode('adapters')->children() as $adapterName => $adapter) {
+            /* @var $adapter Varien_SimpleXml_Element */
+            if (isset($adapter->use)) {
+                $adapter = $this->getNode('adapters/' . (string) $adapter->use);
+            }
+            $adapters[$adapterName] = $adapter;
+        }
+        return $adapters;
+    }
+
+    /**
+     * Retrieve active adapters
+     *
+     * @return array
+     */
+    public function getActiveAdapters()
+    {
+        $adapters = array();
+        foreach ($this->getAdapters() as $adapterName => $adapter) {
+            if (!isset($adapter->active) || $adapter->active == '0') {
+                continue;
+            }
+
+            if (isset($adapter->required) && isset($adapter->required->extensions)) {
+                foreach ($adapter->required->extensions->children() as $extension=>$data) {
+                    if (!extension_loaded($extension)) {
+                        continue;
+                    }
+                }
+            }
+
+            $adapters[$adapterName] = $adapter;
+        }
+
+        return $adapters;
+    }
+
+    /**
+     * Retrieve handlers
+     *
+     * @return Varien_Simplexml_Element
+     */
+    public function getHandlers()
+    {
+        return $this->getNode('handlers')->children();
+    }
+
+    /**
+     * Retrieve resources
+     *
+     * @return Varien_Simplexml_Element
+     */
+    public function getResources()
+    {
+        return $this->getNode('resources')->children();
+    }
+
+    /**
+     * Retrieve resources alias
+     *
+     * @return Varien_Simplexml_Element
+     */
+    public function getResourcesAlias()
+    {
+        return $this->getNode('resources_alias')->children();
+    }
+
+
+    /**
+     * Load Acl resources from config
+     *
+     * @param Mage_Api_Model_Acl $acl
+     * @param Mage_Core_Model_Config_Element $resource
+     * @param string $parentName
+     * @return Mage_Api_Model_Config
+     */
+    public function loadAclResources(Mage_Api_Model_Acl $acl, $resource=null, $parentName=null)
+    {
+        $resourceName = null;
+        if (is_null($resource)) {
+            $resource = $this->getNode('acl/resources');
+        } else {
+            $resourceName = (is_null($parentName) ? '' : $parentName.'/').$resource->getName();
+            $acl->addResource(
+                Mage::getModel('Mage_Api_Model_Acl_Resource', array('resourceId' => $resourceName)),
+                $parentName
+            );
+        }
+
+        $children = $resource->children();
+
+        if (empty($children)) {
+            return $this;
+        }
+
+        foreach ($children as $res) {
+            if ($res->getName() != 'title' && $res->getName() != 'sort_order') {
+                $this->loadAclResources($acl, $res, $resourceName);
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Get acl assert config
+     *
+     * @param string $name
+     * @return Mage_Core_Model_Config_Element|boolean
+     */
+    public function getAclAssert($name='')
+    {
+        $asserts = $this->getNode('acl/asserts');
+        if (''===$name) {
+            return $asserts;
+        }
+
+        if (isset($asserts->$name)) {
+            return $asserts->$name;
+        }
+
+        return false;
+    }
+
+    /**
+     * Retrieve privilege set by name
+     *
+     * @param string $name
+     * @return Mage_Core_Model_Config_Element|boolean
+     */
+    public function getAclPrivilegeSet($name='')
+    {
+        $sets = $this->getNode('acl/privilegeSets');
+        if (''===$name) {
+            return $sets;
+        }
+
+        if (isset($sets->$name)) {
+            return $sets->$name;
+        }
+
+        return false;
+    }
+
+    public function getFaults($resourceName=null)
+    {
+        if (is_null($resourceName)
+            || !isset($this->getResources()->$resourceName)
+            || !isset($this->getResources()->$resourceName->faults)) {
+            $faultsNode = $this->getNode('faults');
+        } else {
+            $faultsNode = $this->getResources()->$resourceName->faults;
+        }
+        /* @var $faultsNode Varien_Simplexml_Element */
+
+        $translateModule = 'Mage_Api';
+        if (isset($faultsNode['module'])) {
+           $translateModule = (string) $faultsNode['module'];
+        }
+
+        $faults = array();
+        foreach ($faultsNode->children() as $faultName => $fault) {
+            $faults[$faultName] = array(
+                'code'    => (string) $fault->code,
+                'message' => Mage::helper($translateModule)->__((string)$fault->message)
+            );
+        }
+
+        return $faults;
+    }
+
+    /**
+     * Retrieve cache object
+     *
+     * @return Zend_Cache_Frontend_File
+     */
+    public function getCache()
+    {
+        return Mage::app()->getCache();
+    }
+
+    protected function _loadCache($id)
+    {
+        return Mage::app()->loadCache($id);
+    }
+
+    protected function _saveCache($data, $id, $tags=array(), $lifetime=false)
+    {
+        return Mage::app()->saveCache($data, $id, $tags, $lifetime);
+    }
+
+    protected function _removeCache($id)
+    {
+        return Mage::app()->removeCache($id);
+    }
+} // Class Mage_Api_Model_Config End
diff --git a/app/code/core/Mage/Api/Model/Resource/Abstract.php b/app/code/core/Mage/Api/Model/Resource/Abstract.php
new file mode 100644
index 00000000000..30573f5d844
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Abstract.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Api resource abstract
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Abstract
+{
+
+    /**
+     * Resource configuration
+     *
+     * @var Varien_Simplexml_Element
+     */
+    protected $_resourceConfig = null;
+
+    /**
+     * Retrieve webservice session
+     *
+     * @return Mage_Api_Model_Session
+     */
+    protected function _getSession()
+    {
+        return Mage::getSingleton('Mage_Api_Model_Session');
+    }
+
+    /**
+     * Retrieve webservice configuration
+     *
+     * @return Mage_Api_Model_Config
+     */
+    protected function _getConfig()
+    {
+        return Mage::getSingleton('Mage_Api_Model_Config');
+    }
+
+    /**
+     * Set configuration for api resource
+     *
+     * @param Varien_Simplexml_Element $xml
+     * @return Mage_Api_Model_Resource_Abstract
+     */
+    public function setResourceConfig(Varien_Simplexml_Element $xml)
+    {
+        $this->_resourceConfig = $xml;
+        return $this;
+    }
+
+    /**
+     * Retrieve configuration for api resource
+     *
+     * @return Varien_Simplexml_Element
+     */
+    public function getResourceConfig()
+    {
+        return $this->_resourceConfig;
+    }
+
+    /**
+     * Retrieve webservice server
+     *
+     * @return Mage_Api_Model_Server
+     */
+    protected function _getServer()
+    {
+        return Mage::getSingleton('Mage_Api_Model_Server');
+    }
+
+    /**
+     * Dispatches fault
+     *
+     * @param string $code
+     */
+    protected function _fault($code, $customMessage=null)
+    {
+        throw new Mage_Api_Exception($code, $customMessage);
+    }
+} // Class Mage_Api_Model_Resource_Abstract End
diff --git a/app/code/core/Mage/Api/Model/Resource/Acl.php b/app/code/core/Mage/Api/Model/Resource/Acl.php
new file mode 100755
index 00000000000..afffbc50fd4
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Acl.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Resource model for admin ACL
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Acl extends Mage_Core_Model_Resource_Db_Abstract
+{
+    /**
+     * Initialize resource connections
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('api_role', 'role_id');
+    }
+
+    /**
+     * Load ACL for the user
+     *
+     * @return Mage_Api_Model_Acl
+     */
+    public function loadAcl()
+    {
+        $acl = Mage::getModel('Mage_Api_Model_Acl');
+        $adapter = $this->_getReadAdapter();
+
+        Mage::getSingleton('Mage_Api_Model_Config')->loadAclResources($acl);
+
+        $rolesArr = $adapter->fetchAll(
+            $adapter->select()
+                ->from($this->getTable('api_role'))
+                ->order(array('tree_level', 'role_type'))
+        );
+        $this->loadRoles($acl, $rolesArr);
+
+        $rulesArr =  $adapter->fetchAll(
+            $adapter->select()
+                ->from(array('r'=>$this->getTable('api_rule')))
+                ->joinLeft(
+                    array('a'=>$this->getTable('api_assert')),
+                    'a.assert_id=r.assert_id',
+                    array('assert_type', 'assert_data')
+                ));
+        $this->loadRules($acl, $rulesArr);
+        return $acl;
+    }
+
+    /**
+     * Load roles
+     *
+     * @param Mage_Api_Model_Acl $acl
+     * @param array $rolesArr
+     * @return Mage_Api_Model_Resource_Acl
+     */
+    public function loadRoles(Mage_Api_Model_Acl $acl, array $rolesArr)
+    {
+        foreach ($rolesArr as $role) {
+            $parent = $role['parent_id']>0 ? Mage_Api_Model_Acl::ROLE_TYPE_GROUP.$role['parent_id'] : null;
+            switch ($role['role_type']) {
+                case Mage_Api_Model_Acl::ROLE_TYPE_GROUP:
+                    $roleId = $role['role_type'].$role['role_id'];
+                    $acl->addRole(
+                        Mage::getModel('Mage_Api_Model_Acl_Role_Group', array('roleId' => $roleId)),
+                        $parent
+                    );
+                    break;
+
+                case Mage_Api_Model_Acl::ROLE_TYPE_USER:
+                    $roleId = $role['role_type'].$role['user_id'];
+                    if (!$acl->hasRole($roleId)) {
+                        $acl->addRole(
+                            Mage::getModel('Mage_Api_Model_Acl_Role_User', array('roleId' => $roleId)),
+                            $parent
+                        );
+                    } else {
+                        $acl->addRoleParent($roleId, $parent);
+                    }
+                    break;
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Load rules
+     *
+     * @param Mage_Api_Model_Acl $acl
+     * @param array $rulesArr
+     * @return Mage_Api_Model_Resource_Acl
+     */
+    public function loadRules(Mage_Api_Model_Acl $acl, array $rulesArr)
+    {
+        foreach ($rulesArr as $rule) {
+            $role = $rule['role_type'].$rule['role_id'];
+            $resource = $rule['resource_id'];
+            $privileges = !empty($rule['api_privileges']) ? explode(',', $rule['api_privileges']) : null;
+
+            $assert = null;
+            if (0!=$rule['assert_id']) {
+                $assertClass = Mage::getSingleton('Mage_Api_Model_Config')->getAclAssert($rule['assert_type'])->getClassName();
+                $assert = new $assertClass(unserialize($rule['assert_data']));
+            }
+            try {
+                if ($rule['api_permission'] == 'allow') {
+                    $acl->allow($role, $resource, $privileges, $assert);
+                } else if ($rule['api_permission'] == 'deny') {
+                    $acl->deny($role, $resource, $privileges, $assert);
+                }
+            } catch (Exception $e) {
+                // TODO: properly process exception
+            }
+        }
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Acl/Role.php b/app/code/core/Mage/Api/Model/Resource/Acl/Role.php
new file mode 100755
index 00000000000..7cb39b0aa1f
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Acl/Role.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * ACL role resource
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Acl_Role extends Mage_Core_Model_Resource_Db_Abstract
+{
+    /**
+     * Resource initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('api_role', 'role_id');
+    }
+
+    /**
+     * Action before save
+     *
+     * @param Mage_Core_Model_Abstract $object
+     * @return Mage_Api_Model_Resource_Acl_Role
+     */
+    protected function _beforeSave(Mage_Core_Model_Abstract $object)
+    {
+        if (!$object->getId()) {
+            $this->setCreated(Mage::getSingleton('Mage_Core_Model_Date')->gmtDate());
+        }
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Acl/Role/Collection.php b/app/code/core/Mage/Api/Model/Resource/Acl/Role/Collection.php
new file mode 100755
index 00000000000..9eb406b78b2
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Acl/Role/Collection.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Acl Role Resource Collection
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Acl_Role_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    /**
+     * Resource collection initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Role', 'Mage_Api_Model_Resource_Role');
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Permissions/Collection.php b/app/code/core/Mage/Api/Model/Resource/Permissions/Collection.php
new file mode 100755
index 00000000000..b637787a41f
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Permissions/Collection.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Permissions Resource Collection
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Permissions_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    /**
+     * Resource collection initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Rules', 'Mage_Api_Model_Resource_Rules');
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Role.php b/app/code/core/Mage/Api/Model/Resource/Role.php
new file mode 100755
index 00000000000..6a7e0154d92
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Role.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * ACL role resource
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Role extends Mage_Core_Model_Resource_Db_Abstract
+{
+    /**
+     * Resource initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('api_role', 'role_id');
+    }
+
+    /**
+     * Action before save
+     *
+     * @param Mage_Core_Model_Abstract $object
+     * @return Mage_Api_Model_Resource_Role
+     */
+    protected function _beforeSave(Mage_Core_Model_Abstract $object)
+    {
+        if (!$object->getId()) {
+            $object->setCreated(now());
+        }
+        $object->setModified(now());
+        return $this;
+    }
+
+    /**
+     * Load an object
+     *
+     * @param Mage_Core_Model_Abstract $object
+     * @param mixed $value
+     * @param string $field field to load by (defaults to model id)
+     * @return Mage_Core_Model_Resource_Db_Abstract
+     */
+    public function load(Mage_Core_Model_Abstract $object, $value, $field = null)
+    {
+        if (!intval($value) && is_string($value)) {
+            $field = 'role_id';
+        }
+        return parent::load($object, $value, $field);
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Role/Collection.php b/app/code/core/Mage/Api/Model/Resource/Role/Collection.php
new file mode 100755
index 00000000000..7af32b391cf
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Role/Collection.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Api Role Resource Collection
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Role_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    /**
+     * Resource collection initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Role', 'Mage_Api_Model_Resource_Role');
+    }
+
+    /**
+     * Aet user filter
+     *
+     * @param int $userId
+     * @return Mage_Api_Model_Resource_Role_Collection
+     */
+    public function setUserFilter($userId)
+    {
+        $this->addFieldToFilter('user_id', $userId);
+        $this->addFieldToFilter('role_type', Mage_Api_Model_Acl::ROLE_TYPE_GROUP);
+        return $this;
+    }
+
+    /**
+     * Set roles filter
+     *
+     * @return Mage_Api_Model_Resource_Role_Collection
+     */
+    public function setRolesFilter()
+    {
+        $this->addFieldToFilter('role_type', Mage_Api_Model_Acl::ROLE_TYPE_GROUP);
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Roles.php b/app/code/core/Mage/Api/Model/Resource/Roles.php
new file mode 100755
index 00000000000..9676fe097a5
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Roles.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * ACL roles resource
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Roles extends Mage_Core_Model_Resource_Db_Abstract
+{
+    /**
+     * User table name
+     *
+     * @var unknown
+     */
+    protected $_usersTable;
+
+    /**
+     * Rule table name
+     *
+     * @var unknown
+     */
+    protected $_ruleTable;
+
+    /**
+     * Resource initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('api_role', 'role_id');
+
+        $this->_usersTable  = $this->getTable('api_user');
+        $this->_ruleTable   = $this->getTable('api_rule');
+    }
+
+    /**
+     * Action before save
+     *
+     * @param Mage_Core_Model_Abstract $role
+     * @return Mage_Api_Model_Resource_Roles
+     */
+    protected function _beforeSave(Mage_Core_Model_Abstract $role)
+    {
+        if ($role->getId() == '') {
+            if ($role->getIdFieldName()) {
+                $role->unsetData($role->getIdFieldName());
+            } else {
+                $role->unsetData('id');
+            }
+        }
+
+        if ($role->getPid() > 0) {
+            $row = $this->load($role->getPid());
+        } else {
+            $row = array('tree_level' => 0);
+        }
+        $role->setTreeLevel($row['tree_level'] + 1);
+        $role->setRoleName($role->getName());
+        return $this;
+    }
+
+    /**
+     * Action after save
+     *
+     * @param Mage_Core_Model_Abstract $role
+     * @return Mage_Api_Model_Resource_Roles
+     */
+    protected function _afterSave(Mage_Core_Model_Abstract $role)
+    {
+        $this->_updateRoleUsersAcl($role);
+        Mage::app()->getCache()->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG);
+        return $this;
+    }
+
+    /**
+     * Action after delete
+     *
+     * @param Mage_Core_Model_Abstract $role
+     * @return Mage_Api_Model_Resource_Roles
+     */
+    protected function _afterDelete(Mage_Core_Model_Abstract $role)
+    {
+        $adapter = $this->_getWriteAdapter();
+        $adapter->delete($this->getMainTable(), array('parent_id=?'=>$role->getId()));
+        $adapter->delete($this->_ruleTable, array('role_id=?'=>$role->getId()));
+        return $this;
+    }
+
+    /**
+     * Get role users
+     *
+     * @param Mage_Api_Model_Roles $role
+     * @return unknown
+     */
+    public function getRoleUsers(Mage_Api_Model_Roles $role)
+    {
+        $adapter   = $this->_getReadAdapter();
+        $select     = $adapter->select()
+            ->from($this->getMainTable(), array('user_id'))
+            ->where('parent_id = ?', $role->getId())
+            ->where('role_type = ?', Mage_Api_Model_Acl::ROLE_TYPE_USER)
+            ->where('user_id > 0');
+        return $adapter->fetchCol($select);
+    }
+
+    /**
+     * Update role users
+     *
+     * @param Mage_Api_Model_Roles $role
+     * @return boolean
+     */
+    private function _updateRoleUsersAcl(Mage_Api_Model_Roles $role)
+    {
+        $users  = $this->getRoleUsers($role);
+        $rowsCount = 0;
+        if (sizeof($users) > 0) {
+            $rowsCount = $this->_getWriteAdapter()->update(
+                $this->_usersTable,
+                array('reload_acl_flag' => 1),
+                array('user_id IN(?)' => $users));
+        }
+        return ($rowsCount > 0) ? true : false;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Roles/Collection.php b/app/code/core/Mage/Api/Model/Resource/Roles/Collection.php
new file mode 100755
index 00000000000..b302d527928
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Roles/Collection.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Api Roles Resource Collection
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Roles_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    /**
+     * Resource collection initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Role', 'Mage_Api_Model_Resource_Role');
+    }
+
+    /**
+     * Convert items array to array for select options
+     *
+     * @return array
+     */
+    public function toOptionArray()
+    {
+        return $this->_toOptionArray('role_id', 'role_name');
+    }
+
+    /**
+     * Init collection select
+     *
+     * @return Mage_Api_Model_Resource_Roles_Collection
+     */
+    protected function _initSelect()
+    {
+        parent::_initSelect();
+        $this->getSelect()->where('main_table.role_type = ?', Mage_Api_Model_Acl::ROLE_TYPE_GROUP);
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Roles/User/Collection.php b/app/code/core/Mage/Api/Model/Resource/Roles/User/Collection.php
new file mode 100755
index 00000000000..9349e9a6b9a
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Roles/User/Collection.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Roles User Resource Collection
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Roles_User_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    /**
+     * Resource collection initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_User', 'Mage_Api_Model_Resource_User');
+    }
+
+    /**
+     * Init collection select
+     *
+     * @return Mage_Api_Model_Resource_Roles_User_Collection
+     */
+    protected function _initSelect()
+    {
+        parent::_initSelect();
+
+        $this->getSelect()->where("user_id > 0");
+
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Rules.php b/app/code/core/Mage/Api/Model/Resource/Rules.php
new file mode 100755
index 00000000000..7756864fe32
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Rules.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Rules resource model
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Rules extends Mage_Core_Model_Resource_Db_Abstract
+{
+    /**
+     * Resource initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('api_rule', 'rule_id');
+    }
+
+    /**
+     * Save rule
+     *
+     * @param Mage_Api_Model_Rules $rule
+     */
+    public function saveRel(Mage_Api_Model_Rules $rule)
+    {
+        $adapter = $this->_getWriteAdapter();
+        $adapter->beginTransaction();
+
+        try {
+            $roleId = $rule->getRoleId();
+            $adapter->delete($this->getMainTable(), array('role_id = ?' => $roleId));
+            $masterResources = Mage::getModel('Mage_Api_Model_Roles')->getResourcesList2D();
+            $masterAdmin = false;
+            if ($postedResources = $rule->getResources()) {
+                foreach ($masterResources as $index => $resName) {
+                    if (!$masterAdmin) {
+                        $permission = (in_array($resName, $postedResources))? 'allow' : 'deny';
+                        $adapter->insert($this->getMainTable(), array(
+                            'role_type'     => 'G',
+                            'resource_id'   => trim($resName, '/'),
+                            'api_privileges'    => null,
+                            'assert_id'     => 0,
+                            'role_id'       => $roleId,
+                            'api_permission'    => $permission
+                            ));
+                    }
+                    if ($resName == 'all' && $permission == 'allow') {
+                        $masterAdmin = true;
+                    }
+                }
+            }
+
+            $adapter->commit();
+        } catch (Mage_Core_Exception $e) {
+            throw $e;
+        } catch (Exception $e) {
+            $adapter->rollBack();
+        }
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/Rules/Collection.php b/app/code/core/Mage/Api/Model/Resource/Rules/Collection.php
new file mode 100755
index 00000000000..9c13b1f73ea
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/Rules/Collection.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Api Rules Resource Collection
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_Rules_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    /**
+     * Resource collection initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Rules', 'Mage_Api_Model_Resource_Rules');
+    }
+
+    /**
+     * Retrieve rules by role
+     *
+     * @param int $id
+     * @return Mage_Api_Model_Resource_Rules_Collection
+     */
+    public function getByRoles($id)
+    {
+        $this->getSelect()->where("role_id = ?", (int)$id);
+        return $this;
+    }
+
+    /**
+     * Add sort by length
+     *
+     * @return Mage_Api_Model_Resource_Rules_Collection
+     */
+    public function addSortByLength()
+    {
+        $this->getSelect()->columns(array('length' => $this->getConnection()->getLengthSql('resource_id')))
+            ->order('length DESC');
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/User.php b/app/code/core/Mage/Api/Model/Resource/User.php
new file mode 100755
index 00000000000..811d1cce262
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/User.php
@@ -0,0 +1,435 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * ACL user resource
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_User extends Mage_Core_Model_Resource_Db_Abstract
+{
+    /**
+     * Resource initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('api_user', 'user_id');
+    }
+
+    /**
+     * Initialize unique fields
+     *
+     * @return Mage_Api_Model_Resource_User
+     */
+    protected function _initUniqueFields()
+    {
+        $this->_uniqueFields = array(
+            array(
+                'field' => 'email',
+                'title' => Mage::helper('Mage_Api_Helper_Data')->__('Email')
+            ),
+            array(
+                'field' => 'username',
+                'title' => Mage::helper('Mage_Api_Helper_Data')->__('User Name')
+            ),
+        );
+        return $this;
+    }
+
+    /**
+     * Authenticate user by $username and $password
+     *
+     * @param Mage_Api_Model_User $user
+     * @return Mage_Api_Model_Resource_User
+     */
+    public function recordLogin(Mage_Api_Model_User $user)
+    {
+        $data = array(
+            'lognum'  => $user->getLognum()+1,
+        );
+        $condition = $this->_getReadAdapter()->quoteInto('user_id=?', $user->getUserId());
+        $this->_getWriteAdapter()->update($this->getTable('api_user'), $data, $condition);
+        return $this;
+    }
+
+    /**
+     * Record api user session
+     *
+     * @param Mage_Api_Model_User $user
+     * @return Mage_Api_Model_Resource_User
+     */
+    public function recordSession(Mage_Api_Model_User $user)
+    {
+        $readAdapter    = $this->_getReadAdapter();
+        $writeAdapter   = $this->_getWriteAdapter();
+        $select = $readAdapter->select()
+            ->from($this->getTable('api_session'), 'user_id')
+            ->where('user_id = ?', $user->getId())
+            ->where('sessid = ?', $user->getSessid());
+        $loginDate = now();
+        if ($readAdapter->fetchRow($select)) {
+            $writeAdapter->update(
+                $this->getTable('api_session'),
+                array ('logdate' => $loginDate),
+                $readAdapter->quoteInto('user_id = ?', $user->getId()) . ' AND '
+                . $readAdapter->quoteInto('sessid = ?', $user->getSessid())
+            );
+        } else {
+            $writeAdapter->insert(
+                $this->getTable('api_session'),
+                array(
+                    'user_id' => $user->getId(),
+                    'logdate' => $loginDate,
+                    'sessid' => $user->getSessid()
+                )
+            );
+        }
+        $user->setLogdate($loginDate);
+        return $this;
+    }
+
+    /**
+     * Clean old session
+     *
+     * @param Mage_Api_Model_User $user
+     * @return Mage_Api_Model_Resource_User
+     */
+    public function cleanOldSessions(Mage_Api_Model_User $user)
+    {
+        $readAdapter    = $this->_getReadAdapter();
+        $writeAdapter   = $this->_getWriteAdapter();
+        $timeout        = Mage::getStoreConfig('api/config/session_timeout');
+        $timeSubtract     = $readAdapter->getDateAddSql(
+            'logdate',
+            $timeout,
+            Varien_Db_Adapter_Interface::INTERVAL_SECOND);
+        $writeAdapter->delete(
+            $this->getTable('api_session'),
+            array('user_id = ?' => $user->getId(), $readAdapter->quote(now()) . ' > '.$timeSubtract)
+        );
+        return $this;
+    }
+
+    /**
+     * Load data by username
+     *
+     * @param string $username
+     * @return array
+     */
+    public function loadByUsername($username)
+    {
+        $adapter = $this->_getReadAdapter();
+        $select = $adapter->select()->from($this->getTable('api_user'))
+            ->where('username=:username');
+        return $adapter->fetchRow($select, array('username'=>$username));
+    }
+
+    /**
+     * load by session id
+     *
+     * @param string $sessId
+     * @return array
+     */
+    public function loadBySessId($sessId)
+    {
+        $result = array();
+        $adapter = $this->_getReadAdapter();
+        $select = $adapter->select()
+            ->from($this->getTable('api_session'))
+            ->where('sessid = ?', $sessId);
+        if ($apiSession = $adapter->fetchRow($select)) {
+            $selectUser = $adapter->select()
+                ->from($this->getTable('api_user'))
+                ->where('user_id = ?', $apiSession['user_id']);
+                if ($user = $adapter->fetchRow($selectUser)) {
+                    $result = array_merge($user, $apiSession);
+                }
+        }
+        return $result;
+    }
+
+    /**
+     * Clear by session
+     *
+     * @param string $sessid
+     * @return Mage_Api_Model_Resource_User
+     */
+    public function clearBySessId($sessid)
+    {
+        $this->_getWriteAdapter()->delete(
+            $this->getTable('api_session'),
+            array('sessid = ?' => $sessid)
+        );
+        return $this;
+    }
+
+    /**
+     * Retrieve api user role data if it was assigned to role
+     *
+     * @param int | Mage_Api_Model_User $user
+     * @return null | array
+     */
+    public function hasAssigned2Role($user)
+    {
+        $userId = null;
+        $result = null;
+        if (is_numeric($user)) {
+            $userId = $user;
+        } else if ($user instanceof Mage_Core_Model_Abstract) {
+            $userId = $user->getUserId();
+        }
+
+        if ($userId) {
+            $adapter = $this->_getReadAdapter();
+            $select = $adapter->select();
+            $select->from($this->getTable('api_role'))
+                ->where('parent_id > 0 AND user_id = ?', $userId);
+            $result = $adapter->fetchAll($select);
+        }
+        return $result;
+    }
+
+    /**
+     * Action before save
+     *
+     * @param Mage_Core_Model_Abstract $user
+     * @return Mage_Api_Model_Resource_User
+     */
+    protected function _beforeSave(Mage_Core_Model_Abstract $user)
+    {
+        if (!$user->getId()) {
+            $user->setCreated(now());
+        }
+        $user->setModified(now());
+        return $this;
+    }
+
+    /**
+     * Delete the object
+     *
+     * @param Mage_Core_Model_Abstract $user
+     * @return boolean
+     */
+    public function delete(Mage_Core_Model_Abstract $user)
+    {
+        $dbh = $this->_getWriteAdapter();
+        $uid = (int) $user->getId();
+        $dbh->beginTransaction();
+        try {
+            $dbh->delete($this->getTable('api_user'), array('user_id = ?' => $uid));
+            $dbh->delete($this->getTable('api_role'), array('user_id = ?' => $uid));
+        } catch (Mage_Core_Exception $e) {
+            throw $e;
+            return false;
+        } catch (Exception $e) {
+            $dbh->rollBack();
+            return false;
+        }
+        $dbh->commit();
+        return true;
+    }
+
+    /**
+     * Save user roles
+     *
+     * @param Mage_Core_Model_Abstract $user
+     * @return unknown
+     */
+    public function _saveRelations(Mage_Core_Model_Abstract $user)
+    {
+        $rolesIds = $user->getRoleIds();
+        if (!is_array($rolesIds) || count($rolesIds) == 0) {
+            return $user;
+        }
+
+        $adapter = $this->_getWriteAdapter();
+
+        $adapter->beginTransaction();
+
+        try {
+            $adapter->delete(
+                $this->getTable('api_role'),
+                array('user_id = ?' => (int) $user->getId()));
+            foreach ($rolesIds as $rid) {
+                $rid = intval($rid);
+                if ($rid > 0) {
+                    //$row = $this->load($user, $rid);
+                } else {
+                    $row = array('tree_level' => 0);
+                }
+                $row = array('tree_level' => 0);
+
+                $data = array(
+                    'parent_id'     => $rid,
+                    'tree_level'    => $row['tree_level'] + 1,
+                    'sort_order'    => 0,
+                    'role_type'     => Mage_Api_Model_Acl::ROLE_TYPE_USER,
+                    'user_id'       => $user->getId(),
+                    'role_name'     => $user->getFirstname()
+                );
+                $adapter->insert($this->getTable('api_role'), $data);
+            }
+            $adapter->commit();
+        } catch (Mage_Core_Exception $e) {
+            throw $e;
+        } catch (Exception $e) {
+            $adapter->rollBack();
+        }
+        return $this;
+    }
+
+    /**
+     * Retrieve roles data
+     *
+     * @param Mage_Core_Model_Abstract $user
+     * @return array
+     */
+    public function _getRoles(Mage_Core_Model_Abstract $user)
+    {
+        if (!$user->getId()) {
+            return array();
+        }
+        $table   = $this->getTable('api_role');
+        $adapter = $this->_getReadAdapter();
+        $select  = $adapter->select()
+            ->from($table, array())
+            ->joinLeft(
+                array('ar' => $table),
+                $adapter->quoteInto(
+                    "ar.role_id = {$table}.parent_id AND ar.role_type = ?",
+                    Mage_Api_Model_Acl::ROLE_TYPE_GROUP),
+                array('role_id'))
+            ->where("{$table}.user_id = ?", $user->getId());
+
+        return (($roles = $adapter->fetchCol($select)) ? $roles : array());
+    }
+
+    /**
+     * Add Role
+     *
+     * @param Mage_Core_Model_Abstract $user
+     * @return Mage_Api_Model_Resource_User
+     */
+    public function add(Mage_Core_Model_Abstract $user)
+    {
+        $adapter = $this->_getWriteAdapter();
+        $aRoles  = $this->hasAssigned2Role($user);
+        if (sizeof($aRoles) > 0) {
+            foreach ($aRoles as $idx => $data) {
+                $adapter->delete(
+                    $this->getTable('api_role'),
+                    array('role_id = ?' => $data['role_id'])
+                );
+            }
+        }
+
+        if ($user->getId() > 0) {
+            $role = Mage::getModel('Mage_Api_Model_Role')->load($user->getRoleId());
+        } else {
+            $role = new Varien_Object(array('tree_level' => 0));
+        }
+        $adapter->insert($this->getTable('api_role'), array(
+            'parent_id' => $user->getRoleId(),
+            'tree_level'=> ($role->getTreeLevel() + 1),
+            'sort_order'=> 0,
+            'role_type' => Mage_Api_Model_Acl::ROLE_TYPE_USER,
+            'user_id'   => $user->getUserId(),
+            'role_name' => $user->getFirstname()
+        ));
+
+        return $this;
+    }
+
+    /**
+     * Delete from role
+     *
+     * @param Mage_Core_Model_Abstract $user
+     * @return Mage_Api_Model_Resource_User
+     */
+    public function deleteFromRole(Mage_Core_Model_Abstract $user)
+    {
+        if ($user->getUserId() <= 0) {
+            return $this;
+        }
+        if ($user->getRoleId() <= 0) {
+            return $this;
+        };
+
+        $adapter   = $this->_getWriteAdapter();
+        $table     = $this->getTable('api_role');
+
+        $condition = array(
+            "{$table}.user_id = ?"  => $user->getUserId(),
+            "{$table}.parent_id = ?"=> $user->getRoleId()
+        );
+        $adapter->delete($table, $condition);
+        return $this;
+    }
+
+    /**
+     * Retrieve roles which exists for user
+     *
+     * @param Mage_Core_Model_Abstract $user
+     * @return array
+     */
+    public function roleUserExists(Mage_Core_Model_Abstract $user)
+    {
+        $result = array();
+        if ($user->getUserId() > 0) {
+            $adapter    = $this->_getReadAdapter();
+            $select     = $adapter->select()->from($this->getTable('api_role'))
+                ->where('parent_id = ?', $user->getRoleId())
+                ->where('user_id = ?', $user->getUserId());
+            $result = $adapter->fetchCol($select);
+        }
+        return $result;
+    }
+
+    /**
+     * Check if user not unique
+     *
+     * @param Mage_Core_Model_Abstract $user
+     * @return array
+     */
+    public function userExists(Mage_Core_Model_Abstract $user)
+    {
+        $usersTable = $this->getTable('api_user');
+        $adapter    = $this->_getReadAdapter();
+        $condition  = array(
+            $adapter->quoteInto("{$usersTable}.username = ?", $user->getUsername()),
+            $adapter->quoteInto("{$usersTable}.email = ?", $user->getEmail()),
+        );
+        $select = $adapter->select()
+            ->from($usersTable)
+            ->where(implode(' OR ', $condition))
+            ->where($usersTable.'.user_id != ?', (int) $user->getId());
+        return $adapter->fetchRow($select);
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Resource/User/Collection.php b/app/code/core/Mage/Api/Model/Resource/User/Collection.php
new file mode 100755
index 00000000000..50459268f5e
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Resource/User/Collection.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Api User Resource Collection
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Resource_User_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    /**
+     * Resource collection initialization
+     *
+     */
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_User', 'Mage_Api_Model_Resource_User');
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Role.php b/app/code/core/Mage/Api/Model/Role.php
new file mode 100644
index 00000000000..7363ffc260e
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Role.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Role item model
+ *
+ * @method Mage_Api_Model_Resource_Role _getResource()
+ * @method Mage_Api_Model_Resource_Role getResource()
+ * @method int getParentId()
+ * @method Mage_Api_Model_Role setParentId(int $value)
+ * @method int getTreeLevel()
+ * @method Mage_Api_Model_Role setTreeLevel(int $value)
+ * @method int getSortOrder()
+ * @method Mage_Api_Model_Role setSortOrder(int $value)
+ * @method string getRoleType()
+ * @method Mage_Api_Model_Role setRoleType(string $value)
+ * @method int getUserId()
+ * @method Mage_Api_Model_Role setUserId(int $value)
+ * @method string getRoleName()
+ * @method Mage_Api_Model_Role setRoleName(string $value)
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Role extends Mage_Core_Model_Abstract
+{
+    /**
+     * Initialize resource
+     */
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Resource_Role');
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Roles.php b/app/code/core/Mage/Api/Model/Roles.php
new file mode 100644
index 00000000000..6af4054c984
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Roles.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Enter description here ...
+ *
+ * @method Mage_Api_Model_Resource_Roles _getResource()
+ * @method Mage_Api_Model_Resource_Roles getResource()
+ * @method int getParentId()
+ * @method Mage_Api_Model_Roles setParentId(int $value)
+ * @method int getTreeLevel()
+ * @method Mage_Api_Model_Roles setTreeLevel(int $value)
+ * @method int getSortOrder()
+ * @method Mage_Api_Model_Roles setSortOrder(int $value)
+ * @method string getRoleType()
+ * @method Mage_Api_Model_Roles setRoleType(string $value)
+ * @method int getUserId()
+ * @method Mage_Api_Model_Roles setUserId(int $value)
+ * @method string getRoleName()
+ * @method Mage_Api_Model_Roles setRoleName(string $value)
+ * @method string getName()
+ * @method Mage_Api_Model_Role setName() setName(string $name)
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Roles extends Mage_Core_Model_Abstract
+{
+    /**
+     * Filters
+     *
+     * @var array
+     */
+    protected $_filters;
+
+
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Resource_Roles');
+    }
+
+    public function update()
+    {
+        $this->getResource()->update($this);
+        return $this;
+    }
+
+    public function getUsersCollection()
+    {
+        return Mage::getResourceModel('Mage_Api_Model_Resource_Roles_User_Collection');
+    }
+
+    public function getResourcesTree()
+    {
+        return $this->_buildResourcesArray(null, null, null, null, true);
+    }
+
+    public function getResourcesList()
+    {
+        return $this->_buildResourcesArray();
+    }
+
+    public function getResourcesList2D()
+    {
+        return $this->_buildResourcesArray(null, null, null, true);
+    }
+
+    public function getRoleUsers()
+    {
+        return $this->getResource()->getRoleUsers($this);
+    }
+
+    protected function _buildResourcesArray(
+        Varien_Simplexml_Element $resource = null, $parentName = null, $level = 0, $represent2Darray = null,
+        $rawNodes = false, $module = 'Mage_Adminhtml'
+    ) {
+        static $result;
+
+        if (is_null($resource)) {
+            $resource = Mage::getSingleton('Mage_Api_Model_Config')->getNode('acl/resources');
+            $resourceName = null;
+            $level = -1;
+        } else {
+            $resourceName = $parentName;
+            if ($resource->getName()!='title' && $resource->getName()!='sort_order'
+                && $resource->getName() != 'children'
+            ) {
+                $resourceName = (is_null($parentName) ? '' : $parentName.'/').$resource->getName();
+
+                //assigning module for its' children nodes
+                if ($resource->getAttribute('module')) {
+                    $module = (string)$resource->getAttribute('module');
+                }
+
+                if ($rawNodes) {
+                    $resource->addAttribute("aclpath", $resourceName);
+                }
+
+                $resource->title = Mage::helper($module)->__((string)$resource->title);
+
+                if ( is_null($represent2Darray) ) {
+                    $result[$resourceName]['name']  = (string)$resource->title;
+                    $result[$resourceName]['level'] = $level;
+                } else {
+                    $result[] = $resourceName;
+                }
+            }
+        }
+
+        $children = $resource->children();
+        if (empty($children)) {
+            if ($rawNodes) {
+                return $resource;
+            } else {
+                return $result;
+            }
+        }
+        foreach ($children as $child) {
+            $this->_buildResourcesArray($child, $resourceName, $level+1, $represent2Darray, $rawNodes, $module);
+        }
+        if ($rawNodes) {
+            return $resource;
+        } else {
+            return $result;
+        }
+    }
+
+    /**
+     * Filter data before save
+     *
+     * @return Mage_Api_Model_Roles
+     */
+    protected function _beforeSave()
+    {
+        $this->filter();
+        parent::_beforeSave();
+        return $this;
+    }
+
+    /**
+     * Filter set data
+     *
+     * @return Mage_Api_Model_Roles
+     */
+    public function filter()
+    {
+        $data = $this->getData();
+        if (!$this->_filters || !$data) {
+            return $this;
+        }
+        /** @var $filter Mage_Core_Model_Input_Filter */
+        $filter = Mage::getModel('Mage_Core_Model_Input_Filter');
+        $filter->setFilters($this->_filters);
+        $this->setData($filter->filter($data));
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Rules.php b/app/code/core/Mage/Api/Model/Rules.php
new file mode 100644
index 00000000000..fd3f412e84e
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Rules.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Enter description here ...
+ *
+ * @method Mage_Api_Model_Resource_Rules _getResource()
+ * @method Mage_Api_Model_Resource_Rules getResource()
+ * @method int getRoleId()
+ * @method Mage_Api_Model_Rules setRoleId(int $value)
+ * @method string getResourceId()
+ * @method Mage_Api_Model_Rules setResourceId(string $value)
+ * @method string getPrivileges()
+ * @method Mage_Api_Model_Rules setPrivileges(string $value)
+ * @method int getAssertId()
+ * @method Mage_Api_Model_Rules setAssertId(int $value)
+ * @method string getRoleType()
+ * @method Mage_Api_Model_Rules setRoleType(string $value)
+ * @method string getPermission()
+ * @method Mage_Api_Model_Rules setPermission(string $value)
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Rules extends Mage_Core_Model_Abstract
+{
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Resource_Rules');
+    }
+
+    public function update() {
+        $this->getResource()->update($this);
+        return $this;
+    }
+
+    public function getCollection() {
+        return Mage::getResourceModel('Mage_Api_Model_Resource_Permissions_Collection');
+    }
+
+    public function saveRel() {
+        $this->getResource()->saveRel($this);
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Server.php b/app/code/core/Mage/Api/Model/Server.php
new file mode 100644
index 00000000000..b3859b94d1e
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Server.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Webservice api abstract
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Server
+{
+
+    /**
+     * Api Name by Adapter
+     * @var string
+     */
+    protected $_api = "";
+
+    /**
+     * Web service adapter
+     *
+     * @var Mage_Api_Model_Server_Adapter_Soap
+     */
+    protected $_adapter;
+
+    /**
+     * Complex retrieve adapter code by calling auxiliary model method
+     *
+     * @param string $alias Alias name
+     * @return string|null Returns NULL if no alias found
+     */
+    public function getAdapterCodeByAlias($alias)
+    {
+        /** @var $config Mage_Api_Model_Config */
+        $config  = Mage::getSingleton('Mage_Api_Model_Config');
+        $aliases = $config->getAdapterAliases();
+
+        if (!isset($aliases[$alias])) {
+            return null;
+        }
+        $object = Mage::getModel($aliases[$alias][0]);
+        $method = $aliases[$alias][1];
+
+        if (!method_exists($object, $method)) {
+            Mage::throwException(Mage::helper('Mage_Api_Helper_Data')->__('Can not find webservice adapter.'));
+        }
+        return $object->$method();
+    }
+
+    /**
+     * Initialize server components
+     *
+     * @param Mage_Api_Controller_Action $controller
+     * @param string $adapter Adapter name
+     * @param string $handler Handler name
+     * @return Mage_Api_Model_Server
+     */
+    public function init(Mage_Api_Controller_Action $controller, $adapter = 'default', $handler = 'default')
+    {
+        $this->initialize($adapter, $handler);
+
+        $this->_adapter->setController($controller);
+
+        return $this;
+    }
+
+    /**
+     * Initialize server components. Lightweight implementation of init() method
+     *
+     * @param string $adapterCode Adapter code
+     * @param string $handler OPTIONAL Handler name (if not specified, it will be found from config)
+     * @return Mage_Api_Model_Server
+     */
+    public function initialize($adapterCode, $handler = null)
+    {
+        /** @var $helper Mage_Api_Model_Config */
+        $helper   = Mage::getSingleton('Mage_Api_Model_Config');
+        $adapters = $helper->getActiveAdapters();
+
+        if (isset($adapters[$adapterCode])) {
+            /** @var $adapterModel Mage_Api_Model_Server_Adapter_Soap */
+            $adapterModel = Mage::getModel((string) $adapters[$adapterCode]->model);
+
+            if (!($adapterModel instanceof Mage_Api_Model_Server_Adapter_Soap)) {
+                Mage::throwException(Mage::helper('Mage_Api_Helper_Data')->__('Invalid webservice adapter specified.'));
+            }
+            $this->_adapter = $adapterModel;
+            $this->_api     = $adapterCode;
+
+            // get handler code from config if no handler passed as argument
+            if (null === $handler && !empty($adapters[$adapterCode]->handler)) {
+                $handler = (string) $adapters[$adapterCode]->handler;
+            }
+            $handlers = $helper->getHandlers();
+
+            if (!isset($handlers->$handler)) {
+                Mage::throwException(Mage::helper('Mage_Api_Helper_Data')->__('Invalid webservice handler specified.'));
+            }
+            $handlerClassName = Mage::getConfig()->getModelClassName((string) $handlers->$handler->model);
+
+            $this->_adapter->setHandler($handlerClassName);
+        } else {
+            Mage::throwException(Mage::helper('Mage_Api_Helper_Data')->__('Invalid webservice adapter specified.'));
+        }
+        return $this;
+    }
+
+    /**
+     * Run server
+     *
+     */
+    public function run()
+    {
+        $this->getAdapter()->run();
+    }
+
+    /**
+     * Get Api name by Adapter
+     * @return string
+     */
+    public function getApiName()
+    {
+        return $this->_api;
+    }
+
+    /**
+     * Retrieve web service adapter
+     *
+     * @return Mage_Api_Model_Server_Adapter_Soap
+     */
+    public function getAdapter()
+    {
+        return $this->_adapter;
+    }
+
+
+} // Class Mage_Api_Model_Server_Abstract End
diff --git a/app/code/core/Mage/Api/Model/Server/Adapter/Soap.php b/app/code/core/Mage/Api/Model/Server/Adapter/Soap.php
new file mode 100644
index 00000000000..58649ff834f
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Server/Adapter/Soap.php
@@ -0,0 +1,241 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * SOAP adapter.
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Server_Adapter_Soap extends Varien_Object
+{
+    /**
+     * Soap server
+     *
+     * @var SoapServer
+     */
+    protected $_soap = null;
+
+    /**
+     * Set handler class name for webservice
+     *
+     * @param string $handler
+     * @return Mage_Api_Model_Server_Adapter_Soap
+     */
+    public function setHandler($handler)
+    {
+        $this->setData('handler', $handler);
+        return $this;
+    }
+
+    /**
+     * Retrive handler class name for webservice
+     *
+     * @return string
+     */
+    public function getHandler()
+    {
+        return $this->getData('handler');
+    }
+
+    /**
+     * Set webservice api controller
+     *
+     * @param Mage_Api_Controller_Action $controller
+     * @return Mage_Api_Model_Server_Adapter_Soap
+     */
+    public function setController(Mage_Api_Controller_Action $controller)
+    {
+        $this->setData('controller', $controller);
+        return $this;
+    }
+
+    /**
+     * Retrive webservice api controller. If no controller have been set - emulate it by the use of Varien_Object
+     *
+     * @return Mage_Api_Controller_Action|Varien_Object
+     */
+    public function getController()
+    {
+        $controller = $this->getData('controller');
+
+        if (null === $controller) {
+            $controller = new Varien_Object(
+                array('request' => Mage::app()->getRequest(), 'response' => Mage::app()->getResponse())
+            );
+
+            $this->setData('controller', $controller);
+        }
+        return $controller;
+    }
+
+    public function run()
+    {
+        $apiConfigCharset = Mage::getStoreConfig("api/config/charset");
+
+        if ($this->getController()->getRequest()->getParam('wsdl') !== null) {
+            $wsdlConfig = Mage::getModel('Mage_Api_Model_Wsdl_Config');
+            $wsdlConfig->setHandler($this->getHandler())
+                ->setCacheId('wsdl_config_global_soap')
+                ->init();
+            $this->getController()->getResponse()
+                ->clearHeaders()
+                ->setHeader('Content-Type', 'text/xml; charset=' . $apiConfigCharset)
+                ->setBody(
+                preg_replace(
+                    '/<\?xml version="([^\"]+)"([^\>]+)>/i',
+                    '<?xml version="$1" encoding="' . $apiConfigCharset . '"?>',
+                    $wsdlConfig->getWsdlContent()
+                )
+            );
+        } else {
+            try {
+                $this->_instantiateServer();
+
+                $this->getController()->getResponse()
+                    ->clearHeaders()
+                    ->setHeader('Content-Type', 'text/xml; charset=' . $apiConfigCharset)
+                    ->setBody(
+                    preg_replace(
+                        '/<\?xml version="([^\"]+)"([^\>]+)>/i',
+                        '<?xml version="$1" encoding="' . $apiConfigCharset . '"?>',
+                        $this->_soap->handle()
+                    )
+                );
+            } catch (Zend_Soap_Server_Exception $e) {
+                $this->fault($e->getCode(), $e->getMessage());
+            } catch (Exception $e) {
+                $this->fault($e->getCode(), $e->getMessage());
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Dispatch webservice fault
+     *
+     * @param int $code
+     * @param string $message
+     */
+    public function fault($code, $message)
+    {
+        if ($this->_extensionLoaded()) {
+            throw new SoapFault($code, $message);
+        } else {
+            die('<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
+                <SOAP-ENV:Body>
+                <SOAP-ENV:Fault>
+                <faultcode>' . $code . '</faultcode>
+                <faultstring>' . $message . '</faultstring>
+                </SOAP-ENV:Fault>
+                </SOAP-ENV:Body>
+                </SOAP-ENV:Envelope>');
+        }
+
+    }
+
+    /**
+     * Check whether Soap extension is loaded
+     *
+     * @return boolean
+     */
+    protected function _extensionLoaded()
+    {
+        return class_exists('SoapServer', false);
+    }
+
+    /**
+     * Transform wsdl url if $_SERVER["PHP_AUTH_USER"] is set
+     *
+     * @param array
+     * @return String
+     */
+    protected function getWsdlUrl($params = null, $withAuth = true)
+    {
+        $urlModel = Mage::getModel('Mage_Core_Model_Url')
+            ->setUseSession(false);
+
+        $wsdlUrl = $params !== null
+            ? $urlModel->getUrl('*/*/*', array('_current' => true, '_query' => $params))
+            : $urlModel->getUrl('*/*/*');
+
+        if ($withAuth) {
+            $phpAuthUser = urlencode($this->getController()->getRequest()->getServer('PHP_AUTH_USER', false));
+            $phpAuthPw = urlencode($this->getController()->getRequest()->getServer('PHP_AUTH_PW', false));
+
+            if ($phpAuthUser && $phpAuthPw) {
+                $wsdlUrl = sprintf("http://%s:%s@%s", $phpAuthUser, $phpAuthPw, str_replace('http://', '', $wsdlUrl));
+            }
+        }
+
+        return $wsdlUrl;
+    }
+
+    /**
+     * Try to instantiate Zend_Soap_Server
+     * If schema import error is caught, it will retry in 1 second.
+     *
+     * @throws Zend_Soap_Server_Exception
+     */
+    protected function _instantiateServer()
+    {
+        $apiConfigCharset = Mage::getStoreConfig('api/config/charset');
+        $wsdlCacheEnabled = (bool)Mage::getStoreConfig('api/config/wsdl_cache_enabled');
+
+        if ($wsdlCacheEnabled) {
+            ini_set('soap.wsdl_cache_enabled', '1');
+        } else {
+            ini_set('soap.wsdl_cache_enabled', '0');
+        }
+
+        $tries = 0;
+        do {
+            $retry = false;
+            try {
+                $this->_soap = new \Zend\Soap\Server($this->getWsdlUrl(array("wsdl" => 1)),
+                    array('encoding' => $apiConfigCharset));
+            } catch (SoapFault $e) {
+                if (false !== strpos(
+                    $e->getMessage(),
+                    "can't import schema from 'http://schemas.xmlsoap.org/soap/encoding/'"
+                )
+                ) {
+                    $retry = true;
+                    sleep(1);
+                } else {
+                    throw $e;
+                }
+                $tries++;
+            }
+        } while ($retry && $tries < 5);
+        use_soap_error_handler(false);
+        $this->_soap
+            ->setReturnResponse(true)
+            ->setClass($this->getHandler());
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Server/Adapter/Soap/Wsi.php b/app/code/core/Mage/Api/Model/Server/Adapter/Soap/Wsi.php
new file mode 100644
index 00000000000..d3d62dca236
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Server/Adapter/Soap/Wsi.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * SOAP WS-I compatible adapter
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Server_Adapter_Soap_Wsi extends Mage_Api_Model_Server_Adapter_Soap
+{
+    /**
+     * Run webservice
+     *
+     * @param Mage_Api_Controller_Action $controller
+     * @return Mage_Api_Model_Server_Adapter_Soap
+     */
+    public function run()
+    {
+        $apiConfigCharset = Mage::getStoreConfig("api/config/charset");
+
+        if ($this->getController()->getRequest()->getParam('wsdl') !== null) {
+            $wsdlConfig = Mage::getModel('Mage_Api_Model_Wsdl_Config');
+            $wsdlConfig->setHandler($this->getHandler())
+                ->setCacheId('wsdl_config_global_soap_wsi')
+                ->init();
+            $this->getController()->getResponse()
+                ->clearHeaders()
+                ->setHeader('Content-Type', 'text/xml; charset=' . $apiConfigCharset)
+                ->setBody(
+                preg_replace(
+                    '/(\>\<)/i',
+                    ">\n<",
+                    str_replace(
+                        '<soap:operation soapAction=""></soap:operation>',
+                        "<soap:operation soapAction=\"\" />\n",
+                        str_replace(
+                            '<soap:body use="literal"></soap:body>',
+                            "<soap:body use=\"literal\" />\n",
+                            preg_replace(
+                                '/<\?xml version="([^\"]+)"([^\>]+)>/i',
+                                '<?xml version="$1" encoding="' . $apiConfigCharset . '"?>',
+                                $wsdlConfig->getWsdlContent()
+                            )
+                        )
+                    )
+                )
+            );
+        } else {
+            try {
+                $this->_instantiateServer();
+
+                $this->getController()->getResponse()
+                    ->clearHeaders()
+                    ->setHeader('Content-Type', 'text/xml; charset=' . $apiConfigCharset)
+                    ->setBody(
+                    str_replace(
+                        '<soap:operation soapAction=""></soap:operation>',
+                        "<soap:operation soapAction=\"\" />\n",
+                        str_replace(
+                            '<soap:body use="literal"></soap:body>',
+                            "<soap:body use=\"literal\" />\n",
+                            preg_replace(
+                                '/<\?xml version="([^\"]+)"([^\>]+)>/i',
+                                '<?xml version="$1" encoding="' . $apiConfigCharset . '"?>',
+                                $this->_soap->handle()
+                            )
+                        )
+                    )
+                );
+            } catch (Zend_Soap_Server_Exception $e) {
+                $this->fault($e->getCode(), $e->getMessage());
+            } catch (Exception $e) {
+                $this->fault($e->getCode(), $e->getMessage());
+            }
+        }
+
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Server/Handler/Soap.php b/app/code/core/Mage/Api/Model/Server/Handler/Soap.php
new file mode 100644
index 00000000000..376b016693e
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Server/Handler/Soap.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Webservices server handler v2
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Server_Handler_Soap extends Mage_Api_Model_Server_HandlerAbstract
+{
+    protected $_resourceSuffix = '_V2';
+
+    /**
+     * Interceptor for all interfaces
+     *
+     * @param string $function
+     * @param array $args
+     * @return mixed
+     */
+
+    public function __call($function, $args)
+    {
+        $sessionId = array_shift($args);
+        $apiKey = '';
+        $nodes = Mage::getSingleton('Mage_Api_Model_Config')->getNode('v2/resources_function_prefix')->children();
+        foreach ($nodes as $resource => $prefix) {
+            $prefix = $prefix->asArray();
+            if (false !== strpos($function, $prefix)) {
+                $method = substr($function, strlen($prefix));
+                $apiKey = $resource . '.' . strtolower($method[0]) . substr($method, 1);
+            }
+        }
+        return $this->_call($sessionId, $apiKey, $args);
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Server/Handler/Soap/Wsi.php b/app/code/core/Mage/Api/Model/Server/Handler/Soap/Wsi.php
new file mode 100644
index 00000000000..4cd286f41ea
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Server/Handler/Soap/Wsi.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Webservices server handler WSI
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Server_Handler_Soap_Wsi extends Mage_Api_Model_Server_HandlerAbstract
+{
+    protected $_resourceSuffix = '_V2';
+
+    /**
+     * Interceptor for all interfaces
+     *
+     * @param string $function
+     * @param array $args
+     */
+
+    public function __call($function, $args)
+    {
+        $args = $args[0];
+
+        /** @var Mage_Api_Helper_Data */
+        $helper = Mage::helper('Mage_Api_Helper_Data');
+
+        $helper->wsiArrayUnpacker($args);
+        $args = get_object_vars($args);
+
+        if (isset($args['sessionId'])) {
+            $sessionId = $args['sessionId'];
+            unset($args['sessionId']);
+        } else {
+            // Was left for backward compatibility.
+            $sessionId = array_shift($args);
+        }
+
+        $apiKey = '';
+        $nodes = Mage::getSingleton('Mage_Api_Model_Config')->getNode('v2/resources_function_prefix')->children();
+        foreach ($nodes as $resource => $prefix) {
+            $prefix = $prefix->asArray();
+            if (false !== strpos($function, $prefix)) {
+                $method = substr($function, strlen($prefix));
+                $apiKey = $resource . '.' . strtolower($method[0]) . substr($method, 1);
+            }
+        }
+
+        list($modelName, $methodName) = $this->_getResourceName($apiKey);
+        $methodParams = $this->getMethodParams($modelName, $methodName);
+
+        $args = $this->prepareArgs($methodParams, $args);
+
+        $res = $this->call($sessionId, $apiKey, $args);
+
+        $obj = $helper->wsiArrayPacker($res);
+        $stdObj = new stdClass();
+        $stdObj->result = $obj;
+
+        return $stdObj;
+    }
+
+    /**
+     * Login user and Retrieve session id
+     *
+     * @param string $username
+     * @param string $apiKey
+     * @return string
+     */
+    public function login($username, $apiKey = null)
+    {
+        if (is_object($username)) {
+            $apiKey = $username->apiKey;
+            $username = $username->username;
+        }
+
+        $stdObject = new stdClass();
+        $stdObject->result = parent::login($username, $apiKey);
+        return $stdObject;
+    }
+
+    /**
+     * Return called class and method names
+     *
+     * @param String $apiPath
+     * @return Array
+     */
+    protected function _getResourceName($apiPath)
+    {
+
+        list($resourceName, $methodName) = explode('.', $apiPath);
+
+        if (empty($resourceName) || empty($methodName)) {
+            return $this->_fault('resource_path_invalid');
+        }
+
+        $resourcesAlias = $this->_getConfig()->getResourcesAlias();
+        $resources = $this->_getConfig()->getResources();
+        if (isset($resourcesAlias->$resourceName)) {
+            $resourceName = (string)$resourcesAlias->$resourceName;
+        }
+
+        $methodInfo = $resources->$resourceName->methods->$methodName;
+
+        $modelName = $this->_prepareResourceModelName((string)$resources->$resourceName->model);
+
+        $modelClass = Mage::getConfig()->getModelClassName($modelName);
+
+        $method = (isset($methodInfo->method) ? (string)$methodInfo->method : $methodName);
+
+        return array($modelClass, $method);
+    }
+
+    /**
+     * Return an array of parameters for the callable method.
+     *
+     * @param String $modelName
+     * @param String $methodName
+     * @return Array of ReflectionParameter
+     */
+    public function getMethodParams($modelName, $methodName)
+    {
+
+        $method = new ReflectionMethod($modelName, $methodName);
+
+        return $method->getParameters();
+    }
+
+    /**
+     * Prepares arguments for the method calling. Sort in correct order, set default values for omitted parameters.
+     *
+     * @param Array $params
+     * @param Array $args
+     * @return Array
+     */
+    public function prepareArgs($params, $args)
+    {
+
+        $callArgs = array();
+
+        /** @var $parameter ReflectionParameter */
+        foreach ($params AS $parameter) {
+            $pName = $parameter->getName();
+            if (isset($args[$pName])) {
+                $callArgs[$pName] = $args[$pName];
+            } else {
+                if ($parameter->isOptional()) {
+                    $callArgs[$pName] = $parameter->getDefaultValue();
+                } else {
+                    Mage::logException(new Exception("Required parameter \"$pName\" is missing.", 0));
+                    $this->_fault('invalid_request_param');
+                }
+            }
+        }
+        return $callArgs;
+    }
+
+}
diff --git a/app/code/core/Mage/Api/Model/Server/HandlerAbstract.php b/app/code/core/Mage/Api/Model/Server/HandlerAbstract.php
new file mode 100644
index 00000000000..6552147c922
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Server/HandlerAbstract.php
@@ -0,0 +1,416 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Webservice default handler
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+abstract class Mage_Api_Model_Server_HandlerAbstract
+{
+    protected $_resourceSuffix = null;
+
+    public function __construct()
+    {
+        set_error_handler(array($this, 'handlePhpError'), E_ALL);
+        Mage::app()->loadAreaPart(Mage_Core_Model_App_Area::AREA_ADMIN, Mage_Core_Model_App_Area::PART_EVENTS);
+    }
+
+    public function handlePhpError($errorCode, $errorMessage, $errorFile)
+    {
+        Mage::log($errorMessage . $errorFile);
+        if (in_array($errorCode, array(E_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR))) {
+            $this->_fault('internal');
+        }
+        return true;
+    }
+
+
+    /**
+     * Retrive webservice session
+     *
+     * @return Mage_Api_Model_Session
+     */
+    protected function _getSession()
+    {
+        return Mage::getSingleton('Mage_Api_Model_Session');
+    }
+
+    /**
+     * Retrive webservice configuration
+     *
+     * @return Mage_Api_Model_Config
+     */
+    protected function _getConfig()
+    {
+        return Mage::getSingleton('Mage_Api_Model_Config');
+    }
+
+    /**
+     * Retrive webservice server
+     *
+     * @return Mage_Api_Model_Server
+     */
+    protected function _getServer()
+    {
+        return Mage::getSingleton('Mage_Api_Model_Server');
+    }
+
+    /**
+     * Start webservice session
+     *
+     * @param string $sessionId
+     * @return Mage_Api_Model_Server_HandlerAbstract
+     */
+    protected function _startSession($sessionId = null)
+    {
+        $this->_getSession()->setSessionId($sessionId);
+        $this->_getSession()->init('api', 'api');
+        return $this;
+    }
+
+    /**
+     * Check current user permission on resource and privilege
+     *
+     *
+     * @param   string $resource
+     * @param   string $privilege
+     * @return  bool
+     */
+    protected function _isAllowed($resource, $privilege = null)
+    {
+        return $this->_getSession()->isAllowed($resource, $privilege);
+    }
+
+    /**
+     * Dispatch webservice fault
+     *
+     * @param string $faultName
+     * @param string $resourceName
+     * @param string $customMessage
+     */
+    protected function _fault($faultName, $resourceName = null, $customMessage = null)
+    {
+        $faults = $this->_getConfig()->getFaults($resourceName);
+        if (!isset($faults[$faultName]) && !is_null($resourceName)) {
+            $this->_fault($faultName);
+            return;
+        } elseif (!isset($faults[$faultName])) {
+            $this->_fault('unknown');
+            return;
+        }
+        $this->_getServer()->getAdapter()->fault(
+            $faults[$faultName]['code'],
+            (is_null($customMessage) ? $faults[$faultName]['message'] : $customMessage)
+        );
+    }
+
+    /**
+     * Retrive webservice fault as array
+     *
+     * @param string $faultName
+     * @param string $resourceName
+     * @param string $customMessage
+     * @return array
+     */
+    protected function _faultAsArray($faultName, $resourceName = null, $customMessage = null)
+    {
+        $faults = $this->_getConfig()->getFaults($resourceName);
+        if (!isset($faults[$faultName]) && !is_null($resourceName)) {
+            return $this->_faultAsArray($faultName);
+        } elseif (!isset($faults[$faultName])) {
+            return $this->_faultAsArray('unknown');
+        }
+
+        return array(
+            'isFault' => true,
+            'faultCode' => $faults[$faultName]['code'],
+            'faultMessage' => (is_null($customMessage) ? $faults[$faultName]['message'] : $customMessage)
+        );
+    }
+
+    /**
+     * Start web service session
+     *
+     * @return string
+     */
+    public function startSession()
+    {
+        $this->_startSession();
+        return $this->_getSession()->getSessionId();
+    }
+
+
+    /**
+     * End web service session
+     *
+     * @param string $sessionId
+     * @return boolean
+     */
+    public function endSession($sessionId)
+    {
+        $this->_startSession($sessionId);
+        $this->_getSession()->clear();
+        return true;
+    }
+
+    /**
+     * Enter description here...
+     *
+     * @param string $resource
+     * @return string
+     */
+    protected function _prepareResourceModelName($resource)
+    {
+        if (null !== $this->_resourceSuffix) {
+            return $resource . $this->_resourceSuffix;
+        }
+        return $resource;
+    }
+
+    /**
+     * Login user and Retrieve session id
+     *
+     * @param string $username
+     * @param string $apiKey
+     * @return string
+     */
+    public function login($username, $apiKey = null)
+    {
+        if (empty($username) || empty($apiKey)) {
+            return $this->_fault('invalid_request_param');
+        }
+
+        try {
+            $this->_startSession();
+            $this->_getSession()->login($username, $apiKey);
+        } catch (Exception $e) {
+            return $this->_fault('access_denied');
+        }
+        return $this->_getSession()->getSessionId();
+    }
+
+    /**
+     * Call resource functionality
+     *
+     * @param string $sessionId
+     * @param string $apiPath
+     * @param array  $args
+     * @return mixed
+     * @throws Mage_Api_Exception
+     */
+    protected function _call($sessionId, $apiPath, $args = array())
+    {
+        $this->_startSession($sessionId);
+
+        if (!$this->_getSession()->isLoggedIn($sessionId)) {
+            return $this->_fault('session_expired');
+        }
+
+        list($resourceName, $methodName) = explode('.', $apiPath);
+
+        if (empty($resourceName) || empty($methodName)) {
+            return $this->_fault('resource_path_invalid');
+        }
+
+        $resourcesAlias = $this->_getConfig()->getResourcesAlias();
+        $resources = $this->_getConfig()->getResources();
+        if (isset($resourcesAlias->$resourceName)) {
+            $resourceName = (string)$resourcesAlias->$resourceName;
+        }
+
+        if (!isset($resources->$resourceName)
+            || !isset($resources->$resourceName->methods->$methodName)
+        ) {
+            return $this->_fault('resource_path_invalid');
+        }
+
+        if (!isset($resources->$resourceName->public)
+            && isset($resources->$resourceName->acl)
+            && !$this->_isAllowed((string)$resources->$resourceName->acl)
+        ) {
+            return $this->_fault('access_denied');
+
+        }
+
+
+        if (!isset($resources->$resourceName->methods->$methodName->public)
+            && isset($resources->$resourceName->methods->$methodName->acl)
+            && !$this->_isAllowed((string)$resources->$resourceName->methods->$methodName->acl)
+        ) {
+            return $this->_fault('access_denied');
+        }
+
+        $methodInfo = $resources->$resourceName->methods->$methodName;
+
+        try {
+            $method = (isset($methodInfo->method) ? (string)$methodInfo->method : $methodName);
+
+            $modelName = $this->_prepareResourceModelName((string)$resources->$resourceName->model);
+            try {
+                $model = Mage::getModel($modelName);
+                if ($model instanceof Mage_Api_Model_Resource_Abstract) {
+                    $model->setResourceConfig($resources->$resourceName);
+                }
+            } catch (Exception $e) {
+                throw new Mage_Api_Exception('resource_path_not_callable');
+            }
+
+            if (method_exists($model, $method)) {
+                if (isset($methodInfo->arguments) && ((string)$methodInfo->arguments) == 'array') {
+                    return $model->$method((is_array($args) ? $args : array($args)));
+                } elseif (!is_array($args)) {
+                    return $model->$method($args);
+                } else {
+                    return call_user_func_array(array(&$model, $method), $args);
+                }
+            } else {
+                throw new Mage_Api_Exception('resource_path_not_callable');
+            }
+        } catch (Mage_Api_Exception $e) {
+            return $this->_fault($e->getMessage(), $resourceName, $e->getCustomMessage());
+        } catch (Exception $e) {
+            Mage::logException($e);
+            return $this->_fault('internal', null, $e->getMessage());
+        }
+    }
+
+    /**
+     * List of available resources
+     *
+     * @param string $sessionId
+     * @return array
+     */
+    public function resources($sessionId)
+    {
+        $this->_startSession($sessionId);
+
+        if (!$this->_getSession()->isLoggedIn($sessionId)) {
+            return $this->_fault('session_expired');
+        }
+
+        $resources = array();
+
+        $resourcesAlias = array();
+        foreach ($this->_getConfig()->getResourcesAlias() as $alias => $resourceName) {
+            $resourcesAlias[(string)$resourceName][] = $alias;
+        }
+
+
+        foreach ($this->_getConfig()->getResources() as $resourceName => $resource) {
+            if (isset($resource->acl) && !$this->_isAllowed((string)$resource->acl)) {
+                continue;
+            }
+
+            $methods = array();
+            foreach ($resource->methods->children() as $methodName => $method) {
+                if (isset($method->acl) && !$this->_isAllowed((string)$method->acl)) {
+                    continue;
+                }
+                $methodAliases = array();
+                if (isset($resourcesAlias[$resourceName])) {
+                    foreach ($resourcesAlias[$resourceName] as $alias) {
+                        $methodAliases[] = $alias . '.' . $methodName;
+                    }
+                }
+
+                $methods[] = array(
+                    'title' => (string)$method->title,
+                    'description' => (isset($method->description) ? (string)$method->description : null),
+                    'path' => $resourceName . '.' . $methodName,
+                    'name' => $methodName,
+                    'aliases' => $methodAliases
+                );
+            }
+
+            if (count($methods) == 0) {
+                continue;
+            }
+
+            $resources[] = array(
+                'title' => (string)$resource->title,
+                'description' => (isset($resource->description) ? (string)$resource->description : null),
+                'name' => $resourceName,
+                'aliases' => (isset($resourcesAlias[$resourceName]) ? $resourcesAlias[$resourceName] : array()),
+                'methods' => $methods
+            );
+        }
+
+        return $resources;
+    }
+
+    /**
+     * List of resource faults
+     *
+     * @param string $sessionId
+     * @param string $resourceName
+     * @return array
+     */
+    public function resourceFaults($sessionId, $resourceName)
+    {
+        $this->_startSession($sessionId);
+
+        if (!$this->_getSession()->isLoggedIn($sessionId)) {
+            return $this->_fault('session_expired');
+        }
+
+        $resourcesAlias = $this->_getConfig()->getResourcesAlias();
+        $resources = $this->_getConfig()->getResources();
+
+        if (isset($resourcesAlias->$resourceName)) {
+            $resourceName = (string)$resourcesAlias->$resourceName;
+        }
+
+
+        if (empty($resourceName)
+            || !isset($resources->$resourceName)
+        ) {
+            return $this->_fault('resource_path_invalid');
+        }
+
+        if (isset($resources->$resourceName->acl)
+            && !$this->_isAllowed((string)$resources->$resourceName->acl)
+        ) {
+            return $this->_fault('access_denied');
+        }
+
+        return array_values($this->_getConfig()->getFaults($resourceName));
+    }
+
+    /**
+     * List of global faults
+     *
+     * @param  string $sessionId
+     * @return array
+     */
+    public function globalFaults($sessionId)
+    {
+        $this->_startSession($sessionId);
+        return array_values($this->_getConfig()->getFaults());
+    }
+} // Class Mage_Api_Model_Server_HandlerAbstract End
diff --git a/app/code/core/Mage/Api/Model/Session.php b/app/code/core/Mage/Api/Model/Session.php
new file mode 100644
index 00000000000..d9dfae0fe69
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Session.php
@@ -0,0 +1,207 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Webservice api session
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Session extends Mage_Core_Model_Session_Abstract
+{
+    public $sessionIds = array();
+    protected $_currentSessId = null;
+
+    public function start($sessionName=null)
+    {
+//        parent::start($sessionName=null);
+        $this->_currentSessId = md5(time() . uniqid('', true) . $sessionName);
+        $this->sessionIds[] = $this->getSessionId();
+        return $this;
+    }
+
+    public function init($namespace, $sessionName=null)
+    {
+        if (is_null($this->_currentSessId)) {
+            $this->start();
+        }
+        return $this;
+    }
+
+    public function getSessionId()
+    {
+        return $this->_currentSessId;
+    }
+
+    public function setSessionId($sessId = null)
+    {
+        if (!is_null($sessId)) {
+            $this->_currentSessId = $sessId;
+        }
+        return $this;
+    }
+
+    public function revalidateCookie()
+    {
+        // In api we don't use cookies
+    }
+
+    public function clear() {
+        if ($sessId = $this->getSessionId()) {
+            try {
+                Mage::getModel('Mage_Api_Model_User')->logoutBySessId($sessId);
+            } catch (Exception $e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public function login($username, $apiKey)
+    {
+        $user = Mage::getModel('Mage_Api_Model_User')
+            ->setSessid($this->getSessionId())
+            ->login($username, $apiKey);
+
+        if ( $user->getId() && $user->getIsActive() != '1' ) {
+            Mage::throwException(Mage::helper('Mage_Api_Helper_Data')->__('Your account has been deactivated.'));
+        } elseif (!Mage::getModel('Mage_Api_Model_User')->hasAssigned2Role($user->getId())) {
+            Mage::throwException(Mage::helper('Mage_Api_Helper_Data')->__('Access denied.'));
+        } else {
+            if ($user->getId()) {
+                $this->setUser($user);
+                $this->setAcl(Mage::getResourceModel('Mage_Api_Model_Resource_Acl')->loadAcl());
+            } else {
+                Mage::throwException(Mage::helper('Mage_Api_Helper_Data')->__('Unable to login.'));
+            }
+        }
+
+        return $user;
+    }
+
+    public function refreshAcl($user=null)
+    {
+        if (is_null($user)) {
+            $user = $this->getUser();
+        }
+        if (!$user) {
+            return $this;
+        }
+        if (!$this->getAcl() || $user->getReloadAclFlag()) {
+            $this->setAcl(Mage::getResourceModel('Mage_Api_Model_Resource_Acl')->loadAcl());
+        }
+        if ($user->getReloadAclFlag()) {
+            $user->unsetData('api_key');
+            $user->setReloadAclFlag('0')->save();
+        }
+        return $this;
+    }
+
+    /**
+     * Check current user permission on resource and privilege
+     *
+     *
+     * @param   string $resource
+     * @param   string $privilege
+     * @return  bool
+     */
+    public function isAllowed($resource, $privilege=null)
+    {
+        $user = $this->getUser();
+        $acl = $this->getAcl();
+
+        if ($user && $acl) {
+            try {
+                if ($acl->isAllowed($user->getAclRole(), 'all', null)){
+                    return true;
+                }
+            } catch (Exception $e) {}
+
+            try {
+                return $acl->isAllowed($user->getAclRole(), $resource, $privilege);
+            } catch (Exception $e) {
+                return false;
+            }
+        }
+        return false;
+    }
+
+    /**
+     *  Check session expiration
+     *
+     *  @return  boolean
+     */
+    public function isSessionExpired ($user)
+    {
+        if (!$user->getId()) {
+            return true;
+        }
+        $timeout = strtotime( now() ) - strtotime( $user->getLogdate() );
+        return $timeout > Mage::getStoreConfig('api/config/session_timeout');
+    }
+
+
+    public function isLoggedIn($sessId = false)
+    {
+        $userExists = $this->getUser() && $this->getUser()->getId();
+
+        if (!$userExists && $sessId !== false) {
+            return $this->_renewBySessId($sessId);
+        }
+
+        if ($userExists) {
+            Mage::register('isSecureArea', true, true);
+        }
+        return $userExists;
+    }
+
+    /**
+     *  Renew user by session ID if session not expired
+     *
+     *  @param    string $sessId
+     *  @return  boolean
+     */
+    protected function _renewBySessId ($sessId)
+    {
+        $user = Mage::getModel('Mage_Api_Model_User')->loadBySessId($sessId);
+        if (!$user->getId() || !$user->getSessid()) {
+            return false;
+        }
+
+        if ($user->getSessid() == $sessId && !$this->isSessionExpired($user)) {
+            $this->setUser($user);
+            $this->setAcl(Mage::getResourceModel('Mage_Api_Model_Resource_Acl')->loadAcl());
+
+            $user->getResource()->recordLogin($user)
+                ->recordSession($user);
+
+            return true;
+        }
+        return false;
+    }
+
+} // Class Mage_Api_Model_Session End
diff --git a/app/code/core/Mage/Api/Model/User.php b/app/code/core/Mage/Api/Model/User.php
new file mode 100644
index 00000000000..a3101d94f9f
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/User.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Enter description here ...
+ *
+ * @method Mage_Api_Model_Resource_User _getResource()
+ * @method Mage_Api_Model_Resource_User getResource()
+ * @method string getFirstname()
+ * @method Mage_Api_Model_User setFirstname(string $value)
+ * @method string getLastname()
+ * @method Mage_Api_Model_User setLastname(string $value)
+ * @method string getEmail()
+ * @method Mage_Api_Model_User setEmail(string $value)
+ * @method string getUsername()
+ * @method Mage_Api_Model_User setUsername(string $value)
+ * @method string getApiKey()
+ * @method Mage_Api_Model_User setApiKey(string $value)
+ * @method string getCreated()
+ * @method Mage_Api_Model_User setCreated(string $value)
+ * @method string getModified()
+ * @method Mage_Api_Model_User setModified(string $value)
+ * @method int getLognum()
+ * @method Mage_Api_Model_User setLognum(int $value)
+ * @method int getReloadAclFlag()
+ * @method Mage_Api_Model_User setReloadAclFlag(int $value)
+ * @method int getIsActive()
+ * @method Mage_Api_Model_User setIsActive(int $value)
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_User extends Mage_Core_Model_Abstract
+{
+    /**
+     * Prefix of model events names
+     *
+     * @var string
+     */
+    protected $_eventPrefix = 'api_user';
+
+    protected function _construct()
+    {
+        $this->_init('Mage_Api_Model_Resource_User');
+    }
+
+    public function save()
+    {
+        $this->_beforeSave();
+        $data = array(
+                'firstname' => $this->getFirstname(),
+                'lastname'  => $this->getLastname(),
+                'email'     => $this->getEmail(),
+                'modified'  => Mage::getSingleton('Mage_Core_Model_Date')->gmtDate()
+            );
+
+        if($this->getId() > 0) {
+            $data['user_id']   = $this->getId();
+        }
+
+        if( $this->getUsername() ) {
+            $data['username']   = $this->getUsername();
+        }
+
+        if ($this->getApiKey()) {
+            $data['api_key']   = $this->_getEncodedApiKey($this->getApiKey());
+        }
+
+        if ($this->getNewApiKey()) {
+            $data['api_key']   = $this->_getEncodedApiKey($this->getNewApiKey());
+        }
+
+        if ( !is_null($this->getIsActive()) ) {
+            $data['is_active']  = intval($this->getIsActive());
+        }
+
+        $this->setData($data);
+        $this->_getResource()->save($this);
+        $this->_afterSave();
+        return $this;
+    }
+
+    public function delete()
+    {
+        $this->_beforeDelete();
+        $this->_getResource()->delete($this);
+        $this->_afterDelete();
+        return $this;
+    }
+
+    public function saveRelations()
+    {
+        $this->_getResource()->_saveRelations($this);
+        return $this;
+    }
+
+    public function getRoles()
+    {
+        return $this->_getResource()->_getRoles($this);
+    }
+
+    public function deleteFromRole()
+    {
+        $this->_getResource()->deleteFromRole($this);
+        return $this;
+    }
+
+    public function roleUserExists()
+    {
+        $result = $this->_getResource()->roleUserExists($this);
+        return ( is_array($result) && count($result) > 0 ) ? true : false;
+    }
+
+    public function add()
+    {
+        $this->_getResource()->add($this);
+        return $this;
+    }
+
+    public function userExists()
+    {
+        $result = $this->_getResource()->userExists($this);
+        return ( is_array($result) && count($result) > 0 ) ? true : false;
+    }
+
+    public function getCollection() {
+        return Mage::getResourceModel('Mage_Api_Model_Resource_User_Collection');
+    }
+
+    public function getName($separator=' ')
+    {
+        return $this->getFirstname().$separator.$this->getLastname();
+    }
+
+    public function getId()
+    {
+        return $this->getUserId();
+    }
+
+    /**
+     * Get user ACL role
+     *
+     * @return string
+     */
+    public function getAclRole()
+    {
+        return 'U'.$this->getUserId();
+    }
+
+    /**
+     * Authenticate user name and api key and save loaded record
+     *
+     * @param string $username
+     * @param string $apiKey
+     * @return boolean
+     */
+    public function authenticate($username, $apiKey)
+    {
+        $this->loadByUsername($username);
+        if (!$this->getId()) {
+            return false;
+        }
+        $auth = Mage::helper('Mage_Core_Helper_Data')->validateHash($apiKey, $this->getApiKey());
+        if ($auth) {
+            return true;
+        } else {
+            $this->unsetData();
+            return false;
+        }
+    }
+
+    /**
+     * Login user
+     *
+     * @param   string $login
+     * @param   string $apiKey
+     * @return  Mage_Api_Model_User
+     */
+    public function login($username, $apiKey)
+    {
+        $sessId = $this->getSessid();
+        if ($this->authenticate($username, $apiKey)) {
+            $this->setSessid($sessId);
+            $this->getResource()->cleanOldSessions($this)
+                ->recordLogin($this)
+                ->recordSession($this);
+            Mage::dispatchEvent('api_user_authenticated', array(
+               'model'    => $this,
+               'api_key'  => $apiKey,
+            ));
+        }
+
+        return $this;
+    }
+
+    public function reload()
+    {
+        $this->load($this->getId());
+        return $this;
+    }
+
+    public function loadByUsername($username)
+    {
+        $this->setData($this->getResource()->loadByUsername($username));
+        return $this;
+    }
+
+    public function loadBySessId ($sessId)
+    {
+        $this->setData($this->getResource()->loadBySessId($sessId));
+        return $this;
+    }
+
+    public function logoutBySessId($sessid)
+    {
+        $this->getResource()->clearBySessId($sessid);
+        return $this;
+    }
+
+    public function hasAssigned2Role($user)
+    {
+        return $this->getResource()->hasAssigned2Role($user);
+    }
+
+    protected function _getEncodedApiKey($apiKey)
+    {
+        return Mage::helper('Mage_Core_Helper_Data')->getHash($apiKey, 2);
+    }
+
+}
diff --git a/app/code/core/Mage/Api/Model/Wsdl/Config.php b/app/code/core/Mage/Api/Model/Wsdl/Config.php
new file mode 100644
index 00000000000..b9a5e525cd2
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Wsdl/Config.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Wsdl config model
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Wsdl_Config extends Mage_Api_Model_Wsdl_Config_Base
+{
+    protected static $_namespacesPrefix = null;
+
+    public function __construct($sourceData = null)
+    {
+        $this->setCacheId('wsdl_config_global');
+        parent::__construct($sourceData);
+    }
+
+    /**
+     * Return wsdl content
+     *
+     * @return string
+     */
+    public function getWsdlContent()
+    {
+        return $this->_xml->asXML();
+    }
+
+    /**
+     * Return namespaces with their prefix
+     *
+     * @return array
+     */
+    public static function getNamespacesPrefix()
+    {
+        if (is_null(self::$_namespacesPrefix)) {
+            self::$_namespacesPrefix = array();
+            $config = Mage::getSingleton('Mage_Api_Model_Config')->getNode('v2/wsdl/prefix')->children();
+            foreach ($config as $prefix => $namespace) {
+                self::$_namespacesPrefix[$namespace->asArray()] = $prefix;
+            }
+        }
+        return self::$_namespacesPrefix;
+    }
+
+    public function getCache()
+    {
+        return Mage::app()->getCache();
+    }
+
+    protected function _loadCache($id)
+    {
+        return Mage::app()->loadCache($id);
+    }
+
+    protected function _saveCache($data, $id, $tags = array(), $lifetime = false)
+    {
+        return Mage::app()->saveCache($data, $id, $tags, $lifetime);
+    }
+
+    protected function _removeCache($id)
+    {
+        return Mage::app()->removeCache($id);
+    }
+
+    public function init()
+    {
+        $this->setCacheChecksum(null);
+        $saveCache = true;
+
+        if (Mage::app()->useCache('config')) {
+            $loaded = $this->loadCache();
+            if ($loaded) {
+                return $this;
+            }
+        }
+
+        $mergeWsdl = new Mage_Api_Model_Wsdl_Config_Base();
+        $mergeWsdl->setHandler($this->getHandler());
+
+        /** @var Mage_Api_Helper_Data $helper */
+        $helper = Mage::helper('Mage_Api_Helper_Data');
+        if ($helper->isWsiCompliant()) {
+            /**
+             * Exclude Mage_Api wsdl xml file because it used for previous version
+             * of API wsdl declaration
+             */
+            $mergeWsdl->addLoadedFile(Mage::getConfig()->getModuleDir('etc', "Mage_Api") . DS . 'wsi.xml');
+
+            $baseWsdlFile = Mage::getConfig()->getModuleDir('etc', "Mage_Api") . DS . 'wsi.xml';
+            $this->loadFile($baseWsdlFile);
+            Mage::getConfig()->loadModulesConfiguration('wsi.xml', $this, $mergeWsdl);
+        } else {
+            $baseWsdlFile = Mage::getConfig()->getModuleDir('etc', "Mage_Api") . DS . 'wsdl.xml';
+            $this->loadFile($baseWsdlFile);
+            Mage::getConfig()->loadModulesConfiguration('wsdl.xml', $this, $mergeWsdl);
+        }
+
+        if (Mage::app()->useCache('config')) {
+            $this->saveCache(array('config'));
+        }
+
+        return $this;
+    }
+
+    /**
+     * Return Xml of node as string
+     *
+     * @return string
+     */
+    public function getXmlString()
+    {
+        return $this->getNode()->asXML();
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Wsdl/Config/Base.php b/app/code/core/Mage/Api/Model/Wsdl/Config/Base.php
new file mode 100644
index 00000000000..3f251767854
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Wsdl/Config/Base.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Wsdl base config
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Model_Wsdl_Config_Base extends Varien_Simplexml_Config
+{
+    protected $_handler = '';
+
+    /**
+     * @var Varien_Object
+     */
+    protected $_wsdlVariables = null;
+
+    protected $_loadedFiles = array();
+
+    public function __construct($sourceData=null)
+    {
+        $this->_elementClass = 'Mage_Api_Model_Wsdl_Config_Element';
+
+        // remove wsdl parameter from query
+        $queryParams = Mage::app()->getRequest()->getQuery();
+        unset($queryParams['wsdl']);
+
+        // set up default WSDL template variables
+        $this->_wsdlVariables = new Varien_Object(
+            array(
+                'name' => 'Magento',
+                'url'  => htmlspecialchars(Mage::getUrl('*/*/*', array('_query' => $queryParams)))
+            )
+        );
+        parent::__construct($sourceData);
+    }
+
+    /**
+     * Set handler
+     *
+     * @param string $handler
+     * @return Mage_Api_Model_Wsdl_Config_Base
+     */
+    public function setHandler($handler)
+    {
+        $this->_handler = $handler;
+        return $this;
+    }
+
+    /**
+     * Get handler
+     *
+     * @return string
+     */
+    public function getHandler()
+    {
+        return $this->_handler;
+    }
+
+    /**
+     * Processing file data
+     *
+     * @param string $text
+     * @return string
+     */
+    public function processFileData($text)
+    {
+        /** @var $template Mage_Core_Model_Email_Template_Filter */
+        $template = Mage::getModel('Mage_Core_Model_Email_Template_Filter');
+
+        $this->_wsdlVariables->setHandler($this->getHandler());
+
+        $template->setVariables(array('wsdl'=>$this->_wsdlVariables));
+
+        return $template->filter($text);
+    }
+
+    public function addLoadedFile($file)
+    {
+        if (!in_array($file, $this->_loadedFiles)) {
+            $this->_loadedFiles[] = $file;
+        }
+        return $this;
+    }
+
+    public function loadFile($file)
+    {
+        if (in_array($file, $this->_loadedFiles)) {
+            return false;
+        }
+        $res = parent::loadFile($file);
+        if ($res) {
+            $this->addLoadedFile($file);
+        }
+        return $this;
+    }
+
+    /**
+     * Set variable to be used in WSDL template processing
+     *
+     * @param string $key Varible key
+     * @param string $value Variable value
+     * @return Mage_Api_Model_Wsdl_Config_Base
+     */
+    public function setWsdlVariable($key, $value)
+    {
+        $this->_wsdlVariables->setData($key, $value);
+
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Api/Model/Wsdl/Config/Element.php b/app/code/core/Mage/Api/Model/Wsdl/Config/Element.php
new file mode 100644
index 00000000000..12040ef47a9
--- /dev/null
+++ b/app/code/core/Mage/Api/Model/Wsdl/Config/Element.php
@@ -0,0 +1,272 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Wsdl element model
+ *
+ * @category   Mage
+ * @package    Mage_Core
+ */
+class Mage_Api_Model_Wsdl_Config_Element extends Varien_Simplexml_Element
+{
+    public function extend($source, $overwrite = false)
+    {
+        if (!$source instanceof Varien_Simplexml_Element) {
+            return $this;
+        }
+
+        foreach ($this->getChildren($source) as $namespace => $children) {
+            foreach ($children as $child) {
+                $this->extendChild($child, $overwrite, $namespace);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Extends one node
+     *
+     * @param Varien_Simplexml_Element $source
+     * @param boolean $overwrite
+     * @return Varien_Simplexml_Element
+     */
+    public function extendChild($source, $overwrite = false, $elmNamespace = '')
+    {
+        // this will be our new target node
+        $targetChild = null;
+
+        // name of the source node
+        $sourceName = $source->getName();
+
+        // here we have children of our source node
+        $sourceChildren = $this->getChildren($source);
+
+        if ($elmNamespace == '') {
+            $elmNamespace = null;
+        }
+
+        if (!$source->hasChildren()) {
+            // handle string node
+            $elm = $this->getElementByName($source, $elmNamespace);
+            if (!is_null($elm)) {
+
+                // if target already has children return without regard
+                if ($this->getChildren($elm)) {
+                    return $this;
+                }
+                if ($overwrite) {
+//                    unset($this->$sourceName);
+                    unset($elm);
+                } else {
+                    return $this;
+                }
+            }
+            $targetChild = $this->addChild($sourceName, $source->xmlentities(), $elmNamespace);
+            $targetChild->setParent($this);
+            foreach ($this->getAttributes($source) as $namespace => $attributes) {
+                foreach ($attributes as $key => $value) {
+                    $_namespacesPrefix = Mage_Api_Model_Wsdl_Config::getNamespacesPrefix();
+                    if ($namespace == '') {
+                        $namespace = null;
+                    } elseif (array_key_exists($namespace, $_namespacesPrefix)) {
+                        $key = $_namespacesPrefix[$namespace] . ':' . $key;
+                    }
+
+                    $targetChild->addAttribute($key, $this->xmlentities($value), $namespace);
+                }
+            }
+            return $this;
+        }
+
+        $elm = $this->getElementByName($source, $elmNamespace);
+        if (!is_null($elm)) {
+            $targetChild = $elm;
+        }
+        if (is_null($targetChild)) {
+            // if child target is not found create new and descend
+            $targetChild = $this->addChild($sourceName, null, $elmNamespace);
+            $targetChild->setParent($this);
+            foreach ($this->getAttributes($source) as $namespace => $attributes) {
+                foreach ($attributes as $key => $value) {
+                    $_namespacesPrefix = Mage_Api_Model_Wsdl_Config::getNamespacesPrefix();
+                    if ($namespace == '') {
+                        $namespace = null;
+                    } elseif (array_key_exists($namespace, $_namespacesPrefix)) {
+                        $key = $_namespacesPrefix[$namespace] . ':' . $key;
+                    }
+                    $targetChild->addAttribute($key, $this->xmlentities($value), $namespace);
+                }
+            }
+        }
+
+        foreach ($sourceChildren as $elmNamespace => $children) {
+            foreach ($children as $childKey => $childNode) {
+                $targetChild->extendChild($childNode, $overwrite, $elmNamespace);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Return attributes of all namespaces
+     *
+     * array(
+     *   namespace => array(
+     *     attribute_key => attribute_value,
+     *     ...
+     *   )
+     * )
+     *
+     * @param Varien_Simplexml_Element $source
+     * @return array
+     */
+    public function getAttributes($source, $namespace = null)
+    {
+        $attributes = array();
+        if (!is_null($namespace)) {
+            $attributes[$namespace] = $source->attributes($namespace);
+            return $attributes;
+        }
+        $namespaces = $source->getNamespaces(true);
+        $attributes[''] = $source->attributes('');
+        foreach ($namespaces as $key => $value) {
+            if ($key == '' || $key == 'soap') {
+                continue;
+            }
+            $attributes[$value] = $source->attributes($value);
+        }
+        return $attributes;
+    }
+
+    /**
+     * Return children of all namespaces
+     *
+     * @param Varien_Simplexml_Element $source
+     */
+    public function getChildren($source)
+    {
+        $children = array();
+        $namespaces = $source->getNamespaces(true);
+
+        /** @var Mage_Api_Helper_Data $helper */
+        $helper = Mage::helper('Mage_Api_Helper_Data');
+        $isWsi = $helper->isWsiCompliant();
+
+        foreach ($namespaces as $key => $value) {
+            if ($key == '' || (!$isWsi && $key == 'wsdl')) {
+                continue;
+            }
+            $children[$value] = $source->children($value);
+        }
+        $children[''] = $source->children('');
+        return $children;
+    }
+
+    /**
+     * Return if has children
+     *
+     * @return boolean
+     */
+    public function hasChildren()
+    {
+        if (!$this->getChildren($this)) {
+            return false;
+        }
+
+        // simplexml bug: @attributes is in children() but invisible in foreach
+        foreach ($this->getChildren($this) as $namespace => $children) {
+            foreach ($children as $k => $child) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Return element by tag name, and checking attributes with namespaces
+     *
+     * @param Varien_Simplexml_Element $source
+     * @param string $namespace
+     * @return null|Varien_Simplexml_Element
+     */
+    public function getElementByName($source, $elmNamespace = '')
+    {
+        $sourceName = $source->getName();
+        $extendElmAttributes = $this->getAttributes($source);
+        foreach ($this->children($elmNamespace) as $k => $child) {
+            if ($child->getName() == $sourceName) {
+                $elm = true;
+                foreach ($extendElmAttributes as $namespace => $attributes) {
+                    /**
+                     * if count of attributes of extend element is 0 in $namespace,
+                     * and current element has attributes in $namespace - different elements
+                     */
+//                    if (!count($attributes) && count($this->getAttributes($child, $namespace))) {
+//                        foreach ($this->getAttributes($child, $namespace) as $attribute) {
+//                            $elm = false;
+//                            break;
+//                        }
+//                    }
+                    foreach ($attributes as $key => $value) {
+                        if (is_null($child->getAttribute($key, $namespace)) || $child->getAttribute(
+                            $key,
+                            $namespace
+                        ) != $value
+                        ) {
+                            $elm = false;
+                        }
+                    }
+                }
+                /**
+                 * if count of namespaces attributes of element to extend is 0,
+                 * but current element has namespaces attributes - different elements
+                 */
+                if (!count($extendElmAttributes) && count($this->getAttributes($child))) {
+                    $elm = false;
+                }
+                if ($elm) {
+                    return $child;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns attribute value by attribute name
+     *
+     * @return string
+     */
+    public function getAttribute($name, $namespace = '')
+    {
+        $attrs = $this->attributes($namespace);
+        return isset($attrs[$name]) ? (string)$attrs[$name] : null;
+    }
+
+}
diff --git a/app/code/core/Mage/Api/controllers/Soap/WsiController.php b/app/code/core/Mage/Api/controllers/Soap/WsiController.php
new file mode 100644
index 00000000000..56fe6649657
--- /dev/null
+++ b/app/code/core/Mage/Api/controllers/Soap/WsiController.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * SOAP WS-I compatible API controller.
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_Soap_WsiController extends Mage_Api_Controller_Action
+{
+    public function indexAction()
+    {
+        $handlerName = 'soap_wsi';
+        /* @var $server Mage_Api_Model_Server */
+        $this->_getServer()->init($this, $handlerName, $handlerName)->run();
+    }
+}
diff --git a/app/code/core/Mage/Api/controllers/SoapController.php b/app/code/core/Mage/Api/controllers/SoapController.php
new file mode 100644
index 00000000000..5e6fbb18d29
--- /dev/null
+++ b/app/code/core/Mage/Api/controllers/SoapController.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.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * SOAP API controller.
+ *
+ * @category   Mage
+ * @package    Mage_Api
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Api_SoapController extends Mage_Api_Controller_Action
+{
+    public function indexAction()
+    {
+        $handlerName = 'soap_v2';
+        /* @var $server Mage_Api_Model_Server */
+        $this->_getServer()->init($this, $handlerName, $handlerName)->run();
+    }
+}
diff --git a/app/code/core/Mage/Api/etc/adminhtml.xml b/app/code/core/Mage/Api/etc/adminhtml.xml
new file mode 100644
index 00000000000..2466831fc69
--- /dev/null
+++ b/app/code/core/Mage/Api/etc/adminhtml.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <acl>
+        <resources>
+            <admin>
+                <children>
+                    <system>
+                        <children>
+                            <api translate="title" module="Mage_Api">
+                                <title>Web Services</title>
+                                <sort_order>0</sort_order>
+                                <children>
+                                    <users translate="title">
+                                        <title>SOAP - Users</title>
+                                        <sort_order>10</sort_order>
+                                    </users>
+                                    <roles translate="title">
+                                        <title>SOAP - Roles</title>
+                                        <sort_order>20</sort_order>
+                                    </roles>
+                                </children>
+                            </api>
+                            <config>
+                                <children>
+                                    <api translate="title" module="Mage_Api">
+                                        <title>Magento Core API Section</title>
+                                    </api>
+                                </children>
+                            </config>
+                        </children>
+                    </system>
+                </children>
+            </admin>
+        </resources>
+    </acl>
+</config>
diff --git a/app/code/core/Mage/Api/etc/adminhtml/menu.xml b/app/code/core/Mage/Api/etc/adminhtml/menu.xml
new file mode 100644
index 00000000000..c7740c5e0a6
--- /dev/null
+++ b/app/code/core/Mage/Api/etc/adminhtml/menu.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <menu>
+        <add id="Mage_Api::system_legacy_api" title="Legacy Web Services" module="Mage_Api"
+             sortOrder="25" parent="Mage_Adminhtml::system" resource="Mage_Api::system_legacy_api" />
+        <add id="Mage_Api::system_legacy_api_users" title="SOAP Users" module="Mage_Api"
+             sortOrder="10" parent="Mage_Api::system_legacy_api" action="adminhtml/api_user"
+             resource = "Mage_Api::system_legacy_api_users" />
+        <add id="Mage_Api::system_legacy_api_roles" title="SOAP Roles" module="Mage_Api"
+             sortOrder="20" parent="Mage_Api::system_legacy_api" action="adminhtml/api_role"
+             resource ="Mage_Api::system_legacy_api_users" />
+    </menu>
+</config>
diff --git a/app/code/core/Mage/Api/etc/adminhtml/system.xml b/app/code/core/Mage/Api/etc/adminhtml/system.xml
new file mode 100644
index 00000000000..ece2e625063
--- /dev/null
+++ b/app/code/core/Mage/Api/etc/adminhtml/system.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <system>
+        <section id="api" translate="label" module="Mage_Api" type="text" sortOrder="101" showInDefault="1" showInWebsite="1" showInStore="1">
+            <label>Magento Core API</label>
+            <tab>service</tab>
+            <resource>Mage_Api::config_api</resource>
+            <group id="config" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>General Settings</label>
+                <field id="charset" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Default Response Charset</label>
+                </field>
+                <field id="session_timeout" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Client Session Timeout (sec.)</label>
+                </field>
+                <field id="wsdl_cache_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Enable WSDL Cache</label>
+                    <source_model>Mage_Backend_Model_Config_Source_Yesno</source_model>
+                    <backend_model>Mage_Backend_Model_Config_Backend_Store</backend_model>
+                </field>
+            </group>
+        </section>
+    </system>
+</config>
diff --git a/app/code/core/Mage/Api/etc/api.xml b/app/code/core/Mage/Api/etc/api.xml
new file mode 100644
index 00000000000..36495d74f3a
--- /dev/null
+++ b/app/code/core/Mage/Api/etc/api.xml
@@ -0,0 +1,260 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <adapters>
+            <soap_v2>
+                <model>Mage_Api_Model_Server_Adapter_Soap</model>
+                <handler>soap_v2</handler>
+                <active>1</active>
+                <required>
+                    <extensions>
+                        <soap />
+                    </extensions>
+                </required>
+            </soap_v2>
+            <soap_wsi>
+                <model>Mage_Api_Model_Server_Adapter_Soap_Wsi</model>
+                <handler>soap_wsi</handler>
+                <active>1</active>
+                <required>
+                    <extensions>
+                        <soap />
+                    </extensions>
+                </required>
+            </soap_wsi>
+        </adapters>
+        <handlers>
+            <soap_v2>
+                <model>Mage_Api_Model_Server_Handler_Soap</model>
+            </soap_v2>
+            <soap_wsi>
+                <model>Mage_Api_Model_Server_Handler_Soap_Wsi</model>
+            </soap_wsi>
+        </handlers>
+        <resources>
+        </resources>
+        <resources_alias>
+        </resources_alias>
+        <v2>
+            <wsdl>
+                <prefix>
+                    <wsdl>http://schemas.xmlsoap.org/wsdl/</wsdl>
+                </prefix>
+            </wsdl>
+        </v2>
+        <faults>
+            <unknown>
+                <code>0</code>
+                <message>Unknown Error</message>
+            </unknown>
+            <internal>
+                <code>1</code>
+                <message>Internal Error. Please see log for details.</message>
+            </internal>
+            <access_denied>
+                <code>2</code>
+                <message>Access is denied.</message>
+            </access_denied>
+            <resource_path_invalid>
+                <code>3</code>
+                <message>API path is invalid.</message>
+            </resource_path_invalid>
+            <resource_path_not_callable>
+                <code>4</code>
+                <message>Resource path is not callable.</message>
+            </resource_path_not_callable>
+            <session_expired>
+                <code>5</code>
+                <message>Session expired. Try to relogin.</message>
+            </session_expired>
+            <invalid_request_param>
+                <code>6</code>
+                <message>Required parameter is missing, for more details see "exception.log".</message>
+            </invalid_request_param>
+        </faults>
+        <acl>
+            <resources>
+                <all>
+                </all>
+            </resources>
+
+            <privilegeSets>
+                <default>
+                    <view descr="View entity"/>
+                    <edit descr="Edit entity"/>
+                    <delete descr="Delete entity"/>
+                    <create descr="Create entity"/>
+                </default>
+            </privilegeSets>
+        </acl>
+
+        <domain_messages>
+            <!-- module name -->
+            <core>
+                <!-- 200 -->
+                <success>
+                    <ok>Request is executed.</ok>
+                </success>
+                <!-- 201 -->
+                <created>
+                    <created>Request is executed. Created new resource.</created>
+                </created>
+                <!-- 202 -->
+                <processing>
+                    <processing>Request is carried out.</processing>
+                </processing>
+                <!-- 400 -->
+                <validation>
+                    <invalid_param>Parameter "%s" is not valid.</invalid_param>
+                </validation>
+                <!-- 400 -->
+                <request_error>
+                    <!-- Client sent wrong API version -->
+                    <invalid_api_version>API version "%s" not found.</invalid_api_version>
+                </request_error>
+                <!-- 401 -->
+                <authentication>
+                    <protect_resource>You must provide an authenticated user for this method.</protect_resource>
+                    <invalid_token>Token in request is not valid.</invalid_token>
+                </authentication>
+                <!-- 403 -->
+                <forbidden>
+                    <api_key_invalid>Invalid API key</api_key_invalid>
+                </forbidden>
+                <!-- 404 -->
+                <not_found>
+                    <item_not_found>Requested item %s not found.</item_not_found>
+                    <resource_not_found>Requested resource %s not found.</resource_not_found>
+                </not_found>
+                <!-- 405 -->
+                <not_allowed>
+                    <method_not_allowed>Method "%s" is not allowed.</method_not_allowed>
+                </not_allowed>
+                <!-- 406 -->
+                <not_acceptable>
+                    <api_version_required>Api version is required.</api_version_required>
+                </not_acceptable>
+                <!-- 410 -->
+                <gone>
+                    <!-- Message when client trying sent the API version which no longer maintained -->
+                    <api_deprecated>API version "%s" is deprecated.</api_deprecated>
+                    <!-- Message when client trying request the resource which no longer maintained -->
+                    <deprecated>Resource "%s" is deprecated.</deprecated>
+                </gone>
+
+                <!-- 500 -->
+                <internal_error>
+                    <!-- Code error message not found or not exist -->
+                    <unknown_error>There was unknown error while processing your request.</unknown_error>
+                    <!-- Internal error when server catch some exception or language error -->
+                    <internal_error>There was internal error while processing your request.</internal_error>
+                    <!-- Developer mode message about error -->
+                    <code_error>Server has internal error. %s: %s</code_error>
+                </internal_error>
+                <!-- 501 -->
+                <not_implemented>
+                    <resource_not_implemented>This resource is not implemented so far.</resource_not_implemented>
+                    <method_not_implemented>This method is not implemented so far.</method_not_implemented>
+                </not_implemented>
+            </core>
+        </domain_messages>
+
+        <!-- Message Domains with relation to HTTP codes -->
+        <!-- The priority for domains is the HTTP code -->
+        <domain_codes>
+            <!-- All success messages except "entry_created", "processing" -->
+            <success>
+                <http_code>200</http_code>
+                <type>notification</type>
+            </success>
+            <!-- Messages when created new entry -->
+            <created>
+                <http_code>201</http_code>
+                <type>notification</type>
+            </created>
+            <!-- Processing messages -->
+            <processing>
+                <http_code>202</http_code>
+                <type>notification</type>
+            </processing>
+
+            <!-- Validation messages -->
+            <validation>
+                <http_code>400</http_code>
+                <type>error</type>
+            </validation>
+            <!-- Messages when the request from a client has an error -->
+            <request_error>
+                <http_code>400</http_code>
+                <type>error</type>
+            </request_error>
+            <!-- Authentication error messages -->
+            <authentication>
+                <http_code>401</http_code>
+                <type>error</type>
+            </authentication>
+            <!-- Messages when post request is accepted but cannot performed -->
+            <forbidden>
+                <http_code>403</http_code>
+                <type>error</type>
+            </forbidden>
+            <!-- Messages when some data not found -->
+            <not_found>
+                <http_code>404</http_code>
+                <type>error</type>
+            </not_found>
+            <!-- Messages when some method is not allowed -->
+            <not_allowed>
+                <http_code>405</http_code>
+                <type>error</type>
+            </not_allowed>
+            <!-- Messages when some is not acceptable -->
+            <not_acceptable>
+                <http_code>406</http_code>
+                <type>error</type>
+            </not_acceptable>
+            <!-- Messages when some resource are gone -->
+            <gone>
+                <http_code>410</http_code>
+                <type>error</type>
+            </gone>
+            <!-- All messages related with internal errors -->
+            <internal_error>
+                <http_code>500</http_code>
+                <type>error</type>
+            </internal_error>
+            <!-- Messages when something not implemented -->
+            <not_implemented>
+                <http_code>501</http_code>
+                <type>error</type>
+            </not_implemented>
+        </domain_codes>
+
+    </api>
+</config>
diff --git a/app/code/core/Mage/Api/etc/config.xml b/app/code/core/Mage/Api/etc/config.xml
new file mode 100644
index 00000000000..5fa3bfab386
--- /dev/null
+++ b/app/code/core/Mage/Api/etc/config.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <modules>
+        <Mage_Api>
+            <version>1.6.0.0</version>
+            <active>true</active>
+            <codePool>core</codePool>
+            <depends>
+                <Mage_Core />
+            </depends>
+        </Mage_Api>
+    </modules>
+    <global>
+        <ignoredModules>
+            <entities>
+                <api/>
+            </entities>
+        </ignoredModules>
+        <cache>
+            <types>
+                <config_api translate="label,description" module="Mage_Api">
+                    <label>Legacy API Configuration</label>
+                    <description>Web Services definition files (api.xml).</description>
+                    <tags>CONFIG_API</tags>
+                </config_api>
+            </types>
+        </cache>
+        <resources>
+            <api_setup>
+                <setup>
+                    <module>Mage_Api</module>
+                </setup>
+            </api_setup>
+        </resources>
+        <request>
+            <direct_front_name>
+                <api/>
+            </direct_front_name>
+        </request>
+    </global>
+    <frontend>
+        <routers>
+            <api>
+                <use>standard</use>
+                <args>
+                    <module>Mage_Api</module>
+                    <frontName>api</frontName>
+                </args>
+            </api>
+        </routers>
+        <translate>
+            <modules>
+                <Mage_Api>
+                    <files>
+                        <default>Mage_Api.csv</default>
+                    </files>
+                </Mage_Api>
+            </modules>
+        </translate>
+    </frontend>
+    <adminhtml>
+        <translate>
+            <modules>
+                <Mage_Api>
+                    <files>
+                        <default>Mage_Api.csv</default>
+                    </files>
+                </Mage_Api>
+            </modules>
+        </translate>
+    </adminhtml>
+    <default>
+        <api>
+            <config>
+                <charset>UTF-8</charset>
+                <session_timeout>3600</session_timeout>
+                <wsdl_cache_enabled>0</wsdl_cache_enabled>
+            </config>
+        </api>
+    </default>
+</config>
diff --git a/app/code/core/Mage/Api/etc/wsdl.xml b/app/code/core/Mage/Api/etc/wsdl.xml
new file mode 100644
index 00000000000..fd9fe0d5dd3
--- /dev/null
+++ b/app/code/core/Mage/Api/etc/wsdl.xml
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
+    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
+            <complexType name="associativeEntity">
+                <all>
+                    <element name="key" type="xsd:string" />
+                    <element name="value" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="associativeArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:associativeEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="associativeMultiEntity">
+                <all>
+                    <element name="key" type="xsd:string" />
+                    <element name="value" type="typens:ArrayOfString" />
+                </all>
+            </complexType>
+            <complexType name="associativeMultiArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:associativeMultiEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="filters">
+                <all>
+                    <element name="filter" type="typens:associativeArray" minOccurs="0" />
+                    <element name="complex_filter" type="typens:complexFilterArray" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="complexFilterArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:complexFilter[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="complexFilter">
+                <all>
+                    <element name="key" type="xsd:string" />
+                    <element name="value" type="typens:associativeEntity" />
+                </all>
+            </complexType>
+            <complexType name="ArrayOfString">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="ArrayOfInt">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:int[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="apiMethodEntity">
+                <all>
+                    <element name="title" type="xsd:string" />
+                    <element name="path" type="xsd:string" />
+                    <element name="name" type="xsd:string" />
+                    <element name="aliases" type="typens:ArrayOfString" />
+                </all>
+            </complexType>
+            <complexType name="ArrayOfApiMethods">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:apiMethodEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="apiEntity">
+                <all>
+                    <element name="title" type="xsd:string" />
+                    <element name="name" type="xsd:string" />
+                    <element name="aliases" type="typens:ArrayOfString" />
+                    <element name="methods" type="typens:ArrayOfApiMethods" />
+                </all>
+            </complexType>
+            <complexType name="ArrayOfApis">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:apiEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="existsFaltureEntity">
+                <all>
+                    <element name="code" type="xsd:string" />
+                    <element name="message" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="ArrayOfExistsFaltures">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:existsFaltureEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+        </schema>
+    </types>
+    <message name="endSession">
+        <part name="sessionId" type="xsd:string" />
+    </message>
+    <message name="endSessionResponse">
+        <part name="endSessionReturn" type="xsd:boolean" />
+    </message>
+    <message name="login">
+        <part name="username" type="xsd:string" />
+        <part name="apiKey" type="xsd:string" />
+    </message>
+    <message name="loginResponse">
+        <part name="loginReturn" type="xsd:string" />
+    </message>
+    <message name="resourcesRequest">
+        <part name="sessionId" type="xsd:string" />
+    </message>
+    <message name="resourcesResponse">
+        <part name="resourcesReturn" type="typens:ArrayOfApis" />
+    </message>
+    <message name="globalFaults">
+        <part name="sessionId" type="xsd:string" />
+    </message>
+    <message name="globalFaultsResponse">
+        <part name="globalFaultsReturn" type="typens:ArrayOfExistsFaltures" />
+    </message>
+    <message name="resourceFaults">
+        <part name="resourceName" type="xsd:string" />
+        <part name="sessionId" type="xsd:string" />
+    </message>
+    <message name="resourceFaultsResponse">
+        <part name="resourceFaultsReturn" type="typens:ArrayOfExistsFaltures" />
+    </message>
+    <message name="startSession" />
+    <message name="startSessionResponse">
+        <part name="startSessionReturn" type="xsd:string" />
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="endSession">
+            <documentation>End web service session</documentation>
+            <input message="typens:endSession" />
+            <output message="typens:endSessionResponse" />
+        </operation>
+        <operation name="login">
+            <documentation>Login user and retrive session id</documentation>
+            <input message="typens:login" />
+            <output message="typens:loginResponse" />
+        </operation>
+        <operation name="startSession">
+            <documentation>Start web service session</documentation>
+            <input message="typens:startSession" />
+            <output message="typens:startSessionResponse" />
+        </operation>
+        <operation name="resources">
+            <documentation>List of available resources</documentation>
+            <input message="typens:resourcesRequest" />
+            <output message="typens:resourcesResponse" />
+        </operation>
+        <operation name="globalFaults">
+            <documentation>List of global faults</documentation>
+            <input message="typens:globalFaults" />
+            <output message="typens:globalFaultsResponse" />
+        </operation>
+        <operation name="resourceFaults">
+            <documentation>List of resource faults</documentation>
+            <input message="typens:resourceFaults" />
+            <output message="typens:resourceFaultsResponse" />
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="endSession">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="login">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="startSession">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="resources">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="globalFaults">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="resourceFaults">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/Api/etc/wsi.xml b/app/code/core/Mage/Api/etc/wsi.xml
new file mode 100644
index 00000000000..0db28ab2869
--- /dev/null
+++ b/app/code/core/Mage/Api/etc/wsi.xml
@@ -0,0 +1,381 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="associativeEntity">
+                <xsd:sequence>
+                    <xsd:element name="key" type="xsd:string" />
+                    <xsd:element name="value" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="associativeArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:associativeEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="associativeMultiEntity">
+                <xsd:sequence>
+                    <xsd:element name="key" type="xsd:string" />
+                    <xsd:element name="value" type="typens:ArrayOfString" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="associativeMultiArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:associativeMultiEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="complexFilter">
+                <xsd:sequence>
+                    <xsd:element name="key" type="xsd:string" />
+                    <xsd:element name="value" type="typens:associativeEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="complexFilterArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:complexFilter" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="filters">
+                <xsd:sequence>
+                    <xsd:element name="filter" type="typens:associativeArray" minOccurs="0" />
+                    <xsd:element name="complex_filter" type="typens:complexFilterArray" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="ArrayOfString">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="ArrayOfInt">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="xsd:int" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="apiMethodEntity">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" />
+                    <xsd:element name="path" type="xsd:string" />
+                    <xsd:element name="name" type="xsd:string" />
+                    <xsd:element name="aliases" type="typens:ArrayOfString" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="ArrayOfApiMethods">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:apiMethodEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="apiEntity">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" />
+                    <xsd:element name="name" type="xsd:string" />
+                    <xsd:element name="aliases" type="typens:ArrayOfString" />
+                    <xsd:element name="methods" type="typens:ArrayOfApiMethods" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="ArrayOfApis">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:apiEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="existsFaltureEntity">
+                <xsd:sequence>
+                    <xsd:element name="code" type="xsd:string" />
+                    <xsd:element name="message" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="ArrayOfExistsFaltures">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:existsFaltureEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+
+
+
+            <xsd:element name="callParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="apiPath" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="args" type="xsd:anyType" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="callResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:anyType" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="multiCallParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="calls" type="xsd:anyType" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="options" type="xsd:anyType" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="multiCallResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:anyType" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="endSessionParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="endSessionResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="loginParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="username" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="apiKey" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="loginResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="resourcesRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="resourcesResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:ArrayOfApis" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="globalFaultsParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="globalFaultsResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:ArrayOfExistsFaltures" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="resourceFaultsParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="resourceName" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="resourceFaultsResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:ArrayOfExistsFaltures" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="startSessionResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="call">
+        <wsdl:part name="parameters" element="typens:callParam" />
+    </wsdl:message>
+    <wsdl:message name="callResponse">
+        <wsdl:part name="parameters" element="typens:callResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="multiCall">
+        <wsdl:part name="parameters" element="typens:multiCallParam" />
+    </wsdl:message>
+    <wsdl:message name="multiCallResponse">
+        <wsdl:part name="parameters" element="typens:multiCallResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="endSession">
+        <wsdl:part name="parameters" element="typens:endSessionParam" />
+    </wsdl:message>
+    <wsdl:message name="endSessionResponse">
+        <wsdl:part name="parameters" element="typens:endSessionResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="login">
+        <wsdl:part name="parameters" element="typens:loginParam" />
+    </wsdl:message>
+    <wsdl:message name="loginResponse">
+        <wsdl:part name="parameters" element="typens:loginResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="resourcesRequest">
+        <wsdl:part name="parameters" element="typens:resourcesRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="resourcesResponse">
+        <wsdl:part name="parameters" element="typens:resourcesResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="globalFaults">
+        <wsdl:part name="parameters" element="typens:globalFaultsParam" />
+    </wsdl:message>
+    <wsdl:message name="globalFaultsResponse">
+        <wsdl:part name="parameters" element="typens:globalFaultsResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="resourceFaults">
+        <wsdl:part name="parameters" element="typens:resourceFaultsParam" />
+    </wsdl:message>
+    <wsdl:message name="resourceFaultsResponse">
+        <wsdl:part name="parameters" element="typens:resourceFaultsResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="startSession" />
+    <wsdl:message name="startSessionResponse">
+        <wsdl:part name="parameters" element="typens:startSessionResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="call">
+            <wsdl:documentation>Call api functionality</wsdl:documentation>
+            <wsdl:input message="typens:call" />
+            <wsdl:output message="typens:callResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="multiCall">
+            <wsdl:documentation>Multiple calls of resource functionality</wsdl:documentation>
+            <wsdl:input message="typens:multiCall" />
+            <wsdl:output message="typens:multiCallResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="endSession">
+            <wsdl:documentation>End web service session</wsdl:documentation>
+            <wsdl:input message="typens:endSession" />
+            <wsdl:output message="typens:endSessionResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="login">
+            <wsdl:documentation>Login user and retrive session id</wsdl:documentation>
+            <wsdl:input message="typens:login" />
+            <wsdl:output message="typens:loginResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="startSession">
+            <wsdl:documentation>Start web service session</wsdl:documentation>
+            <wsdl:input message="typens:startSession" />
+            <wsdl:output message="typens:startSessionResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="resources">
+            <wsdl:documentation>List of available resources</wsdl:documentation>
+            <wsdl:input message="typens:resourcesRequest" />
+            <wsdl:output message="typens:resourcesResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="globalFaults">
+            <wsdl:documentation>List of global faults</wsdl:documentation>
+            <wsdl:input message="typens:globalFaults" />
+            <wsdl:output message="typens:globalFaultsResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="resourceFaults">
+            <wsdl:documentation>List of resource faults</wsdl:documentation>
+            <wsdl:input message="typens:resourceFaults" />
+            <wsdl:output message="typens:resourceFaultsResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="call">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="multiCall">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="endSession">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="login">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="startSession">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="resources">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="globalFaults">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="resourceFaults">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="{{var wsdl.name}}Service">
+        <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/Api/locale/de_DE/Mage_Api.csv b/app/code/core/Mage/Api/locale/de_DE/Mage_Api.csv
new file mode 100644
index 00000000000..4d060c6fd98
--- /dev/null
+++ b/app/code/core/Mage/Api/locale/de_DE/Mage_Api.csv
@@ -0,0 +1,16 @@
+"Access denied.","Zugang verweigert."
+"Client Session Timeout (sec.)","Kunde Session-Timeout (in Sekunden)"
+"Default Response Charset","Standard-Schriftsatz für Antwort"
+"Email","E-Mail"
+"General Settings","Allgemeine Einstellungen"
+"Invalid webservice adapter specified.","Ungültiger Webservice Adapter angegeben."
+"Invalid webservice handler specified.","Ungültiger Webservice Handler angegeben."
+"Magento Core API","Magento Core API"
+"Magento Core API Section","Magento Core API Sektion"
+"Roles","Rollen"
+"Unable to login.","Einloggen nicht möglich."
+"User Name","Benutzername"
+"Users","Benutzer"
+"WS-I Compliance","WS-I Übereinstimmung"
+"Web Services","Webdienste"
+"Your account has been deactivated.","Ihr Benutzerkonto wurde deaktiviert."
diff --git a/app/code/core/Mage/Api/locale/en_US/Mage_Api.csv b/app/code/core/Mage/Api/locale/en_US/Mage_Api.csv
new file mode 100644
index 00000000000..5c6674a0d99
--- /dev/null
+++ b/app/code/core/Mage/Api/locale/en_US/Mage_Api.csv
@@ -0,0 +1,16 @@
+"Access denied.","Access denied."
+"Client Session Timeout (sec.)","Client Session Timeout (sec.)"
+"Default Response Charset","Default Response Charset"
+"Email","Email"
+"General Settings","General Settings"
+"Invalid webservice adapter specified.","Invalid webservice adapter specified."
+"Invalid webservice handler specified.","Invalid webservice handler specified."
+"Magento Core API","Magento Core API"
+"Magento Core API Section","Magento Core API Section"
+"Roles","Roles"
+"Unable to login.","Unable to login."
+"User Name","User Name"
+"Users","Users"
+"WS-I Compliance","WS-I Compliance"
+"Web Services","Web Services"
+"Your account has been deactivated.","Your account has been deactivated."
diff --git a/app/code/core/Mage/Api/locale/es_ES/Mage_Api.csv b/app/code/core/Mage/Api/locale/es_ES/Mage_Api.csv
new file mode 100644
index 00000000000..972a0ac704b
--- /dev/null
+++ b/app/code/core/Mage/Api/locale/es_ES/Mage_Api.csv
@@ -0,0 +1,16 @@
+"Access denied.","Acceso denegado"
+"Client Session Timeout (sec.)","Plazo límite de la sesión cliente (seg.)"
+"Default Response Charset","Conjunto de caracteres de respuesta por omisión"
+"Email","Correo electrónico"
+"General Settings","Opciones generales"
+"Invalid webservice adapter specified.","Adaptador de servicio web especificado inválido"
+"Invalid webservice handler specified.","Controlador de servicio web especificado inválido"
+"Magento Core API","API del núcleo de Magento"
+"Magento Core API Section","Apartado de la API (interfaz de programación de aplicaciones) del núcleo de Magento"
+"Roles","Roles"
+"Unable to login.","No es posible entrar al sistema."
+"User Name","Nombre de usuario"
+"Users","Usuarios"
+"WS-I Compliance","Conformidad con WS-I"
+"Web Services","Servicios web"
+"Your account has been deactivated.","Se ha desactivado su cuenta."
diff --git a/app/code/core/Mage/Api/locale/fr_FR/Mage_Api.csv b/app/code/core/Mage/Api/locale/fr_FR/Mage_Api.csv
new file mode 100644
index 00000000000..9389383ef21
--- /dev/null
+++ b/app/code/core/Mage/Api/locale/fr_FR/Mage_Api.csv
@@ -0,0 +1,16 @@
+"Access denied.","Accès refusé."
+"Client Session Timeout (sec.)","Expiration de la session client (secondes)"
+"Default Response Charset","Table de caractères de la réponse par défaut"
+"Email","Email"
+"General Settings","Réglages généraux"
+"Invalid webservice adapter specified.","Adaptateur de service web invalide."
+"Invalid webservice handler specified.","Gérant de service web invalide."
+"Magento Core API","Magento Core API"
+"Magento Core API Section","Magento Core API Section"
+"Roles","Rôles"
+"Unable to login.","Connexion impossible."
+"User Name","Nom d'utilisateur"
+"Users","Utilisateurs"
+"WS-I Compliance","Conforme à WS-I"
+"Web Services","Services Web"
+"Your account has been deactivated.","Votre compte a été désactivé."
diff --git a/app/code/core/Mage/Api/locale/nl_NL/Mage_Api.csv b/app/code/core/Mage/Api/locale/nl_NL/Mage_Api.csv
new file mode 100644
index 00000000000..62570ad76ad
--- /dev/null
+++ b/app/code/core/Mage/Api/locale/nl_NL/Mage_Api.csv
@@ -0,0 +1,16 @@
+"Access denied.","Toegang geweigerd."
+"Client Session Timeout (sec.)","Klant Sessie Time out (sec.)"
+"Default Response Charset","Karakterset standaard antwoord"
+"Email","Email"
+"General Settings","Algemene instellingen"
+"Invalid webservice adapter specified.","Ongeldige webdienst adapter gespecificeerd."
+"Invalid webservice handler specified.","Ongeldige webservice handler gespecificeerd."
+"Magento Core API","Magento Core API"
+"Magento Core API Section","Magento Core API Sectie"
+"Roles","Rollen"
+"Unable to login.","Kan niet inloggen."
+"User Name","Gebruikersnaam"
+"Users","Gebruikers"
+"WS-I Compliance","WS-I naleving"
+"Web Services","Web Diensten"
+"Your account has been deactivated.","Uw account is gedeactiveerd."
diff --git a/app/code/core/Mage/Api/locale/pt_BR/Mage_Api.csv b/app/code/core/Mage/Api/locale/pt_BR/Mage_Api.csv
new file mode 100644
index 00000000000..bebef0b86a0
--- /dev/null
+++ b/app/code/core/Mage/Api/locale/pt_BR/Mage_Api.csv
@@ -0,0 +1,16 @@
+"Access denied.","Acesso negado."
+"Client Session Timeout (sec.)","Tempo Limite da Sessão de Cliente (seg.)"
+"Default Response Charset","Conjunto de Caracteres Predefinido de Resposta"
+"Email","E-mail"
+"General Settings","Definições Gerais"
+"Invalid webservice adapter specified.","Adaptador de serviço de rede especificado inválido."
+"Invalid webservice handler specified.","Processador de serviço de rede especificado inválido."
+"Magento Core API","Núcleo Magento API"
+"Magento Core API Section","Seção Núcleo Magento API"
+"Roles","Funções"
+"Unable to login.","Incapaz de entrar."
+"User Name","Nome do Usuário"
+"Users","Usuários"
+"WS-I Compliance","Conformidade WS-I"
+"Web Services","Serviços Web"
+"Your account has been deactivated.","Sua conta foi desativada."
diff --git a/app/code/core/Mage/Api/locale/zh_CN/Mage_Api.csv b/app/code/core/Mage/Api/locale/zh_CN/Mage_Api.csv
new file mode 100644
index 00000000000..9130432dcad
--- /dev/null
+++ b/app/code/core/Mage/Api/locale/zh_CN/Mage_Api.csv
@@ -0,0 +1,16 @@
+"Access denied.","访问被拒绝"
+"Client Session Timeout (sec.)","客户端会话超时(秒。)"
+"Default Response Charset","默认响应字符集"
+"Email","电子邮件"
+"General Settings","常规设置"
+"Invalid webservice adapter specified.","指定的Web服务适配器无效。"
+"Invalid webservice handler specified.","指定的Web服务处理程序无效。"
+"Magento Core API","Magento Core API"
+"Magento Core API Section","Magento Core API 部分"
+"Roles","角色"
+"Unable to login.","无法登录。"
+"User Name","用户名"
+"Users","用户"
+"WS-I Compliance","WS-I 兼容"
+"Web Services","Web服务"
+"Your account has been deactivated.","您的帐户已被撤销。"
diff --git a/app/code/core/Mage/Api/sql/api_setup/install-1.6.0.0.php b/app/code/core/Mage/Api/sql/api_setup/install-1.6.0.0.php
new file mode 100644
index 00000000000..d47e2af4001
--- /dev/null
+++ b/app/code/core/Mage/Api/sql/api_setup/install-1.6.0.0.php
@@ -0,0 +1,208 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Api install
+ *
+ * @category    Mage
+ * @package     Mage_Api
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+$installer = $this;
+/* @var $installer Mage_Core_Model_Resource_Setup */
+
+$installer->startSetup();
+
+/**
+ * Create table 'api_assert'
+ */
+$table = $installer->getConnection()
+    ->newTable($installer->getTable('api_assert'))
+    ->addColumn('assert_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'identity'  => true,
+        'unsigned'  => true,
+        'nullable'  => false,
+        'primary'   => true,
+        ), 'Assert id')
+    ->addColumn('assert_type', Varien_Db_Ddl_Table::TYPE_TEXT, 20, array(
+        ), 'Assert type')
+    ->addColumn('assert_data', Varien_Db_Ddl_Table::TYPE_TEXT, '64k', array(
+        ), 'Assert additional data')
+    ->setComment('Api ACL Asserts');
+$installer->getConnection()->createTable($table);
+
+/**
+ * Create table 'api_role'
+ */
+$table = $installer->getConnection()
+    ->newTable($installer->getTable('api_role'))
+    ->addColumn('role_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'identity'  => true,
+        'unsigned'  => true,
+        'nullable'  => false,
+        'primary'   => true,
+        ), 'Role id')
+    ->addColumn('parent_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'unsigned'  => true,
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'Parent role id')
+    ->addColumn('tree_level', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
+        'unsigned'  => true,
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'Role level in tree')
+    ->addColumn('sort_order', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
+        'unsigned'  => true,
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'Sort order to display on admin area')
+    ->addColumn('role_type', Varien_Db_Ddl_Table::TYPE_TEXT, 1, array(
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'Role type')
+    ->addColumn('user_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'unsigned'  => true,
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'User id')
+    ->addColumn('role_name', Varien_Db_Ddl_Table::TYPE_TEXT, 50, array(
+        ), 'Role name')
+    ->addIndex($installer->getIdxName('api_role', array('parent_id', 'sort_order')),
+        array('parent_id', 'sort_order'))
+    ->addIndex($installer->getIdxName('api_role', array('tree_level')),
+        array('tree_level'))
+    ->setComment('Api ACL Roles');
+$installer->getConnection()->createTable($table);
+
+/**
+ * Create table 'api_rule'
+ */
+$table = $installer->getConnection()
+    ->newTable($installer->getTable('api_rule'))
+    ->addColumn('rule_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'identity'  => true,
+        'unsigned'  => true,
+        'nullable'  => false,
+        'primary'   => true,
+        ), 'Api rule Id')
+    ->addColumn('role_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'unsigned'  => true,
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'Api role Id')
+    ->addColumn('resource_id', Varien_Db_Ddl_Table::TYPE_TEXT, 255, array(
+        ), 'Module code')
+    ->addColumn('api_privileges', Varien_Db_Ddl_Table::TYPE_TEXT, 20, array(
+        ), 'Privileges')
+    ->addColumn('assert_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'unsigned'  => true,
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'Assert id')
+    ->addColumn('role_type', Varien_Db_Ddl_Table::TYPE_TEXT, 1, array(
+        ), 'Role type')
+    ->addColumn('api_permission', Varien_Db_Ddl_Table::TYPE_TEXT, 10, array(
+        ), 'Permission')
+    ->addIndex($installer->getIdxName('api_rule', array('resource_id', 'role_id')),
+        array('resource_id', 'role_id'))
+    ->addIndex($installer->getIdxName('api_rule', array('role_id', 'resource_id')),
+        array('role_id', 'resource_id'))
+    ->addForeignKey($installer->getFkName('api_rule', 'role_id', 'api_role', 'role_id'),
+        'role_id', $installer->getTable('api_role'), 'role_id',
+        Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
+    ->setComment('Api ACL Rules');
+$installer->getConnection()->createTable($table);
+
+/**
+ * Create table 'api_user'
+ */
+$table = $installer->getConnection()
+    ->newTable($installer->getTable('api_user'))
+    ->addColumn('user_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'identity'  => true,
+        'unsigned'  => true,
+        'nullable'  => false,
+        'primary'   => true,
+        ), 'User id')
+    ->addColumn('firstname', Varien_Db_Ddl_Table::TYPE_TEXT, 32, array(
+        ), 'First name')
+    ->addColumn('lastname', Varien_Db_Ddl_Table::TYPE_TEXT, 32, array(
+        ), 'Last name')
+    ->addColumn('email', Varien_Db_Ddl_Table::TYPE_TEXT, 128, array(
+        ), 'Email')
+    ->addColumn('username', Varien_Db_Ddl_Table::TYPE_TEXT, 40, array(
+        ), 'Nickname')
+    ->addColumn('api_key', Varien_Db_Ddl_Table::TYPE_TEXT, 40, array(
+        ), 'Api key')
+    ->addColumn('created', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
+        'nullable'  => false,
+        ), 'User record create date')
+    ->addColumn('modified', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
+        ), 'User record modify date')
+    ->addColumn('lognum', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
+        'unsigned'  => true,
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'Quantity of log ins')
+    ->addColumn('reload_acl_flag', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
+        'nullable'  => false,
+        'default'   => '0',
+        ), 'Refresh ACL flag')
+    ->addColumn('is_active', Varien_Db_Ddl_Table::TYPE_SMALLINT, null, array(
+        'nullable'  => false,
+        'default'   => '1',
+        ), 'Account status')
+    ->setComment('Api Users');
+$installer->getConnection()->createTable($table);
+
+/**
+ * Create table 'api_session'
+ */
+$table = $installer->getConnection()
+    ->newTable($installer->getTable('api_session'))
+    ->addColumn('user_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
+        'unsigned'  => true,
+        'nullable'  => false,
+        ), 'User id')
+    ->addColumn('logdate', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array(
+        'nullable'  => false,
+        ), 'Login date')
+    ->addColumn('sessid', Varien_Db_Ddl_Table::TYPE_TEXT, 40, array(
+        ), 'Sessioin id')
+    ->addIndex($installer->getIdxName('api_session', array('user_id')),
+        array('user_id'))
+    ->addIndex($installer->getIdxName('api_session', array('sessid')),
+        array('sessid'))
+    ->addForeignKey($installer->getFkName('api_session', 'user_id', 'api_user', 'user_id'),
+        'user_id', $installer->getTable('api_user'), 'user_id',
+        Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
+    ->setComment('Api Sessions');
+$installer->getConnection()->createTable($table);
+
+
+
+$installer->endSetup();
diff --git a/app/code/core/Mage/Backend/Block/Abstract.php b/app/code/core/Mage/Backend/Block/Abstract.php
index 3d4d163fb86..6dda3399ee7 100644
--- a/app/code/core/Mage/Backend/Block/Abstract.php
+++ b/app/code/core/Mage/Backend/Block/Abstract.php
@@ -29,7 +29,9 @@
  *
  * @category   Mage
  * @package    Mage_Backend
- * @author      Magento Core Team <core@magentocommerce.com>
+ * @author     Magento Core Team <core@magentocommerce.com>
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Mage_Backend_Block_Abstract extends Mage_Core_Block_Template
 {
@@ -45,6 +47,8 @@ class Mage_Backend_Block_Abstract extends Mage_Core_Block_Template
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param array $data
      *
@@ -62,11 +66,13 @@ class Mage_Backend_Block_Abstract extends Mage_Core_Block_Template
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
     }
 }
diff --git a/app/code/core/Mage/Backend/Block/Catalog/Product/Tab/Container.php b/app/code/core/Mage/Backend/Block/Catalog/Product/Tab/Container.php
new file mode 100644
index 00000000000..c1a695ea5e5
--- /dev/null
+++ b/app/code/core/Mage/Backend/Block/Catalog/Product/Tab/Container.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.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Block_Catalog_Product_Tab_Container extends Mage_Backend_Block_Template
+    implements Mage_Backend_Block_Widget_Tab_Interface
+{
+
+    /**
+     * Return Tab label
+     *
+     * @return string
+     */
+    public function getTabLabel()
+    {
+        return '';
+    }
+
+    /**
+     * Return Tab title
+     *
+     * @return string
+     */
+    public function getTabTitle()
+    {
+        return $this->getTabLabel();
+    }
+
+    /**
+     * Can show tab in tabs
+     *
+     * @return boolean
+     */
+    public function canShowTab()
+    {
+        return true;
+    }
+
+    /**
+     * Tab is hidden
+     *
+     * @return boolean
+     */
+    public function isHidden()
+    {
+        return false;
+    }
+}
diff --git a/app/code/core/Mage/Backend/Block/Store/Switcher.php b/app/code/core/Mage/Backend/Block/Store/Switcher.php
index e899dc9f8cb..23f4d599cf7 100644
--- a/app/code/core/Mage/Backend/Block/Store/Switcher.php
+++ b/app/code/core/Mage/Backend/Block/Store/Switcher.php
@@ -92,6 +92,8 @@ class Mage_Backend_Block_Store_Switcher extends Mage_Backend_Block_Template
     protected $_storeGroupFactory;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -103,6 +105,8 @@ class Mage_Backend_Block_Store_Switcher extends Mage_Backend_Block_Template
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_App $application
      * @param Mage_Core_Model_Website_Factory $websiteFactory
@@ -123,6 +127,8 @@ class Mage_Backend_Block_Store_Switcher extends Mage_Backend_Block_Template
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_App $application,
         Mage_Core_Model_Website_Factory $websiteFactory,
@@ -130,7 +136,7 @@ class Mage_Backend_Block_Store_Switcher extends Mage_Backend_Block_Template
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data);
         $this->_application = $application;
         $this->_websiteFactory = $websiteFactory;
         $this->_storeGroupFactory = $storeGroupFactory;
diff --git a/app/code/core/Mage/Backend/Block/System/Config/Edit.php b/app/code/core/Mage/Backend/Block/System/Config/Edit.php
index 481459bdd67..11437b020fd 100644
--- a/app/code/core/Mage/Backend/Block/System/Config/Edit.php
+++ b/app/code/core/Mage/Backend/Block/System/Config/Edit.php
@@ -69,6 +69,8 @@ class Mage_Backend_Block_System_Config_Edit extends Mage_Backend_Block_Widget
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Backend_Model_Config_Structure $configStructure
      * @param array $data
@@ -87,12 +89,14 @@ class Mage_Backend_Block_System_Config_Edit extends Mage_Backend_Block_Widget
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Backend_Model_Config_Structure $configStructure,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
         $this->_configStructure = $configStructure;
     }
diff --git a/app/code/core/Mage/Backend/Block/System/Config/Form.php b/app/code/core/Mage/Backend/Block/System/Config/Form.php
index 9248b2bde74..513d5d98775 100644
--- a/app/code/core/Mage/Backend/Block/System/Config/Form.php
+++ b/app/code/core/Mage/Backend/Block/System/Config/Form.php
@@ -133,6 +133,8 @@ class Mage_Backend_Block_System_Config_Form extends Mage_Backend_Block_Widget_Fo
     protected $_coreConfig;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -144,6 +146,8 @@ class Mage_Backend_Block_System_Config_Form extends Mage_Backend_Block_Widget_Fo
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Backend_Model_Config_Factory $configFactory
      * @param Varien_Data_Form_Factory $formFactory
@@ -168,6 +172,8 @@ class Mage_Backend_Block_System_Config_Form extends Mage_Backend_Block_Widget_Fo
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Backend_Model_Config_Factory $configFactory,
         Varien_Data_Form_Factory $formFactory,
@@ -179,7 +185,8 @@ class Mage_Backend_Block_System_Config_Form extends Mage_Backend_Block_Widget_Fo
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
+        );
         $this->_configFactory = $configFactory;
         $this->_formFactory = $formFactory;
         $this->_cloneModelFactory = $cloneModelFactory;
diff --git a/app/code/core/Mage/Backend/Block/System/Config/Form/Field.php b/app/code/core/Mage/Backend/Block/System/Config/Form/Field.php
index 87d6c11fb5b..1d2239516bb 100644
--- a/app/code/core/Mage/Backend/Block/System/Config/Form/Field.php
+++ b/app/code/core/Mage/Backend/Block/System/Config/Form/Field.php
@@ -34,7 +34,7 @@
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Mage_Backend_Block_System_Config_Form_Field
-    extends Mage_Backend_Block_Abstract
+    extends Mage_Core_Block_Template
     implements Varien_Data_Form_Element_Renderer_Interface
 {
     /**
@@ -45,6 +45,8 @@ class Mage_Backend_Block_System_Config_Form_Field
     protected $_application;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -56,6 +58,8 @@ class Mage_Backend_Block_System_Config_Form_Field
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_App $application
      * @param array $data
@@ -74,13 +78,15 @@ class Mage_Backend_Block_System_Config_Form_Field
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_App $application,
         array $data = array()
     ) {
         $this->_application = $application;
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
     }
 
diff --git a/app/code/core/Mage/Backend/Block/System/Config/Form/Field/Heading.php b/app/code/core/Mage/Backend/Block/System/Config/Form/Field/Heading.php
index 037b7de0a44..6a532dcfcb4 100644
--- a/app/code/core/Mage/Backend/Block/System/Config/Form/Field/Heading.php
+++ b/app/code/core/Mage/Backend/Block/System/Config/Form/Field/Heading.php
@@ -31,7 +31,7 @@
  * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Mage_Backend_Block_System_Config_Form_Field_Heading
-    extends Mage_Backend_Block_Abstract implements Varien_Data_Form_Element_Renderer_Interface
+    extends Mage_Core_Block_Template implements Varien_Data_Form_Element_Renderer_Interface
 {
     /**
      * Render element html
diff --git a/app/code/core/Mage/Backend/Block/System/Config/Form/Fieldset.php b/app/code/core/Mage/Backend/Block/System/Config/Form/Fieldset.php
index d27d31ecbd8..64386ce1b16 100644
--- a/app/code/core/Mage/Backend/Block/System/Config/Form/Fieldset.php
+++ b/app/code/core/Mage/Backend/Block/System/Config/Form/Fieldset.php
@@ -33,7 +33,7 @@
  * @author     Magento Core Team <core@magentocommerce.com>
  */
 class Mage_Backend_Block_System_Config_Form_Fieldset
-    extends Mage_Backend_Block_Abstract
+    extends Mage_Core_Block_Template
     implements Varien_Data_Form_Element_Renderer_Interface
 {
 
diff --git a/app/code/core/Mage/Backend/Block/System/Config/Tabs.php b/app/code/core/Mage/Backend/Block/System/Config/Tabs.php
index e72e8eb0326..edc23dd8c7b 100644
--- a/app/code/core/Mage/Backend/Block/System/Config/Tabs.php
+++ b/app/code/core/Mage/Backend/Block/System/Config/Tabs.php
@@ -73,6 +73,8 @@ class Mage_Backend_Block_System_Config_Tabs extends Mage_Backend_Block_Widget
     protected $_storeCode;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -84,6 +86,8 @@ class Mage_Backend_Block_System_Config_Tabs extends Mage_Backend_Block_Widget
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Backend_Model_Config_Structure $configStructure
      * @param array $data
@@ -102,12 +106,15 @@ class Mage_Backend_Block_System_Config_Tabs extends Mage_Backend_Block_Widget
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Backend_Model_Config_Structure $configStructure,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
+        );
         $this->_tabs = $configStructure->getTabs();
 
         $this->setId('system_config_tabs');
diff --git a/app/code/core/Mage/Backend/Block/Template.php b/app/code/core/Mage/Backend/Block/Template.php
index 8bcdb7dcc50..5a125de297a 100644
--- a/app/code/core/Mage/Backend/Block/Template.php
+++ b/app/code/core/Mage/Backend/Block/Template.php
@@ -49,6 +49,8 @@ class Mage_Backend_Block_Template extends Mage_Core_Block_Template
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param array $data
      *
@@ -66,11 +68,13 @@ class Mage_Backend_Block_Template extends Mage_Core_Block_Template
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data);
     }
 
     /**
diff --git a/app/code/core/Mage/Backend/Block/Widget/Form/Element/Dependence.php b/app/code/core/Mage/Backend/Block/Widget/Form/Element/Dependence.php
index 9429e122de3..464ccd6377d 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Form/Element/Dependence.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Form/Element/Dependence.php
@@ -29,7 +29,7 @@
  * Assumes that one element may depend on other element values.
  * Will toggle as "enabled" only if all elements it depends from toggle as true.
  */
-class Mage_Backend_Block_Widget_Form_Element_Dependence extends Mage_Backend_Block_Abstract
+class Mage_Backend_Block_Widget_Form_Element_Dependence extends Mage_Core_Block_Template
 {
     /**
      * name => id mapper
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/Column.php b/app/code/core/Mage/Backend/Block/Widget/Grid/Column.php
index 7c45a2c456f..5f9d1502f7d 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Grid/Column.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/Column.php
@@ -67,24 +67,26 @@ class Mage_Backend_Block_Widget_Grid_Column extends Mage_Backend_Block_Widget
      * @var array
      */
     protected $_rendererTypes = array(
-        'date' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Date',
-        'datetime' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Datetime',
-        'number' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Number',
-        'currency' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Currency',
-        'price' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Price',
-        'country' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Country',
-        'concat' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Concat',
-        'action' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Action',
-        'options' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Options',
-        'checkbox' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Checkbox',
+        'action'     => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Action',
+        'button'     => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Button',
+        'checkbox'   => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Checkbox',
+        'concat'     => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Concat',
+        'country'    => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Country',
+        'currency'   => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Currency',
+        'date'       => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Date',
+        'datetime'   => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Datetime',
+        'default'    => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Text',
+        'grip'       => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Grip',
+        'input'      => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Input',
         'massaction' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Massaction',
-        'radio' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Radio',
-        'input' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Input',
-        'select' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Select',
-        'text' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Longtext',
-        'store' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Store',
-        'wrapline' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Wrapline',
-        'default' => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Text',
+        'number'     => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Number',
+        'options'    => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Options',
+        'price'      => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Price',
+        'radio'      => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Radio',
+        'select'     => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Select',
+        'store'      => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Store',
+        'text'       => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Longtext',
+        'wrapline'   => 'Mage_Backend_Block_Widget_Grid_Column_Renderer_Wrapline',
     );
 
     /**
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Filter/Abstract.php b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Filter/Abstract.php
index 8ffe8e65435..d1255f36132 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Filter/Abstract.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Filter/Abstract.php
@@ -31,7 +31,7 @@
  * @package    Mage_Backend
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Backend_Block_Widget_Grid_Column_Filter_Abstract extends Mage_Backend_Block_Abstract
+class Mage_Backend_Block_Widget_Grid_Column_Filter_Abstract extends Mage_Core_Block_Template
     implements Mage_Backend_Block_Widget_Grid_Column_Filter_Interface
 {
 
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Multistore.php b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Multistore.php
index 378c20fafd0..4b0eac884b1 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Multistore.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Multistore.php
@@ -41,6 +41,8 @@ class Mage_Backend_Block_Widget_Grid_Column_Multistore extends Mage_Backend_Bloc
     protected $_app;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -52,6 +54,8 @@ class Mage_Backend_Block_Widget_Grid_Column_Multistore extends Mage_Backend_Bloc
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_App $application
      * @param array $data
@@ -70,12 +74,14 @@ class Mage_Backend_Block_Widget_Grid_Column_Multistore extends Mage_Backend_Bloc
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_App $application,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
         $this->_app = $application;
     }
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Abstract.php b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Abstract.php
index 3d5d3b39490..cacd32d8e99 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Abstract.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Abstract.php
@@ -33,7 +33,7 @@
  */
 
 abstract class Mage_Backend_Block_Widget_Grid_Column_Renderer_Abstract
-    extends Mage_Backend_Block_Abstract implements Mage_Backend_Block_Widget_Grid_Column_Renderer_Interface
+    extends Mage_Core_Block_Template implements Mage_Backend_Block_Widget_Grid_Column_Renderer_Interface
 {
     protected $_defaultWidth;
     protected $_column;
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Button.php b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Button.php
new file mode 100644
index 00000000000..51f6e5772d3
--- /dev/null
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Button.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Block_Widget_Grid_Column_Renderer_Button
+    extends Mage_Backend_Block_Widget_Grid_Column_Renderer_Abstract
+{
+    /**
+     * Render grid row
+     *
+     * @param Varien_Object $row
+     * @return string
+     */
+    public function render(Varien_Object $row)
+    {
+        $buttonType = $this->getColumn()->getButtonType();
+        return '<button'
+            . ($buttonType ? ' type="' . $buttonType . '"' : '')
+            .'>'
+            . $this->getColumn()->getHeader()
+            . '</button>';
+    }
+}
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Currency.php b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
index 7d6cf0f49a8..70b849f819b 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
@@ -62,6 +62,8 @@ class Mage_Backend_Block_Widget_Grid_Column_Renderer_Currency
     protected $_currencyLocator;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -73,8 +75,10 @@ class Mage_Backend_Block_Widget_Grid_Column_Renderer_Currency
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
-     * @param Mage_Core_MOdel_App $app
+     * @param Mage_Core_Model_App $app
      * @param Mage_Core_Model_Locale $locale
      * @param Mage_Directory_Model_Currency_DefaultLocator $currencyLocator
      * @param array $data
@@ -93,14 +97,17 @@ class Mage_Backend_Block_Widget_Grid_Column_Renderer_Currency
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
-        Mage_Core_MOdel_App $app,
+        Mage_Core_Model_App $app,
         Mage_Core_Model_Locale $locale,
         Mage_Directory_Model_Currency_DefaultLocator $currencyLocator,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
+        );
         $this->_app = $app;
         $this->_locale = $locale;
         $this->_currencyLocator = $currencyLocator;
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Grip.php b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Grip.php
new file mode 100644
index 00000000000..9d6f8f9dc29
--- /dev/null
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/Column/Renderer/Grip.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.
+ *
+ * @category    Mage
+ * @package     Mage_Backend
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Backend_Block_Widget_Grid_Column_Renderer_Grip
+    extends Mage_Backend_Block_Widget_Grid_Column_Renderer_Abstract
+{
+    /**
+     * Render grid row
+     *
+     * @param Varien_Object $row
+     * @return string
+     */
+    public function render(Varien_Object $row)
+    {
+        return '<span class="' . $this->getColumn()->getInlineCss() . '"></span>'
+            . '<input type="hidden" name="entity_id" value="' . $row->getData($this->getColumn()->getIndex()) . '"/>'
+            . '<input type="hidden" name="position" value=""/>';
+    }
+}
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php b/app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php
index 43ff0f47db5..b5acc9dcc7b 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/ColumnSet.php
@@ -121,6 +121,8 @@ class Mage_Backend_Block_Widget_Grid_ColumnSet extends Mage_Core_Block_Template
     protected $_totals = null;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -132,6 +134,8 @@ class Mage_Backend_Block_Widget_Grid_ColumnSet extends Mage_Core_Block_Template
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Backend_Helper_Data $helper
      * @param Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory $generatorFactory
@@ -154,6 +158,8 @@ class Mage_Backend_Block_Widget_Grid_ColumnSet extends Mage_Core_Block_Template
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Backend_Helper_Data $helper,
         Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory $generatorFactory,
@@ -178,7 +184,7 @@ class Mage_Backend_Block_Widget_Grid_ColumnSet extends Mage_Core_Block_Template
         );
 
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data);
 
         $this->setEmptyText($this->_helper->__(
             isset($data['empty_text'])? $data['empty_text'] : 'No records found.'
diff --git a/app/code/core/Mage/Backend/Block/Widget/Grid/Massaction/Abstract.php b/app/code/core/Mage/Backend/Block/Widget/Grid/Massaction/Abstract.php
index 69edb6106b7..40e83c96eeb 100644
--- a/app/code/core/Mage/Backend/Block/Widget/Grid/Massaction/Abstract.php
+++ b/app/code/core/Mage/Backend/Block/Widget/Grid/Massaction/Abstract.php
@@ -331,8 +331,11 @@ abstract class Mage_Backend_Block_Widget_Grid_Massaction_Abstract extends Mage_B
             ->setGrid($gridBlock)
             ->setId($columnId);
 
+        /** @var $columnSetBlock Mage_Backend_Block_Widget_Grid_ColumnSet */
         $columnSetBlock = $gridBlock->getColumnSet();
-        $columnSetBlock->insert($massactionColumn, count($columnSetBlock->getColumns()) + 1, false, $columnId);
+        $childNames = $columnSetBlock->getChildNames();
+        $siblingElement = count($childNames) ? current($childNames) : 0;
+        $columnSetBlock->insert($massactionColumn, $siblingElement, false, $columnId);
         return $this;
     }
 }
diff --git a/app/code/core/Mage/Backend/Model/Config/Backend/Baseurl.php b/app/code/core/Mage/Backend/Model/Config/Backend/Baseurl.php
index fd7aef02d15..2871c24a2c4 100644
--- a/app/code/core/Mage/Backend/Model/Config/Backend/Baseurl.php
+++ b/app/code/core/Mage/Backend/Model/Config/Backend/Baseurl.php
@@ -18,42 +18,163 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Mage
- * @package     Mage_Backend
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
-
 class Mage_Backend_Model_Config_Backend_Baseurl extends Mage_Core_Model_Config_Data
 {
+    /**
+     * Validate a base URL field value
+     *
+     * @return Mage_Backend_Model_Config_Backend_Baseurl
+     * @throws Mage_Core_Exception
+     */
     protected function _beforeSave()
     {
         $value = $this->getValue();
-
-        if (!preg_match('#^{{((un)?secure_)?(base|public)_url}}#', $value)) {
-            $parsedUrl = parse_url($value);
-            if (!isset($parsedUrl['scheme']) || !isset($parsedUrl['host'])) {
-                $fieldConfig = $this->getFieldConfig();
-                $exceptionMsg = Mage::helper('Mage_Core_Helper_Data')
-                    ->__('The %s you entered is invalid. Please make sure that it follows "http://domain.com/" format.',
-                    $fieldConfig['label']
-                );
-                Mage::throwException($exceptionMsg);
+        try {
+            if (!$this->_validateUnsecure($value) && !$this->_validateSecure($value)) {
+                $this->_validateFullyQualifiedUrl($value);
             }
+        } catch (Mage_Core_Exception $e) {
+            $field = $this->getFieldConfig();
+            $label = ($field && is_array($field) ? $field['label'] : 'value');
+            $msg = Mage::helper('Mage_Backend_Helper_Data')->__('Invalid %s. %s', $label, $e->getMessage());
+            $error = new Mage_Core_Exception($msg, 0, $e);
+            throw $error;
+        }
+    }
+
+    /**
+     * Validation sub-routine for unsecure base URLs
+     *
+     * @param string $value
+     * @return bool
+     */
+    private function _validateUnsecure($value)
+    {
+        $placeholders = array('{{unsecure_base_url}}');
+        switch ($this->getPath()) {
+            case Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL:
+                $this->_assertValuesOrUrl(array('{{base_url}}'), $value);
+                break;
+            case Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LINK_URL:
+                $this->_assertStartsWithValuesOrUrl($placeholders, $value);
+                break;
+            case Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_MEDIA_URL:
+            case Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LIB_URL:
+                $this->_assertStartsWithValuesOrUrlOrEmpty($placeholders, $value);
+                break;
+            default:
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     * Validation sub-routine for secure base URLs
+     *
+     * @param string $value
+     * @return bool
+     */
+    private function _validateSecure($value)
+    {
+        $placeholders = array('{{unsecure_base_url}}', '{{secure_base_url}}');
+        switch ($this->getPath()) {
+            case Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL:
+                $this->_assertValuesOrUrl(array('{{base_url}}', '{{unsecure_base_url}}'), $value);
+                break;
+            case Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LINK_URL:
+                $this->_assertStartsWithValuesOrUrl($placeholders, $value);
+                break;
+            case Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL:
+            case Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL:
+                $this->_assertStartsWithValuesOrUrlOrEmpty($placeholders, $value);
+                break;
+            default:
+                return false;
+        }
+        return true;
+    }
+
+    /**
+     * Value equals to one of provided items or is a URL
+     *
+     * @param array $values
+     * @param string $value
+     * @throws Mage_Core_Exception
+     */
+    private function _assertValuesOrUrl(array $values, $value)
+    {
+        if (!in_array($value, $values) && !$this->_isFullyQualifiedUrl($value)) {
+            throw new Mage_Core_Exception(Mage::helper('Mage_Backend_Helper_Data')
+                ->__('Value must be a URL or one of placeholders: %s', implode(',', $values)));
         }
+    }
 
-        $value = rtrim($value, '/');
-        /**
-         * If value is special ({{}}) we don't need add slash
-         */
-        if (!preg_match('#}}$#', $value)) {
-            $value.= '/';
+    /**
+     * Value starts with one of provided items or is a URL
+     *
+     * @param array $values
+     * @param string $value
+     * @throws Mage_Core_Exception
+     */
+    private function _assertStartsWithValuesOrUrl(array $values, $value)
+    {
+        $quoted = array_map('preg_quote', $values, array_fill(0, count($values), '/'));
+        if (!preg_match('/^(' . implode('|', $quoted) . ')(.+\/)?$/', $value) && !$this->_isFullyQualifiedUrl($value)) {
+            throw new Mage_Core_Exception(Mage::helper('Mage_Backend_Helper_Data')
+                ->__('Specify a URL or path that starts with placeholder(s): %s.', implode(', ', $values)));
+        }
+    }
+
+    /**
+     * Value starts with, empty or is a URL
+     *
+     * @param array $values
+     * @param string $value
+     * @throws Mage_Core_Exception
+     */
+    private function _assertStartsWithValuesOrUrlOrEmpty(array $values, $value)
+    {
+        if (empty($value)) {
+            return;
         }
+        try {
+            $this->_assertStartsWithValuesOrUrl($values, $value);
+        } catch (Mage_Core_Exception $e) {
+            $msg = Mage::helper('Mage_Backend_Helper_Data')
+                ->__('%s An empty value is allowed as well.', $e->getMessage());
+            $error = new Mage_Core_Exception($msg, 0, $e);
+            throw $error;
+        }
+    }
 
+    /**
+     * Default validation of a URL
+     *
+     * @param string $value
+     * @throws Mage_Core_Exception
+     */
+    private function _validateFullyQualifiedUrl($value)
+    {
+        if (!$this->_isFullyQualifiedUrl($value)) {
+            throw new Mage_Core_Exception(
+                Mage::helper('Mage_Backend_Helper_Data')->__('Specify a fully qualified URL.')
+            );
+        }
+    }
 
-        $this->setValue($value);
-        return $this;
+    /**
+     * Whether the provided value can be considered as a fully qualified URL
+     *
+     * @param string $value
+     * @return bool
+     */
+    private function _isFullyQualifiedUrl($value)
+    {
+        $url = parse_url($value);
+        return isset($url['scheme']) && isset($url['host']) && preg_match('/\/$/', $value);
     }
 
     /**
@@ -62,7 +183,16 @@ class Mage_Backend_Model_Config_Backend_Baseurl extends Mage_Core_Model_Config_D
     protected function _afterSave()
     {
         if ($this->isValueChanged()) {
-            Mage::getModel('Mage_Core_Model_Design_Package')->cleanMergedJsCss();
+            switch ($this->getPath()) {
+                case Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL:
+                case Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_MEDIA_URL:
+                case Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LIB_URL:
+                case Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL:
+                case Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL:
+                case Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL:
+                    Mage::getDesign()->cleanMergedJsCss();
+                    break;
+            }
         }
     }
 }
diff --git a/app/code/core/Mage/Backend/etc/adminhtml/system.xml b/app/code/core/Mage/Backend/etc/adminhtml/system.xml
index fade2e4deb1..dec72875b4b 100644
--- a/app/code/core/Mage/Backend/etc/adminhtml/system.xml
+++ b/app/code/core/Mage/Backend/etc/adminhtml/system.xml
@@ -126,6 +126,7 @@
                     <label>Design Theme</label>
                     <source_model>Mage_Core_Model_Theme::getLabelsCollectionForSystemConfiguration</source_model>
                     <backend_model>Mage_Core_Model_Design_Backend_Theme</backend_model>
+                    <comment><![CDATA[If no value is specified, the system default will be used. The system default may be modified by third party extensions.]]></comment>
                 </field>
                 <field id="ua_regexp" translate="label comment tooltip" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>User-Agent Exceptions</label>
@@ -498,45 +499,51 @@
                 </field>
             </group>
             <group id="unsecure" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>Unsecure</label>
-                <field id="base_url" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>Base URLs</label>
+                <comment>Any of the fields allow fully qualified URLs that end with '/' (slash) e.g. http://example.com/magento/</comment>
+                <field id="base_url" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Base URL</label>
                     <backend_model>Mage_Backend_Model_Config_Backend_Baseurl</backend_model>
+                    <comment>Specify URL or {{base_url}} placeholder.</comment>
                 </field>
                 <field id="base_link_url" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Base Link URL</label>
                     <backend_model>Mage_Backend_Model_Config_Backend_Baseurl</backend_model>
+                    <comment>May start with {{unsecure_base_url}} placeholder.</comment>
                 </field>
-                <field id="base_public_url" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Base URL for Public Static Files</label>
+                <field id="base_lib_url" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Base URL for Library Files</label>
                     <backend_model>Mage_Backend_Model_Config_Backend_Baseurl</backend_model>
-                    <comment>&lt;strong style="color:red"&gt;Warning!&lt;/strong&gt; When using CDN, in some cases JavaScript may not run properly if CDN is not in your subdomain</comment>
+                    <comment>May be empty or start with {{unsecure_base_url}} placeholder. &lt;br/&gt; &lt;strong style="color:red"&gt;Warning!&lt;/strong&gt; When using CDN, in some cases JavaScript may not run properly if CDN is not in your subdomain</comment>
                 </field>
                 <field id="base_media_url" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Base Media URL</label>
+                    <label>Base URL for Media Files</label>
                     <backend_model>Mage_Backend_Model_Config_Backend_Baseurl</backend_model>
+                    <comment>May be empty or start with {{unsecure_base_url}} placeholder.</comment>
                 </field>
             </group>
             <group id="secure" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>Secure</label>
+                <label>Base URLs (Secure)</label>
+                <comment>Any of the fields allow fully qualified URLs that end with '/' (slash) e.g. http://example.com/magento/</comment>
                 <field id="base_url" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Base URL</label>
+                    <label>Secure Base URL</label>
                     <backend_model>Mage_Backend_Model_Config_Backend_Baseurl</backend_model>
-                    <comment>Make sure that base URL ends with '/' (slash), e.g. http://yourdomain/magento/</comment>
+                    <comment>Specify URL or {{base_url}}, or {{unsecure_base_url}} placeholder.</comment>
                 </field>
-                <field id="base_link_url" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Base Link URL</label>
+                <field id="base_link_url" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Secure Base Link URL</label>
                     <backend_model>Mage_Backend_Model_Config_Backend_Baseurl</backend_model>
-                    <comment>Make sure that base URL ends with '/' (slash), e.g. http://yourdomain/magento/</comment>
+                    <comment>May start with {{secure_base_url}} or {{unsecure_base_url}} placeholder.</comment>
                 </field>
-                <field id="base_public_url" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Base URL for Public Static Files</label>
+                <field id="base_lib_url" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Secure Base URL for Library Files</label>
                     <backend_model>Mage_Backend_Model_Config_Backend_Baseurl</backend_model>
-                    <comment>&lt;strong style="color:red"&gt;Warning!&lt;/strong&gt; When using CDN, in some cases JavaScript may not run properly if CDN is not in your subdomain</comment>
+                    <comment>May be empty or start with {{secure_base_url}}, or {{unsecure_base_url}} placeholder.</comment>
                 </field>
                 <field id="base_media_url" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Base Media URL</label>
+                    <label>Secure Base URL for Media Files</label>
                     <backend_model>Mage_Backend_Model_Config_Backend_Baseurl</backend_model>
+                    <comment>May be empty or start with {{secure_base_url}}, or {{unsecure_base_url}} placeholder.</comment>
                 </field>
                 <field id="use_in_frontend" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Use Secure URLs in Frontend</label>
diff --git a/app/code/core/Mage/Backend/view/adminhtml/widget/grid.phtml b/app/code/core/Mage/Backend/view/adminhtml/widget/grid.phtml
index f102cb97032..dbff31c365f 100644
--- a/app/code/core/Mage/Backend/view/adminhtml/widget/grid.phtml
+++ b/app/code/core/Mage/Backend/view/adminhtml/widget/grid.phtml
@@ -134,6 +134,10 @@ $numColumns = sizeof($this->getColumns());
     <?php if ($this->getCheckboxCheckCallback()): ?>
         <?php echo $this->getJsObjectName() ?>.checkboxCheckCallback = <?php echo $this->getCheckboxCheckCallback() ?>;
     <?php endif; ?>
+    <?php if ($this->getSortableUpdateCallback()): ?>
+        <?php echo $this->getJsObjectName() ?>.sortableUpdateCallback = <?php echo $this->getSortableUpdateCallback()?>;
+    <?php endif; ?>
+    <?php echo $this->getJsObjectName() ?>.bindSortable();
     <?php if ($this->getRowInitCallback()): ?>
         <?php echo $this->getJsObjectName() ?>.initRowCallback = <?php echo $this->getRowInitCallback() ?>;
         <?php echo $this->getJsObjectName() ?>.initGridRows();
diff --git a/app/code/core/Mage/Backend/view/adminhtml/widget/grid/serializer.phtml b/app/code/core/Mage/Backend/view/adminhtml/widget/grid/serializer.phtml
index db1ff39699d..9260fc85e3d 100644
--- a/app/code/core/Mage/Backend/view/adminhtml/widget/grid/serializer.phtml
+++ b/app/code/core/Mage/Backend/view/adminhtml/widget/grid/serializer.phtml
@@ -26,7 +26,7 @@
 ?>
 <?php
 /**
- * @var Mage_Backend_Block_Widget_Grid_Serializer
+ * @var $this Mage_Backend_Block_Widget_Grid_Serializer
  */
 ?>
 <?php $_id = 'id_' . md5(microtime()) ?>
diff --git a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/Extend.php b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/Extend.php
index b8e4b8540ba..dc44094df0c 100644
--- a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/Extend.php
+++ b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Attributes/Extend.php
@@ -85,8 +85,8 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Attributes_Extend
                             $('" . $this->getAttribute()->getAttributeCode() . "').removeClassName('required-entry');
                         }
 
-                        if ($('dynamic-price-warrning')) {
-                            $('dynamic-price-warrning').show();
+                        if ($('dynamic-price-warning')) {
+                            $('dynamic-price-warning').show();
                         }
                     } else {
                         if ($('" . $this->getAttribute()->getAttributeCode() . "')) {";
@@ -105,8 +105,8 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Attributes_Extend
 
             $html .= "}
 
-                        if ($('dynamic-price-warrning')) {
-                            $('dynamic-price-warrning').hide();
+                        if ($('dynamic-price-warning')) {
+                            $('dynamic-price-warning').hide();
                         }
                     }
                 }";
diff --git a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
index 3cfa4a58f23..21bc64d7c13 100644
--- a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
+++ b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
@@ -63,7 +63,7 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle extends Mage_A
     protected function _prepareLayout()
     {
         $this->addChild('add_button', 'Mage_Adminhtml_Block_Widget_Button', array(
-            'label' => Mage::helper('Mage_Bundle_Helper_Data')->__('Add New Option'),
+            'label' => Mage::helper('Mage_Bundle_Helper_Data')->__('Create New Option'),
             'class' => 'add',
             'id'    => 'add_new_option',
             'on_click' => 'bOption.add()'
diff --git a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
index a618e8245bc..7cb28967d4e 100644
--- a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
+++ b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
@@ -125,10 +125,9 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option extends
     protected function _prepareLayout()
     {
         $this->addChild('add_selection_button', 'Mage_Adminhtml_Block_Widget_Button', array(
-            'id'    => $this->getFieldId().'_{{index}}_add_button',
-            'label'     => Mage::helper('Mage_Bundle_Helper_Data')->__('Add Selection'),
-            'on_click'   => 'bSelection.showSearch(event)',
-            'class' => 'add'
+            'id'    => $this->getFieldId() . '_{{index}}_add_button',
+            'label' => Mage::helper('Mage_Bundle_Helper_Data')->__('Add Products to Option'),
+            'class' => 'add add-selection'
         ));
 
         $this->addChild('close_search_button', 'Mage_Adminhtml_Block_Widget_Button', array(
@@ -144,7 +143,10 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option extends
             'on_click' => 'bOption.remove(event)'
         ));
 
-        $this->addChild('selection_template', 'Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selection');
+        $this->addChild(
+            'selection_template',
+            'Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selection'
+        );
 
         return parent::_prepareLayout();
     }
@@ -217,7 +219,7 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option extends
 
     public function getTypeSelectHtml()
     {
-        $select = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+        $select = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setData(array(
                 'id' => $this->getFieldId().'_{{index}}_type',
                 'class' => 'select select-product-option-type required-option-select',
@@ -231,7 +233,7 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option extends
 
     public function getRequireSelectHtml()
     {
-        $select = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+        $select = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setData(array(
                 'id' => $this->getFieldId().'_{{index}}_required',
                 'class' => 'select'
@@ -244,6 +246,6 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option extends
 
     public function isDefaultStore()
     {
-        return ($this->getProduct()->getStoreId() == '0');
+        return $this->getProduct()->getStoreId() == '0';
     }
 }
diff --git a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search.php b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search.php
index 8936a2f809c..e8dbf667f01 100644
--- a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search.php
+++ b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search.php
@@ -34,52 +34,42 @@
 
 class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search extends Mage_Adminhtml_Block_Widget
 {
-
+    /**
+     * @var string
+     */
     protected $_template = 'product/edit/bundle/option/search.phtml';
 
     protected function _construct()
     {
         $this->setId('bundle_option_selection_search');
-
-    }
-
-    public function getHeaderText()
-    {
-        return Mage::helper('Mage_Bundle_Helper_Data')->__('Please Select Products to Add');
     }
 
+    /**
+     * Create search grid
+     *
+     * @return Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search
+     */
     protected function _prepareLayout()
     {
         $this->setChild(
             'grid',
             $this->getLayout()->createBlock(
                 'Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search_Grid',
-                'adminhtml.catalog.product.edit.tab.bundle.option.search.grid')
+                'adminhtml.catalog.product.edit.tab.bundle.option.search.grid'
+            )
         );
         return parent::_prepareLayout();
     }
 
+    /**
+     * Prepare search grid
+     *
+     * @return Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search
+     */
     protected function _beforeToHtml()
     {
         $this->getChildBlock('grid')->setIndex($this->getIndex())
             ->setFirstShow($this->getFirstShow());
-
         return parent::_beforeToHtml();
     }
-
-    public function getButtonsHtml()
-    {
-        $addButtonData = array(
-            'id'    => 'add_button_' . $this->getIndex(),
-            'label' => Mage::helper('Mage_Sales_Helper_Data')->__('Add Selected Product(s) to Option'),
-            'onclick' => 'bSelection.productGridAddSelected(event)',
-            'class' => 'add',
-        );
-        return $this->getLayout()->createBlock('Mage_Adminhtml_Block_Widget_Button')->setData($addButtonData)->toHtml();
-    }
-
-    public function getHeaderCssClass()
-    {
-        return 'head-catalog-product';
-    }
 }
diff --git a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search/Grid.php b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search/Grid.php
index b3e679acf48..fb88eb4faf6 100644
--- a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search/Grid.php
+++ b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Search/Grid.php
@@ -31,9 +31,9 @@
  * @package     Mage_Bundle
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search_Grid extends Mage_Adminhtml_Block_Widget_Grid
+class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search_Grid
+    extends Mage_Adminhtml_Block_Widget_Grid
 {
-
     protected function _construct()
     {
         parent::_construct();
@@ -45,18 +45,31 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search_
         $this->setUseAjax(true);
     }
 
-    protected function _beforeToHtml()
+    /**
+     * Prepare grid filter buttons
+     */
+    protected function _prepareFilterButtons()
     {
-        $this->setId($this->getId().'_'.$this->getIndex());
-        $this->getChildBlock('reset_filter_button')->setData('onclick', $this->getJsObjectName().'.resetFilter()');
-        $this->getChildBlock('search_button')->setData('onclick', $this->getJsObjectName().'.doFilter()');
+        $this->getChildBlock('reset_filter_button')->setData(
+            'onclick',
+            $this->getJsObjectName() . '.resetFilter(bSelection.gridUpdateCallback)'
+        );
+        $this->getChildBlock('search_button')->setData(
+            'onclick',
+            $this->getJsObjectName() . '.doFilter(bSelection.gridUpdateCallback)'
+        );
+    }
 
+    protected function _beforeToHtml()
+    {
+        $this->setId($this->getId() . '_' . $this->getIndex());
         return parent::_beforeToHtml();
     }
 
     protected function _prepareCollection()
     {
         $collection = Mage::getModel('Mage_Catalog_Model_Product')->getCollection()
+            ->setOrder('id')
             ->setStore($this->getStore())
             ->addAttributeToSelect('name')
             ->addAttributeToSelect('sku')
@@ -66,10 +79,6 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search_
             ->addFilterByRequiredOptions()
             ->addStoreFilter();
 
-        if ($products = $this->_getProducts()) {
-            $collection->addIdFilter($this->_getProducts(), true);
-        }
-
         if ($this->getFirstShow()) {
             $collection->addIdFilter('-1');
             $this->setEmptyText($this->__('Please enter search conditions to view products.'));
@@ -82,32 +91,19 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search_
 
     protected function _prepareColumns()
     {
-        $this->addColumn('id', array(
-            'header'    => Mage::helper('Mage_Sales_Helper_Data')->__('ID'),
-            'sortable'  => true,
-            'width'     => '60px',
-            'index'     => 'entity_id'
+        $this->addColumn('is_selected', array(
+            'header_css_class' => 'a-center',
+            'type'      => 'checkbox',
+            'name'      => 'in_selected',
+            'align'     => 'center',
+            'values'    => $this->_getSelectedProducts(),
+            'index'     => 'entity_id',
         ));
         $this->addColumn('name', array(
             'header'    => Mage::helper('Mage_Sales_Helper_Data')->__('Product Name'),
             'index'     => 'name',
             'column_css_class'=> 'name'
         ));
-
-        $sets = Mage::getResourceModel('Mage_Eav_Model_Resource_Entity_Attribute_Set_Collection')
-            ->setEntityTypeFilter(Mage::getModel('Mage_Catalog_Model_Product')->getResource()->getTypeId())
-            ->load()
-            ->toOptionHash();
-
-        $this->addColumn('set_name',
-            array(
-                'header'=> Mage::helper('Mage_Catalog_Helper_Data')->__('Attrib. Set Name'),
-                'width' => '100px',
-                'index' => 'attribute_set_id',
-                'type'  => 'options',
-                'options' => $sets,
-        ));
-
         $this->addColumn('sku', array(
             'header'    => Mage::helper('Mage_Sales_Helper_Data')->__('SKU'),
             'width'     => '80px',
@@ -122,29 +118,6 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search_
             'rate'      => $this->getStore()->getBaseCurrency()->getRate($this->getStore()->getCurrentCurrencyCode()),
             'index'     => 'price'
         ));
-
-        $this->addColumn('is_selected', array(
-            'header_css_class' => 'a-center',
-            'type'      => 'checkbox',
-            'name'      => 'in_selected',
-            'align'     => 'center',
-            'values'    => $this->_getSelectedProducts(),
-            'index'     => 'entity_id',
-        ));
-
-        $this->addColumn('qty', array(
-            'filter'    => false,
-            'sortable'  => false,
-            'header'    => Mage::helper('Mage_Sales_Helper_Data')->__('Qty to Add'),
-            'name'      => 'qty',
-            'inline_css'=> 'qty',
-            'align'     => 'right',
-            'type'      => 'input',
-            'validate_class' => 'validate-number',
-            'index'     => 'qty',
-            'width'     => '130px',
-        ));
-
         return parent::_prepareColumns();
     }
 
@@ -155,7 +128,10 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search_
 
     protected function _getSelectedProducts()
     {
-        $products = $this->getRequest()->getPost('selected_products', array());
+        $products = $this->getRequest()->getPost(
+            'selected_products',
+            explode(',', $this->getRequest()->getParam('productss'))
+        );
         return $products;
     }
 
diff --git a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php
index 482e8817b96..1aaacc3843d 100644
--- a/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php
+++ b/app/code/core/Mage/Bundle/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php
@@ -97,7 +97,7 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selecti
      */
     public function getPriceTypeSelectHtml()
     {
-        $select = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+        $select = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setData(array(
                 'id'    => $this->getFieldId() . '_{{index}}_price_type',
                 'class' => 'select select-product-option-type required-option-select'
@@ -117,7 +117,7 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selecti
      */
     public function getQtyTypeSelectHtml()
     {
-        $select = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+        $select = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setData(array(
                 'id' => $this->getFieldId().'_{{index}}_can_change_qty',
                 'class' => 'select'
@@ -135,7 +135,7 @@ class Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selecti
      */
     public function getSelectionSearchUrl()
     {
-        return $this->getUrl('*/bundle_selection/search');
+        return $this->getUrl('*/bundle_selection/grid');
     }
 
     /**
diff --git a/app/code/core/Mage/Bundle/view/adminhtml/css/bundle-product.css b/app/code/core/Mage/Bundle/view/adminhtml/css/bundle-product.css
new file mode 100644
index 00000000000..0ca525c5a28
--- /dev/null
+++ b/app/code/core/Mage/Bundle/view/adminhtml/css/bundle-product.css
@@ -0,0 +1,84 @@
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Bundle
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+
+#bundle_product_container {
+    padding-bottom: 15px;
+}
+
+#bundle_product_container .entry-edit > fieldset {
+    margin-bottom: 0;
+}
+
+#bundle_product_container .ui-icon-grip-dotted-vertical {
+    float: left;
+}
+
+#bundle_product_container .ui-icon-circle-triangle-s,
+#bundle_product_container .ui-icon-circle-close {
+    cursor: pointer;
+    float: right;
+    margin-left: 4px;
+}
+
+#bundle_product_container .option-box {
+    padding: 0;
+}
+
+#bundle_product_container .option-box .entry-edit-head .input-text {
+    width: 300px;
+}
+
+#bundle_product_container .option-box .option-header .select-product-option-type {
+    width: 120px;
+}
+
+#bundle_product_container .option-box .entry-edit-head .is-required {
+    margin-left: 4px;
+}
+
+#bundle_product_container .qty-box {
+    text-align: center;
+}
+
+#bundle_product_container .option-header .opt-input-type {
+    width: 130px;
+}
+
+#bundle_product_container .selection .product-sku {
+    width: 250px;
+}
+
+#add_new_option {
+    font-size: 18px;
+}
+
+#bundle_product_container .no-products-message {
+    border: #dadfe0 1px solid;
+    background: #fff;
+    margin: 10px 30px 0;
+    padding: 20px 40px;
+    text-align: center;
+    vertical-align: middle;
+}
diff --git a/app/code/core/Mage/Bundle/view/adminhtml/js/bundle-product.js b/app/code/core/Mage/Bundle/view/adminhtml/js/bundle-product.js
new file mode 100644
index 00000000000..c3decb6dbf3
--- /dev/null
+++ b/app/code/core/Mage/Bundle/view/adminhtml/js/bundle-product.js
@@ -0,0 +1,206 @@
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Bundle
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/*jshint browser:true jquery:true*/
+/*global FORM_KEY*/
+/*global bSelection*/
+(function($) {
+    $.widget('mage.bundleProduct', {
+        _create: function () {
+            this._initOptionBoxes();
+            this._initSortableSelections();
+            this._bindCheckboxHandlers();
+            this._bindAddSelectionDialog();
+            this._hideProductTypeSwitcher();
+            this._bindPanelVisibilityToggler();
+        },
+        _initOptionBoxes: function () {
+            this.element.sortable({
+                axis: 'y',
+                handle: '.entry-edit-head > .ui-icon-grip-dotted-vertical',
+                items: '.option-box',
+                update: this._updateOptionBoxPositions,
+                tolerance: 'pointer'
+            });
+
+            var syncOptionTitle = function (event) {
+                $(event.target).closest('.option-box').find('.head-edit-form').text($(event.target).val());
+            };
+            this._on({
+                'click .remove':  function (event) {
+                    $(event.target).closest('.option-box').find('.delete-product-option').trigger('click');
+                },
+                'click .toggle': function (event) {
+                    $(event.target).closest('.option-box').find('.option-header,.form-list,.selection-search').toggle();
+                },
+                'change .option-box input[name$="[title]"]': syncOptionTitle,
+                'keyup .option-box input[name$="[title]"]': syncOptionTitle
+            });
+        },
+        _initSortableSelections: function () {
+            this.element.find('.option-box .form-list tbody').sortable({
+                axis: 'y',
+                handle: '.ui-icon-grip-dotted-vertical',
+                helper: function(event, ui) {
+                    ui.children().each(function() {
+                        $(this).width($(this).width());
+                    });
+                    return ui;
+                },
+                update: this._updateSelectionsPositions,
+                tolerance: 'pointer'
+            });
+            this.element.find('.option-box').each(function () {
+                $(this).find('.add-selection').appendTo($(this));
+            });
+        },
+        _bindAddSelectionDialog: function () {
+            var widget = this;
+            this._on({'click .add-selection': function (event) {
+                var $optionBox = $(event.target).closest('.option-box'),
+                    $selectionGrid = $optionBox.find('.selection-search'),
+                    optionIndex = $optionBox.attr('id').replace('bundle_option_', ''),
+                    productIds = [],
+                    productSkus = [];
+
+                $optionBox.find('[name$="[product_id]"]').each(function () {
+                    if (!$(this).closest('tr').find('[name$="[delete]"]').val()) {
+                        productIds.push($(this).val());
+                        productSkus.push($(this).closest('tr').find('.product-sku').text());
+                    }
+                });
+
+                bSelection.gridSelection.set(optionIndex, $H({}));
+                bSelection.gridRemoval = $H({});
+                bSelection.gridSelectedProductSkus = productSkus;
+                $selectionGrid.dialog({
+                    title: $optionBox.find('input[name$="[title]"]').val() === '' ?
+                        'Add Products to New Option' :
+                        'Add Products to Option "' + $optionBox.find('input[name$="[title]"]').val() + '"',
+                    autoOpen: false,
+                    minWidth: 980,
+                    modal: true,
+                    resizable: true,
+                    buttons: [{
+                        text: 'Cancel',
+                        click: function() {
+                            $selectionGrid.dialog('close');
+                        }
+                    }, {
+                        text: 'Apply Changes',
+                        'class': 'add',
+                        click: function() {
+                            bSelection.gridSelection.get(optionIndex).each(
+                                function(pair) {
+                                    bSelection.addRow(optionIndex, {
+                                        name: pair.value.get('name'),
+                                        selection_price_value: 0,
+                                        selection_qty: 1,
+                                        sku: pair.value.get('sku'),
+                                        product_id: pair.key,
+                                        option_id: $('bundle_selection_id_' + optionIndex).val()
+                                    });
+                                }
+                            );
+                            bSelection.gridRemoval.each(
+                                function(pair) {
+                                    $optionBox.find('.product-sku').filter(function () {
+                                        return $.trim($(this).text()) == pair.key; // find row by SKU
+                                    }).closest('tr').find('button.delete').trigger('click');
+                                }
+                            );
+                            widget.refreshSortableElements();
+                            widget._updateSelectionsPositions.apply(widget.element);
+                            $selectionGrid.dialog('close');
+                        }
+                    }],
+                    close: function() {
+                        $(this).dialog('destroy');
+                    }
+                });
+
+                $.ajax({
+                    url: bSelection.selectionSearchUrl,
+                    dataType: 'html',
+                    data: {
+                        index: optionIndex,
+                        products: productIds,
+                        selected_products: productIds,
+                        form_key: FORM_KEY
+                    },
+                    success: function(data) {
+                        $selectionGrid.html(data).dialog('open');
+                    },
+                    context: $('body'),
+                    showLoader: true
+                });
+            }});
+        },
+        _hideProductTypeSwitcher: function () {
+            $('#weight_and_type_switcher, label[for=weight_and_type_switcher]').hide();
+        },
+        _bindPanelVisibilityToggler: function () {
+            var element = this.element;
+            this._on('#product_info_tabs', {
+                tabsbeforeactivate: function (event, ui) {
+                    element[$(ui.newPanel).find('#attribute-name-container').length ? 'show' : 'hide']();
+                }
+            });
+        },
+        _bindCheckboxHandlers: function () {
+            this._on({
+                'change .is-required': function (event) {
+                    var $this = $(event.target);
+                    $this.closest('.option-box').find('[name$="[required]"]').val($this.is(':checked') ? 1 : 0);
+                },
+                'change .is-user-defined-qty': function (event) {
+                    var $this = $(event.target);
+                    $this.closest('.qty-box').find('.select').val($this.is(':checked') ? 1 : 0);
+                }
+            });
+            this.element.find('.is-required').each(function () {
+                $(this).prop('checked', $(this).closest('.option-box').find('[name$="[required]"]').val() > 0);
+            });
+            this.element.find('.is-user-defined-qty').each(function () {
+                $(this).prop('checked', $(this).closest('.qty-box').find('.select').val() > 0);
+            });
+        },
+        _updateOptionBoxPositions: function () {
+            $(this).find('[name^=bundle_options][name$="[position]"]').each(function (index) {
+                $(this).val(index);
+            });
+        },
+        _updateSelectionsPositions: function () {
+            $(this).find('[name^=bundle_selections][name$="[position]"]').each(function (index) {
+                $(this).val(index);
+            });
+        },
+        refreshSortableElements: function () {
+            this.element.sortable('refresh');
+            this._updateOptionBoxPositions.apply(this.element);
+            this._initSortableSelections();
+            return this;
+        }
+    });
+})(jQuery);
diff --git a/app/code/core/Mage/Bundle/view/adminhtml/layout.xml b/app/code/core/Mage/Bundle/view/adminhtml/layout.xml
index b2584771ca6..6b42eaef507 100644
--- a/app/code/core/Mage/Bundle/view/adminhtml/layout.xml
+++ b/app/code/core/Mage/Bundle/view/adminhtml/layout.xml
@@ -29,7 +29,7 @@
 <layout>
 
 <!--
-Layout handle for budle products
+Layout handle for bundle products
 -->
 
     <!--<default>
@@ -39,9 +39,11 @@ Layout handle for budle products
     </default>-->
 
     <adminhtml_catalog_product_bundle>
-        <reference name="product_tabs">
-            <action method="addTab"><name>bundle_items</name><block>Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle</block></action>
-            <action method="bindShadowTabs"><first>bundle_items</first><second>customer_options</second></action>
+        <reference name="head">
+            <action method="addCss"><file>Mage_Bundle::css/bundle-product.css</file></action>
+        </reference>
+        <reference name="product-type-tabs">
+            <block type="Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle" name="bundle_items" />
         </reference>
     </adminhtml_catalog_product_bundle>
 
diff --git a/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle.phtml b/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle.phtml
index d5653c16673..7b02d320e23 100644
--- a/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle.phtml
+++ b/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle.phtml
@@ -23,6 +23,8 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
+
+/** @var $this Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle */
 ?>
 <script type="text/javascript">
 if(typeof Bundle=='undefined') {
@@ -30,34 +32,28 @@ if(typeof Bundle=='undefined') {
 }
 </script>
 
-<div class="entry-edit">
+<div class="entry-edit" id="bundle_product_container">
     <div class="entry-edit-head">
-        <h4 class="icon-head head-edit-form fieldset-legend"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Shipment') ?></h4>
+        <h4 class="icon-head head-edit-form fieldset-legend"><?php echo $this->getTabLabel() ?></h4>
     </div>
     <fieldset>
         <table cellspacing="0" class="form-list">
-        <tr>
-            <td class="label"><label for="shipment_type"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Ship Bundle Items') ?></label></td>
-            <td class="value"><select <?php if ($this->isReadonly()): ?>disabled="disabled" <?php endif;?>id="shipment_type" name="<?php echo $this->getFieldSuffix() ?>[shipment_type]" class="select">
-                <option value="1"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Separately') ?></option>
-                <option value="0"<?php if ($this->getProduct()->getShipmentType() == 0): ?> selected="selected"<?php endif; ?>><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Together') ?></option>
-            </select>
-            </td>
-        </tr>
+            <tr>
+                <td class="label"><label for="shipment_type"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Ship Bundle Items') ?></label></td>
+                <td class="value"><select <?php if ($this->isReadonly()): ?>disabled="disabled" <?php endif;?>id="shipment_type" name="<?php echo $this->getFieldSuffix() ?>[shipment_type]" class="select">
+                    <option value="1"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Separately') ?></option>
+                    <option value="0"<?php if ($this->getProduct()->getShipmentType() == 0): ?> selected="selected"<?php endif; ?>><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Together') ?></option>
+                </select>
+                </td>
+            </tr>
         </table>
-    </fieldset>
-</div>
 
-<div class="entry-edit custom-options bundle" id="product_bundle_container">
-    <div class="entry-edit-head">
-        <h4><?php echo $this->__('Bundle Items') ?></h4>
-        <div class="right"><?php echo $this->getAddButtonHtml() ?></div>
-    </div>
+        <div class="entry-edit custom-options bundle" id="product_bundle_container">
+            <?php echo $this->getOptionsBoxHtml() ?>
+        </div>
 
-    <div id="product_options_container" class="box">
-        <div id="product_bundle_container_top"></div>
-        <?php echo $this->getOptionsBoxHtml() ?>
-    </div>
+        <div class="a-center"><?php echo $this->getAddButtonHtml() ?></div>
+    </fieldset>
 </div>
 
 <script type="text/javascript">
@@ -80,6 +76,12 @@ Validation.add('validate-greater-zero-based-on-option', '<?php echo $this->__('P
     }
     return true;
 });
+
+jQuery(function($) {
+    head.js("<?php echo $this->getViewFileUrl('Mage_Bundle::js/bundle-product.js') ?>", function () {
+        $('#bundle_product_container').mage('bundleProduct');
+    });
+});
 </script>
 
 <div><input type="hidden" name="affect_bundle_product_selections" value="1" /></div>
diff --git a/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option.phtml b/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option.phtml
index 9554a172974..7295ff398a5 100644
--- a/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option.phtml
+++ b/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option.phtml
@@ -23,53 +23,100 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
+
+/** @var $this Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option */
+$columnCount = 5;
 ?>
-<script type="text/javascript">
-optionTemplate = '<div id="<?php echo $this->getFieldId() ?>_{{index}}"  class="option-box"> ' +
-'<div class="option-title"> ' +
-    '<label for="<?php echo $this->getFieldName() ?>[{{index}}][title]"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Default Title') ?> <span class="required">*</span></label>' +
-    <?php if ($this->isDefaultStore()): ?>
-    '<input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_title" value="{{title}}">' +
-    <?php else: ?>
-    '<input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][default_title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_default_title" value="{{default_title}}">' +
-    <?php endif; ?>
-<?php echo Mage::helper('Mage_Core_Helper_Data')->jsonEncode($this->getOptionDeleteButtonHtml()) ?> +
-'</div>' +
-    '<table class="option-header" cellpadding="0" cellspacing="0">' +
-        '<thead>' +
-            '<tr>' +
-                <?php if (!$this->isDefaultStore()): ?>
-                '<th class="opt-title"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Store View Title') ?>  <span class="required">*</span></th>' +
-                <?php endif; ?>
-                '<th class="opt-type"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Input Type') ?></th>' +
-                '<th class="opt-req"><?php echo $this->jsQuoteEscape(Mage::helper('Mage_Bundle_Helper_Data')->__('Is Required')) ?></th>' +
-                '<th class="opt-order"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Position') ?></th>' +
-                '<th>&nbsp;</th>' +
-            '</tr>' +
-        '</thead>' +
-        '<tbody>' +
-            '<tr>' +
-                '<input type="hidden" id="<?php echo $this->getFieldId() ?>_id_{{index}}" name="<?php echo $this->getFieldName() ?>[{{index}}][option_id]" value="{{option_id}}">' +
-                '<input type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][delete]" value="" class="delete">' +
-                <?php if (!$this->isDefaultStore()): ?>
-                '<td><input class="input-text required-entry" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][title]" id="id_<?php echo $this->getFieldName() ?>_{{index}}_title_store" value="{{title}}"></td>' +
+<script id="bundle-option-template" type="text/x-jquery-tmpl">
+    <div id="<?php echo $this->getFieldId() ?>_{{index}}" class="option-box">
+        <div class="option-title" style="display:none">
+            <?php echo $this->getOptionDeleteButtonHtml() ?>
+        </div>
+        <div class="entry-edit-head">
+            <span class="ui-icon ui-icon-grip-dotted-vertical"></span>
+            <h4 class="icon-head head-edit-form fieldset-legend">{{title}}</h4>
+            <span class="ui-icon ui-icon-circle-triangle-s toggle"></span>
+            <span class="ui-icon ui-icon-circle-close remove"></span>
+        </div>
+        <table class="option-header" cellpadding="0" cellspacing="0">
+            <thead>
+            <tr>
+                <th class="opt-title"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Default Title') ?>
+                    <span class="required">*</span>
+                </th>
+            <?php if (!$this->isDefaultStore()): $columnCount++; ?>
+                <th class="opt-title"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Store View Title') ?>
+                    <span class="required">*</span>
+                </th>
+            <?php endif; ?>
+                <th class="opt-input-type"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Input Type') ?></th>
+                <th class="opt-req">&nbsp;</th>
+                <th class="opt-order" style="display:none"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Position') ?></th>
+                <th>&nbsp;</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr>
+                <td>
+                <?php if ($this->isDefaultStore()): ?>
+                    <input class="input-text required-entry" type="text"
+                           name="<?php echo $this->getFieldName() ?>[{{index}}][title]"
+                           id="id_<?php echo $this->getFieldName() ?>_{{index}}_title" value="{{title}}" />
+                <?php else: ?>
+                    <input class="input-text required-entry" type="text"
+                           name="<?php echo $this->getFieldName() ?>[{{index}}][default_title]"
+                           id="id_<?php echo $this->getFieldName() ?>_{{index}}_default_title" value="{{default_title}}" />
                 <?php endif; ?>
-                '<td><?php echo $this->getTypeSelectHtml() ?></td>' +
-                '<td><?php echo $this->getRequireSelectHtml() ?></td>' +
-                '<td><input class="input-text validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{index}}][position]" value="{{position}}"></td>' +
-                '<td>&nbsp;' + <?php echo Mage::helper('Mage_Core_Helper_Data')->jsonEncode($this->getAddSelectionButtonHtml()) ?> + '</td>' +
-            '</tr>' +
-        '</tbody>' +
-    '</table>' +
-    '<div id="<?php echo $this->getFieldId() ?>_search_{{index}}">' +
-    '</div>' +
-'</div>';
+                    <input type="hidden" id="<?php echo $this->getFieldId() ?>_id_{{index}}"
+                           name="<?php echo $this->getFieldName() ?>[{{index}}][option_id]" value="{{option_id}}" />
+                    <input type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][delete]"
+                           value="" class="delete" />
+                </td>
+            <?php if (!$this->isDefaultStore()): ?>
+                <td>
+                    <input class="input-text required-entry" type="text"
+                           name="<?php echo $this->getFieldName() ?>[{{index}}][title]"
+                           id="id_<?php echo $this->getFieldName() ?>_{{index}}_title_store" value="{{title}}" />
+                </td>
+            <?php endif; ?>
+                <td class="opt-input-type"><?php echo $this->getTypeSelectHtml() ?></td>
+                <td class="opt-req">
+                    <label>
+                        <input type="checkbox" class="is-required" checked="checked" />
+                        <?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Required')?>
+                    </label>
+                    <span style="display:none"><?php echo $this->getRequireSelectHtml() ?></span>
+                </td>
+                <td class="opt-order" style="display:none">
+                    <input class="input-text validate-zero-or-greater" type="text"
+                           name="<?php echo $this->getFieldName() ?>[{{index}}][position]" value="{{position}}" />
+                </td>
+                <td>&nbsp;</td>
+            </tr>
+            <tr>
+                <td colspan="<?php echo $columnCount; ?>">
+                    <div class="no-products-message">
+                        <?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('There are no products in this option.')?>
+                    </div>
+                </td>
+            </tr>
+            </tbody>
+            <tfoot>
+            <tr>
+                <td><?php echo $this->getAddSelectionButtonHtml() ?></td>
+            </tr>
+            </tfoot>
+        </table>
+        <div id="<?php echo $this->getFieldId() ?>_search_{{index}}" class="selection-search"></div>
+    </div>
+</script>
+<script type="text/javascript">
+    var optionTemplate = jQuery('#bundle-option-template').html();
 </script>
 
 <?php echo $this->getSelectionHtml() ?>
 
 <script type="text/javascript">
-
 function changeInputType(oldObject, oType) {
     var newObject = document.createElement('input');
     newObject.type = oType;
@@ -86,30 +133,26 @@ function changeInputType(oldObject, oType) {
 Bundle.Option = Class.create();
 Bundle.Option.prototype = {
     idLabel : '<?php echo $this->getFieldId() ?>',
-    top : '',
     templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
     templateText : '',
     itemsCount : 0,
     initialize : function(template) {
         this.templateText = template;
-        this.top = $('product_bundle_container_top');
     },
 
     add : function(data) {
-        if(!data){
+        if (!data) {
             data = {};
-            this.top = $('product_bundle_container_top');
         } else {
-            data.title = data.title.replace('"', "&quot;");
+            data.title = data.title.replace(/</g, "&lt;");
+            data.title = data.title.replace(/"/g, "&quot;");
         }
 
         data.index = this.itemsCount++;
 
         this.template = new Template(this.templateText, this.templateSyntax);
 
-        Element.insert(this.top, {'after':this.template.evaluate(data)});
-
-        this.top = $(this.idLabel + '_' + data.index);
+        jQuery('#product_bundle_container').append(jQuery(this.template.evaluate(data)));
 
         //set selected type
         if (data.type) {
@@ -127,6 +170,10 @@ Bundle.Option.prototype = {
         // rebind change notifications
         varienWindowOnload(true);
 
+        if (jQuery && jQuery('#bundle_product_container').data('bundleProduct')) {
+            jQuery('#bundle_product_container').bundleProduct('refreshSortableElements');
+        }
+
         return data.index;
     },
 
@@ -203,33 +250,26 @@ Bundle.Option.prototype = {
             }
         );
     }
-}
+};
 
 var optionIndex = 0;
 bOption = new Bundle.Option(optionTemplate);
-//adding data to templates
-<?php foreach ($this->getOptions() as $_option): ?>
-optionIndex = bOption.add(<?php echo $_option->toJson() ?>);
-<?php if ($_option->getSelections()):?>
-    <?php foreach ($_option->getSelections() as $_selection): ?>
-    <?php $_selection->setName($this->escapeHtml($_selection->getName())); ?>
-bSelection.addRow(optionIndex, <?php echo $_selection->toJson() ?>);
-    <?php endforeach; ?>
-<?php endif; ?>
-<?php endforeach; ?>
-/**
- * Adding event on price type select box of product to hide or show prices for selections
- */
-function togglePriceType() {
-    if ($('price_type').value == '1') {
-        bOption.priceTypeFixed();
-    } else {
-        bOption.priceTypeDynamic();
+<?php
+    foreach ($this->getOptions() as $_option) {
+        /** @var $_option Mage_Bundle_Model_Option */
+        echo 'optionIndex = bOption.add(', $_option->toJson(), ');', PHP_EOL;
+        if ($_option->getSelections()) {
+            foreach ($_option->getSelections() as $_selection) {
+                /** @var $_selection Mage_Catalog_Model_Product */
+                $_selection->setName($this->escapeHtml($_selection->getName()));
+                echo 'bSelection.addRow(optionIndex,', $_selection->toJson(), ');', PHP_EOL;
+            }
+        }
     }
+?>
+function togglePriceType() {
+    bOption['priceType' + ($('price_type').value == '1' ? 'Fixed' : 'Dynamic')]();
 }
-
 togglePriceType();
-
 Event.observe('price_type', 'change', togglePriceType);
-
 </script>
diff --git a/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option/search.phtml b/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option/search.phtml
index 88ff45f13cd..e3844c3d7bb 100644
--- a/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option/search.phtml
+++ b/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option/search.phtml
@@ -23,13 +23,6 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-?>
-<div class="entry-edit">
-    <div class="entry-edit-head">
-        <div style="float: right;"><?php echo $this->getButtonsHtml() ?></div>
-        <h4 class="fieldset-legend <?php echo ($this->getHeaderCssClass()) ? $this->getHeaderCssClass().' icon-head' : '' ?>"><?php echo $this->getHeaderText() ?></h4>
-    </div>
-    <fieldset>
-        <?php echo $this->getChildHtml() ?>
-    </fieldset>
-</div>
+
+/** @var $this Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search */
+echo $this->getChildHtml();
diff --git a/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option/selection.phtml b/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option/selection.phtml
index 27e7ce46814..04ad0b43ac1 100644
--- a/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option/selection.phtml
+++ b/app/code/core/Mage/Bundle/view/adminhtml/product/edit/bundle/option/selection.phtml
@@ -23,54 +23,99 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
+
+/** @var $this Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Selection */
 ?>
-<script type="text/javascript">
-//<![CDATA[
-
-var bundleTemplateBox = '<table class="border" cellpadding="0" cellspacing="0">' +
-    '    <thead>' +
-    '        <tr class="headings">' +
-    '            <th><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Name') ?></th>' +
-    <?php if ($this->getCanReadPrice() !== false) : ?>
-    '            <th class="type-price price-type-box"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Price') ?></th>' +
-    '            <th class="type-type price-type-box"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Price Type') ?></th>' +
+<script id="bundle-option-selection-box-template" type="text/x-jquery-tmpl">
+    <table class="border" cellpadding="0" cellspacing="0">
+        <thead>
+            <tr class="headings">
+                <th style="width:1px">&nbsp;</th>
+                <th style="width:1px"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Default') ?></th>
+                <th class="product-name"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Name') ?></th>
+                <th class="product-sku"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('SKU') ?></th>
+            <?php if ($this->getCanReadPrice() !== false): ?>
+                <th class="type-price price-type-box"><?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('Price') ?></th>
+                <th class="type-type price-type-box"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Price Type') ?></th>
+            <?php endif; ?>
+                <th class="type-price"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Default Qty') ?></th>
+                <th class="type-uqty qty-box"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('User Defined Qty') ?></th>
+                <th class="type-order" style="display:none"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Position') ?></th>
+                <th class="last">&nbsp;</th>
+            </tr>
+        </thead>
+        <tbody>
+        </tbody>
+    </table>
+</script>
+<script id="bundle-option-selection-row-template" type="text/x-jquery-tmpl">
+    <td>
+        <span class="ui-icon ui-icon-grip-dotted-vertical"></span>
+        <input type="hidden" id="<?php echo $this->getFieldId() ?>_id_{{index}}"
+               name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_id]"
+               value="{{selection_id}}"/>
+        <input type="hidden" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][option_id]"
+               value="{{option_id}}"/>
+        <input type="hidden" class="product"
+               name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][product_id]"
+               value="{{product_id}}"/>
+        <input type="hidden" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][delete]"
+               value="" class="delete"/>
+    </td>
+    <td class="a-center">
+        <input onclick="bSelection.checkGroup(event)" type="{{option_type}}" class="default"
+               name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][is_default]"
+               value="1" {{checked}} />
+    </td>
+    <td class="product-name">{{name}}</td>
+    <td class="product-sku">{{sku}}</td>
+<?php if ($this->getCanReadPrice() !== false): ?>
+    <td class="price-type-box">
+        <input id="<?php echo $this->getFieldId() ?>_{{index}}_price_value"
+               class="input-text required-entry validate-zero-or-greater" type="text"
+               name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_price_value]"
+               value="{{selection_price_value}}"
+            <?php if($this->getCanEditPrice() === false): ?>
+               disabled="disabled"
+            <?php endif; ?>/>
+    </td>
+    <td class="price-type-box">
+        <?php echo $this->getPriceTypeSelectHtml() ?>
+        <div><?php echo $this->getCheckboxScopeHtml() ?></div>
+    </td>
+<?php else: ?>
+    <input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_value"
+           name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][selection_price_value]" value="0" />
+    <input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_type"
+           name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][selection_price_type]" value="0" />
+    <?php if ($this->isUsedWebsitePrice()): ?>
+    <input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_scope"
+           name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][default_price_scope]" value="1" />
     <?php endif; ?>
-    '            <th class="type-price"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Default Qty') ?></th>' +
-    '            <th class="type-uqty qty-box"><?php echo$this->jsQuoteEscape(Mage::helper('Mage_Bundle_Helper_Data')->__('User Defined Qty')) ?></th>' +
-    '            <th class="type-order"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Position') ?></th>' +
-    '            <th style="width:1px"><?php echo Mage::helper('Mage_Bundle_Helper_Data')->__('Default') ?></th>' +
-    '            <th class="last">&nbsp;</th>' +
-    '        </tr>' +
-    '    </thead> ' +
-    '    <tbody>' +
-    '    </tbody>' +
-    '</table>';
-
-var bundleTemplateRow ='<td>' +
-                '    <input type="hidden" id="<?php echo $this->getFieldId() ?>_id_{{index}}" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_id]" value="{{selection_id}}">' +
-                '    <input type="hidden" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][option_id]" value="{{option_id}}">' +
-                '    <input type="hidden" class="product" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][product_id]" value="{{product_id}}">' +
-                '    <input type="hidden" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][delete]" value="" class="delete">' +
-                '    {{name}}<br />' +
-                '   <div  class="nobr">' +
-                '        <strong><?php echo $this->helper('Mage_Sales_Helper_Data')->__('SKU') ?>:</strong> {{sku}}' +
-                '    </div>' +
-                '</td>' +
-                <?php if ($this->getCanReadPrice() !== false) : ?>
-                '<td class="price-type-box"><input id="<?php echo $this->getFieldId() ?>_{{index}}_price_value" class="input-text required-entry validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_price_value]" value="{{selection_price_value}}"<?php if($this->getCanEditPrice() === false) : ?> disabled="disabled"<?php endif; ?>></td>' +
-                '<td class="price-type-box"><?php echo $this->getPriceTypeSelectHtml() ?><div><?php echo $this->getCheckboxScopeHtml() ?></div></td>' +
-                <?php else : ?>
-                    '<input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_value" name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][selection_price_value]" value="0" />' +
-                    '<input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_type" name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][selection_price_type]" value="0" />' +
-                    <?php if ($this->isUsedWebsitePrice()): ?>
-                    '<input type="hidden" id="<?php echo $this->getFieldId(); ?>_{{index}}_price_scope" name="<?php echo $this->getFieldName(); ?>[{{parentIndex}}][{{index}}][default_price_scope]" value="1" />' +
-                    <?php endif; ?>
-                <?php endif; ?>
-                '<td><input class="input-text required-entry validate-greater-zero-based-on-option validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_qty]" value="{{selection_qty}}"></td>' +
-                '<td class="qty-box"><?php echo $this->getQtyTypeSelectHtml() ?></td>' +
-                '<td><input class="input-text required-entry validate-zero-or-greater" type="text" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][position]" value="{{position}}"></td>' +
-                '<td class="a-center"><input onclick="bSelection.checkGroup(event)" type="{{option_type}}" class="default" name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][is_default]" value="1" {{checked}}></td>' +
-                '<td class="last"><span title="Delete Row">' + <?php echo Mage::helper('Mage_Core_Helper_Data')->jsonEncode($this->getSelectionDeleteButtonHtml()) ?> + '</span></td>';
+<?php endif; ?>
+    <td>
+        <input class="input-text required-entry validate-greater-zero-based-on-option validate-zero-or-greater" type="text"
+               name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][selection_qty]"
+               value="{{selection_qty}}" />
+    </td>
+    <td class="qty-box">
+        <input type="checkbox" class="is-user-defined-qty" checked="checked" />
+        <span style="display:none"><?php echo $this->getQtyTypeSelectHtml() ?></span>
+    </td>
+    <td class="type-order" style="display:none">
+        <input class="input-text required-entry validate-zero-or-greater" type="text"
+               name="<?php echo $this->getFieldName() ?>[{{parentIndex}}][{{index}}][position]"
+               value="{{position}}" />
+    </td>
+    <td class="last">
+        <span title="Delete Row">
+            <?php echo $this->getSelectionDeleteButtonHtml() ?>
+        </span>
+    </td>
+</script>
+<script type="text/javascript">
+var bundleTemplateBox = jQuery('#bundle-option-selection-box-template').html(),
+    bundleTemplateRow = jQuery('#bundle-option-selection-row-template').html();
 
 Bundle.Selection = Class.create();
 Bundle.Selection.prototype = {
@@ -81,7 +126,10 @@ Bundle.Selection.prototype = {
     templateRow : '',
     itemsCount : 0,
     row : null,
-    gridSelection : new Hash(),
+    gridSelection: new Hash(),
+    gridRemoval: new Hash(),
+    gridSelectedProductSkus: [],
+    selectionSearchUrl: '<?php echo $this->getSelectionSearchUrl() ?>',
 
     initialize : function() {
         this.templateBox = '<div class="grid tier form-list" id="' + this.idLabel + '_box_{{parentIndex}}">' + bundleTemplateBox + '</div>';
@@ -89,31 +137,27 @@ Bundle.Selection.prototype = {
         this.templateRow = '<tr class="selection" id="' + this.idLabel + '_row_{{index}}">' + bundleTemplateRow + '</tr>';
     },
 
-    showSearch : function(event) {
-        var element = Event.findElement(event, 'div');
-        var parts = element.id.split('_');
-
-        var products = new Array();
-
-        var inputs = $A($$('#' + element.id + ' tr.selection input.product'));
-        for (i=0; i<inputs.length; i++) {
-            products.push(inputs[i].value);
-        }
-
-        this.gridSelection.set(parts[2], $H({}));
-
-        new Ajax.Updater(bOption.idLabel + '_search_' + parts[2], '<?php echo $this->getSelectionSearchUrl() ?>', {
-            method: 'post',
-            parameters : {'index' : parts[2], 'products[]' : products, 'form_key': FORM_KEY},
-            evalScripts : true
-        });
+    gridUpdateCallback: function () {
+        (function ($) {
+            var $grid = $('table[id^=bundle_selection_search_grid_]:visible');
+            $grid.find('.checkbox').prop({checked: false});
+
+            var checkRowBySku = function (sku) {
+                sku = $.trim(sku);
+                $grid('.sku').filter(function () {
+                    return $.trim($(this).text()) == sku;
+                }).closest('tr').find('.checkbox').prop({checked: true});
+            };
+            $.each(bSelection.gridSelection.values().pop().toArray(), function () {
+                checkRowBySku(this.pop().get('sku'));
+            });
 
-        if (Event.element(event).tagName.toLowerCase() != 'button') {
-            var button = Event.element(event).up('button');
-        } else {
-            var button = Event.element(event);
-        }
-        button.hide();
+            $.each(bSelection.gridSelectedProductSkus, function () {
+                if (!bSelection.gridRemoval.get(this)) {
+                    checkRowBySku(this);
+                }
+            });
+        })(jQuery);
     },
 
     addRow : function (parentIndex, data) {
@@ -153,7 +197,9 @@ Bundle.Selection.prototype = {
         this.template = new Template(this.templateRow, this.templateSyntax);
         var tbody = $$('#' + this.idLabel + '_box_' + parentIndex + ' tbody');
 
-        Element.insert(tbody[0], {'bottom':this.template.evaluate(data)});
+        // replace <script to avoid evalScripts() execution
+        var escapedHTML = this.template.evaluate(data).replace(/<(\/?)script/g, '&lt;$1script');
+        Element.insert(tbody[0], {bottom: escapedHTML});
 
         if (data.selection_price_type) {
             $A($(this.idLabel + '_'+data.index+'_price_type').options).each(function(option){
@@ -202,6 +248,8 @@ Bundle.Selection.prototype = {
                 }
             );
         }
+
+        jQuery('#bundle_option_' + parentIndex + ' .no-products-message').closest('tr').hide();
     },
 
     bindScopeCheckbox : function(){
@@ -231,7 +279,7 @@ Bundle.Selection.prototype = {
     },
 
     addBox : function (parentIndex) {
-        var div = $(bOption.idLabel + '_' + parentIndex)
+        var div = $(bOption.idLabel + '_' + parentIndex);
         this.template = new Template(this.templateBox, this.templateSyntax);
         var data = {'parentIndex' : parentIndex};
         Element.insert(div, {'bottom':this.template.evaluate(data)});
@@ -247,12 +295,10 @@ Bundle.Selection.prototype = {
             Element.removeClassName(element, 'selection');
             Element.hide(element);
 
-            if (container) {
-                if ($$('#' + container.id + ' tr.selection')) {
-                    if (!$$('#' + container.id + ' tr.selection').length) {
-                        container.hide();
-                    }
-                }
+            var selection = $$('#' + container.id + ' tr.selection');
+            if (container && selection && !selection.length) {
+                container.hide();
+                jQuery(element).closest('.option-box').find('.no-products-message').closest('tr').show();
             }
         }
     },
@@ -273,54 +319,30 @@ Bundle.Selection.prototype = {
         }
     },
 
-    productGridAddSelected : function(event) {
-        var element = Event.findElement(event, 'button');
-        var parts = element.id.split('_');
-
-        $(bOption.idLabel + '_search_' + parts[2]).innerHTML = '';
-        $(bOption.idLabel + '_' + parts[2] + '_add_button').show();
-
-        this.gridSelection.get(parts[2]).each(
-            function(pair) {
-                var qty = pair.value.get('qty');
-                var data = {
-                    'name' : pair.value.get('name'),
-                    'selection_price_value' : 0,
-                    'selection_qty' : (qty == '' ? 1 : qty),
-                    'sku' : pair.value.get('sku'),
-                    'position' : 0,
-                    'product_id' : pair.key,
-                    'option_id' : $(bOption.idLabel + '_id_' + parts[2]).value
-                };
-                bSelection.addRow(parts[2], data);
-            }
-        );
-    },
-
     productGridRowInit : function(grid, row){
         var checkbox = $(row).getElementsByClassName('checkbox')[0];
         var inputs = $(row).getElementsByClassName('input-text');
         for (var i = 0; i < inputs.length; i++) {
             inputs[i].checkbox = checkbox;
-            Event.observe(inputs[i], 'keyup', this.productGridRowInputChange.bind(this));
-            Event.observe(inputs[i], 'change', this.productGridRowInputChange.bind(this));
         }
     },
 
     productGridCheckboxCheck : function(grid, element, checked) {
         var id = element.up('table').id.split('_')[4];
         if (element.value > 0) {
+            var tr = element.parentNode.parentNode,
+                sku = jQuery.trim(tr.select('td.sku')[0].innerHTML);
             if (element.checked) {
-                var tr = element.parentNode.parentNode;
                 if (!this.gridSelection.get(id)) {
-                    this.gridSelection.set(id, new Hash());
+                    this.gridSelection.set(id, $H({}));
                 }
                 this.gridSelection.get(id).set(element.value, $H({}));
                 this.gridSelection.get(id).get(element.value).set('name', tr.select('td.name')[0].innerHTML);
-                this.gridSelection.get(id).get(element.value).set('qty', tr.select('input.qty')[0].value);
-                this.gridSelection.get(id).get(element.value).set('sku', tr.select('td.sku')[0].innerHTML);
+                this.gridSelection.get(id).get(element.value).set('sku', sku);
+                this.gridRemoval.unset(sku);
             } else {
                 this.gridSelection.get(id).unset(element.value);
+                this.gridRemoval.set(sku, 1);
             }
         }
     },
@@ -335,18 +357,8 @@ Bundle.Selection.prototype = {
                 grid.setCheckboxChecked(checkbox[0], checked);
             }
         }
-    },
-
-    productGridRowInputChange : function(event) {
-        var element = Event.element(event);
-        if (!element.checkbox.checked) {
-            return;
-        }
-        var id = element.up('table').id.split('_')[4];
-        this.gridSelection.get(id).get(element.checkbox.value).set('qty', element.value);
     }
-}
+};
 
 bSelection = new Bundle.Selection();
-//]]>
 </script>
diff --git a/app/code/core/Mage/Captcha/Helper/Data.php b/app/code/core/Mage/Captcha/Helper/Data.php
index be91d72983c..34131609db0 100755
--- a/app/code/core/Mage/Captcha/Helper/Data.php
+++ b/app/code/core/Mage/Captcha/Helper/Data.php
@@ -64,11 +64,6 @@ class Mage_Captcha_Helper_Data extends Mage_Core_Helper_Abstract
      */
     protected $_captcha = array();
 
-    /**
-     * @var Mage_Core_Model_Config_Options
-     */
-    protected $_option;
-
     /**
      * @var Mage_Core_Model_Config
      */
@@ -79,21 +74,29 @@ class Mage_Captcha_Helper_Data extends Mage_Core_Helper_Abstract
      */
     protected $_filesystem;
 
+    /**
+     * @var Mage_Core_Model_Dir
+     */
+    protected $_dirs = null;
+
     /**
      * @var Mage_Core_Model_App
      */
     protected $_app;
 
     /**
+     * @param Mage_Core_Model_Dir $dirs
      * @param Mage_Core_Model_App $app
      * @param Mage_Core_Model_Config $config
      * @param Magento_Filesystem $filesystem
      */
     public function __construct(
+        Mage_Core_Model_Dir $dirs,
         Mage_Core_Model_App $app,
         Mage_Core_Model_Config $config,
         Magento_Filesystem $filesystem
     ) {
+        $this->_dirs = $dirs;
         $this->_app = $app;
         $this->_config = $config;
         $this->_filesystem = $filesystem;
@@ -133,7 +136,7 @@ class Mage_Captcha_Helper_Data extends Mage_Core_Helper_Abstract
     {
         $store = $this->_app->getStore($store);
         $areaCode = $store->isAdmin() ? 'admin' : 'customer';
-        return $store->getConfig($areaCode . '/captcha/' . $id, $store);
+        return $store->getConfig($areaCode . '/captcha/' . $id);
     }
 
     /**
@@ -149,10 +152,11 @@ class Mage_Captcha_Helper_Data extends Mage_Core_Helper_Abstract
         $node = $this->_config->getNode(Mage_Captcha_Helper_Data::XML_PATH_CAPTCHA_FONTS);
         $fonts = array();
         if ($node) {
+            $libDir = $this->_dirs->getDir(Mage_Core_Model_Dir::LIB);
             foreach ($node->children() as $fontName => $fontNode) {
                 $fonts[$fontName] = array(
                     'label' => (string)$fontNode->label,
-                    'path' => $this->_config->getOptions()->getDir('base') . DIRECTORY_SEPARATOR . $fontNode->path
+                    'path' => $libDir . DIRECTORY_SEPARATOR . $fontNode->path
                 );
             }
         }
@@ -167,7 +171,7 @@ class Mage_Captcha_Helper_Data extends Mage_Core_Helper_Abstract
      */
     public function getImgDir($website = null)
     {
-        $mediaDir = $this->_config->getOptions()->getDir('media');
+        $mediaDir =  $this->_dirs->getDir(Mage_Core_Model_Dir::MEDIA);
         $captchaDir = Magento_Filesystem::getPathFromArray(array($mediaDir, 'captcha',
             $this->_app->getWebsite($website)->getCode()));
         $this->_filesystem->setWorkingDirectory($mediaDir);
@@ -184,7 +188,7 @@ class Mage_Captcha_Helper_Data extends Mage_Core_Helper_Abstract
      */
     public function getImgUrl($website = null)
     {
-        return $this->_app->getStore()->getBaseUrl('media') . 'captcha'
+        return $this->_app->getStore()->getBaseUrl(Mage_Core_Model_Dir::MEDIA) . 'captcha'
             . '/' . $this->_app->getWebsite($website)->getCode() . '/';
     }
 }
diff --git a/app/code/core/Mage/Captcha/Model/Zend.php b/app/code/core/Mage/Captcha/Model/Zend.php
index 063e4862e1c..2d177c89737 100755
--- a/app/code/core/Mage/Captcha/Model/Zend.php
+++ b/app/code/core/Mage/Captcha/Model/Zend.php
@@ -49,10 +49,9 @@ class Mage_Captcha_Model_Zend extends Zend_Captcha_Image implements Mage_Captcha
     const DEFAULT_WORD_LENGTH_TO   = 5;
 
     /**
-     * Helper Instance
-     * @var Mage_Captcha_Helper_Data
+     * @var Magento_ObjectManager|null
      */
-    protected $_helper = null;
+    protected $_objectManager = null;
 
     /**
      * Captcha expire time
@@ -87,16 +86,18 @@ class Mage_Captcha_Model_Zend extends Zend_Captcha_Image implements Mage_Captcha
     /**
      * Zend captcha constructor
      *
-     * @param array $params
+     * @param Magento_ObjectManager $objectManager
+     * @param $params
+     * @throws Exception
      */
-    public function __construct($params)
+    public function __construct(Magento_ObjectManager $objectManager, $params)
     {
         if (!is_array($params) || !isset($params['formId'])) {
             throw new Exception('formId is mandatory');
         }
 
         $this->_formId = $params['formId'];
-        $this->_helper = isset($params['helper']) ? $params['helper'] : null;
+        $this->_objectManager = $objectManager;
         $this->_resourceModel = isset($params['resourceModel']) ? $params['resourceModel'] : null;
         $this->_session = isset($params['session']) ? $params['session'] : null;
     }
@@ -355,10 +356,7 @@ class Mage_Captcha_Model_Zend extends Zend_Captcha_Image implements Mage_Captcha
      */
     protected function _getHelper()
     {
-        if (empty($this->_helper)) {
-            $this->_helper = Mage::helper('Mage_Captcha_Helper_Data');
-        }
-        return $this->_helper;
+        return $this->_objectManager->get('Mage_Captcha_Helper_Data');
     }
 
     /**
diff --git a/app/code/core/Mage/Captcha/etc/config.xml b/app/code/core/Mage/Captcha/etc/config.xml
index 2603c37b5ef..9dfceb9e55e 100755
--- a/app/code/core/Mage/Captcha/etc/config.xml
+++ b/app/code/core/Mage/Captcha/etc/config.xml
@@ -226,7 +226,7 @@
             <fonts>
                 <linlibertine>
                     <label>LinLibertine</label>
-                    <path>lib/LinLibertineFont/LinLibertine_Bd-2.8.1.ttf</path>
+                    <path>LinLibertineFont/LinLibertine_Bd-2.8.1.ttf</path>
                 </linlibertine>
             </fonts>
             <frontend>
diff --git a/app/code/core/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php b/app/code/core/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php
index 07562d12b8d..410a83d0ec8 100644
--- a/app/code/core/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php
+++ b/app/code/core/Mage/Catalog/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php
@@ -62,6 +62,8 @@ class Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_Co
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory $generatorFactory
      * @param Mage_Core_Model_Registry $registryManager,
@@ -84,6 +86,8 @@ class Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_Co
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory $generatorFactory,
         Mage_Core_Model_Registry $registryManager,
@@ -93,7 +97,7 @@ class Mage_Catalog_Block_Product_Configurable_AssociatedSelector_Backend_Grid_Co
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem,
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem,
             $helperFactory->get('Mage_Backend_Helper_Data'), $generatorFactory, $subtotals, $totals, $data);
 
         $this->_registryManager = $registryManager;
diff --git a/app/code/core/Mage/Catalog/Block/Product/Grouped/AssociatedProducts.php b/app/code/core/Mage/Catalog/Block/Product/Grouped/AssociatedProducts.php
new file mode 100644
index 00000000000..e63a825b3d1
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Block/Product/Grouped/AssociatedProducts.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Catalog_Block_Product_Grouped_AssociatedProducts extends Mage_Backend_Block_Catalog_Product_Tab_Container
+{
+    protected function _construct()
+    {
+        parent::_construct();
+        $this->setId('grouped_product_container');
+    }
+
+    /**
+     * Return Tab label
+     *
+     * @return string
+     */
+    public function getTabLabel()
+    {
+        return Mage::helper('Mage_Catalog_Helper_Data')->__('Grouped Products');
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Block/Product/Grouped/AssociatedProducts/Grid.php b/app/code/core/Mage/Catalog/Block/Product/Grouped/AssociatedProducts/Grid.php
new file mode 100644
index 00000000000..fe6f85d9229
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Block/Product/Grouped/AssociatedProducts/Grid.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Products in grouped grid
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Block_Product_Grouped_AssociatedProducts_Grid extends Mage_Backend_Block_Widget_Grid
+{
+    /**
+     * Input name product data will be serialized into
+     */
+    protected $_hiddenInputName;
+
+    /**
+     * Names of the inputs to serialize
+     */
+    protected $_fieldsToSave = array();
+
+    protected function _construct()
+    {
+        parent::_construct();
+        $this->setId('super_product_grid');
+        $this->setDefaultSort('entity_id');
+        $this->setSkipGenerateContent(true);
+        $this->setUseAjax(true);
+    }
+
+    /**
+     * Retrieve grouped products
+     *
+     * @return array
+     */
+    public function getAssociatedProducts()
+    {
+        $associatedProducts = Mage::registry('current_product')->getTypeInstance()
+            ->getAssociatedProducts(Mage::registry('current_product'));
+        $products = array();
+        foreach ($associatedProducts as $product) {
+            $products[$product->getId()] = array(
+                'qty'       => $product->getQty(),
+                'position'  => $product->getPosition()
+            );
+        }
+        return $this->helper('Mage_Core_Helper_Data')->jsonEncode($products);
+    }
+
+    /**
+     * Get associated product ids
+     *
+     * @return array
+     */
+    public function getAssociatedProductIds()
+    {
+        $associatedProducts = Mage::registry('current_product')->getTypeInstance()
+            ->getAssociatedProducts(Mage::registry('current_product'));
+        $ids = array();
+        foreach ($associatedProducts as $product) {
+            $ids[] = $product->getId();
+        }
+        return $this->helper('Mage_Core_Helper_Data')->jsonEncode($ids);
+    }
+
+    /**
+     * Get hidden input name
+     *
+     * @return string
+     */
+    public function getHiddenInputName()
+    {
+        return $this->_hiddenInputName;
+    }
+
+    /**
+     * Get fields names
+     *
+     * @return array
+     */
+    public function getFieldsToSave()
+    {
+        return $this->_fieldsToSave;
+    }
+
+    /**
+     * Init function
+     *
+     * @param string $hiddenInputName
+     * @param array $fieldsToSave
+     */
+    public function setGridData($hiddenInputName, $fieldsToSave = array())
+    {
+        $this->_hiddenInputName = $hiddenInputName;
+        $this->_fieldsToSave = $fieldsToSave;
+    }
+
+    /**
+     * Callback for jQuery UI sortable update
+     *
+     * @return string
+     */
+    public function getSortableUpdateCallback()
+    {
+        return <<<SCRIPT
+function () {
+    if(jQuery && jQuery('#grouped-product-container').data('groupedProduct')) {
+        jQuery('#grouped-product-container').groupedProduct('updateRowsPositions');
+    }
+}
+SCRIPT;
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Model/Api/Resource.php b/app/code/core/Mage/Catalog/Model/Api/Resource.php
new file mode 100644
index 00000000000..ef968559942
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Api/Resource.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog api resource
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Api_Resource extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Default ignored attribute codes
+     *
+     * @var array
+     */
+    protected $_ignoredAttributeCodes = array('entity_id', 'attribute_set_id', 'entity_type_id');
+
+    /**
+     * Default ignored attribute types
+     *
+     * @var array
+     */
+    protected $_ignoredAttributeTypes = array();
+
+    /**
+     * Field name in session for saving store id
+     * @var string
+     */
+    protected $_storeIdSessionField   = 'store_id';
+
+    /**
+     * Check is attribute allowed
+     *
+     * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
+     * @param array $attributes
+     * @return boolean
+     */
+    protected function _isAllowedAttribute($attribute, $attributes = null)
+    {
+        if (is_array($attributes)
+            && !( in_array($attribute->getAttributeCode(), $attributes)
+                  || in_array($attribute->getAttributeId(), $attributes))) {
+            return false;
+        }
+
+        return !in_array($attribute->getFrontendInput(), $this->_ignoredAttributeTypes)
+               && !in_array($attribute->getAttributeCode(), $this->_ignoredAttributeCodes);
+    }
+
+    /**
+     * Retrives store id from store code, if no store id specified,
+     * it use seted session or admin store
+     *
+     * @param string|int $store
+     * @return int
+     */
+    protected function _getStoreId($store = null)
+    {
+        if (is_null($store)) {
+            $store = ($this->_getSession()->hasData($this->_storeIdSessionField)
+                        ? $this->_getSession()->getData($this->_storeIdSessionField) : 0);
+        }
+
+        try {
+            $storeId = Mage::app()->getStore($store)->getId();
+        } catch (Mage_Core_Model_Store_Exception $e) {
+            $this->_fault('store_not_exists');
+        }
+
+        return $storeId;
+    }
+
+    /**
+     * Return loaded product instance
+     *
+     * @param  int|string $productId (SKU or ID)
+     * @param  int|string $store
+     * @param  string $identifierType
+     * @return Mage_Catalog_Model_Product
+     */
+    protected function _getProduct($productId, $store = null, $identifierType = null)
+    {
+        $product = Mage::helper('Mage_Catalog_Helper_Product')->getProduct($productId, $this->_getStoreId($store), $identifierType);
+        if (is_null($product->getId())) {
+            $this->_fault('product_not_exists');
+        }
+        return $product;
+    }
+
+    /**
+     * Set current store for catalog.
+     *
+     * @param string|int $store
+     * @return int
+     */
+    public function currentStore($store=null)
+    {
+        if (!is_null($store)) {
+            try {
+                $storeId = Mage::app()->getStore($store)->getId();
+            } catch (Mage_Core_Model_Store_Exception $e) {
+                $this->_fault('store_not_exists');
+            }
+
+            $this->_getSession()->setData($this->_storeIdSessionField, $storeId);
+        }
+
+        return $this->_getStoreId();
+    }
+} // Class Mage_Catalog_Model_Api_Resource End
diff --git a/app/code/core/Mage/Catalog/Model/Category/Api.php b/app/code/core/Mage/Catalog/Model/Category/Api.php
new file mode 100644
index 00000000000..261101ce0bc
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Category/Api.php
@@ -0,0 +1,524 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog category api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Category_Api extends Mage_Catalog_Model_Api_Resource
+{
+    public function __construct()
+    {
+        $this->_storeIdSessionField = 'category_store_id';
+    }
+
+    /**
+     * Retrive level of categories for category/store view/website
+     *
+     * @param string|int $website
+     * @param string|int $store
+     * @param int $categoryId
+     * @return array
+     */
+    public function level($website = null, $store = null, $categoryId = null)
+    {
+        $ids = array();
+        $storeId = Mage_Catalog_Model_Category::DEFAULT_STORE_ID;
+
+        // load root categories of website
+        if (null !== $website) {
+            try {
+                $website = Mage::app()->getWebsite($website);
+                if (null === $store) {
+                    if (null === $categoryId) {
+                        foreach ($website->getStores() as $store) {
+                            /* @var $store Mage_Core_Model_Store */
+                            $ids[] = $store->getRootCategoryId();
+                        }
+                    } else {
+                        $ids = $categoryId;
+                    }
+                } elseif (in_array($store, $website->getStoreIds())) {
+                    $storeId = Mage::app()->getStore($store)->getId();
+                    $ids = (null === $categoryId)? $store->getRootCategoryId() : $categoryId;
+                } else {
+                    $this->_fault('store_not_exists');
+                }
+            } catch (Mage_Core_Exception $e) {
+                $this->_fault('website_not_exists', $e->getMessage());
+            }
+        }
+        elseif (null !== $store) {
+            // load children of root category of store
+            if (null === $categoryId) {
+                try {
+                    $store = Mage::app()->getStore($store);
+                    $storeId = $store->getId();
+                    $ids = $store->getRootCategoryId();
+                } catch (Mage_Core_Model_Store_Exception $e) {
+                    $this->_fault('store_not_exists');
+                }
+            }
+            // load children of specified category id
+            else {
+                $storeId = $this->_getStoreId($store);
+                $ids = (int)$categoryId;
+            }
+        }
+        // load all root categories
+        else {
+            $ids = (null === $categoryId)? Mage_Catalog_Model_Category::TREE_ROOT_ID : $categoryId;
+        }
+
+        $collection = Mage::getModel('Mage_Catalog_Model_Category')->getCollection()
+            ->setStoreId($storeId)
+            ->addAttributeToSelect('name')
+            ->addAttributeToSelect('is_active');
+
+        if (is_array($ids)) {
+            $collection->addFieldToFilter('entity_id', array('in' => $ids));
+        } else {
+            $collection->addFieldToFilter('parent_id', $ids);
+        }
+
+        // Only basic category data
+        $result = array();
+        foreach ($collection as $category) {
+            /* @var $category Mage_Catalog_Model_Category */
+            $result[] = array(
+                'category_id' => $category->getId(),
+                'parent_id'   => $category->getParentId(),
+                'name'        => $category->getName(),
+                'is_active'   => $category->getIsActive(),
+                'position'    => $category->getPosition(),
+                'level'       => $category->getLevel()
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve category tree
+     *
+     * @param int|null $parentId
+     * @param string|int|null $store
+     * @return array
+     */
+    public function tree($parentId = null, $store = null)
+    {
+        if (is_null($parentId) && !is_null($store)) {
+            $parentId = Mage::app()->getStore($this->_getStoreId($store))->getRootCategoryId();
+        } elseif (is_null($parentId)) {
+            $parentId = 1;
+        }
+
+        /* @var $tree Mage_Catalog_Model_Resource_Category_Tree */
+        $tree = Mage::getResourceSingleton('Mage_Catalog_Model_Resource_Category_Tree')
+            ->load();
+
+        $root = $tree->getNodeById($parentId);
+
+        if($root && $root->getId() == 1) {
+            $root->setName(Mage::helper('Mage_Catalog_Helper_Data')->__('Root'));
+        }
+
+        $collection = Mage::getModel('Mage_Catalog_Model_Category')->getCollection()
+            ->setStoreId($this->_getStoreId($store))
+            ->addAttributeToSelect('name')
+            ->addAttributeToSelect('is_active');
+
+        $tree->addCollectionData($collection, true);
+
+        return $this->_nodeToArray($root);
+    }
+
+    /**
+     * Convert node to array
+     *
+     * @param Varien_Data_Tree_Node $node
+     * @return array
+     */
+    protected function _nodeToArray(Varien_Data_Tree_Node $node)
+    {
+        // Only basic category data
+        $result = array();
+        $result['category_id'] = $node->getId();
+        $result['parent_id']   = $node->getParentId();
+        $result['name']        = $node->getName();
+        $result['is_active']   = $node->getIsActive();
+        $result['position']    = $node->getPosition();
+        $result['level']       = $node->getLevel();
+        $result['children']    = array();
+
+        foreach ($node->getChildren() as $child) {
+            $result['children'][] = $this->_nodeToArray($child);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Initialize and return category model
+     *
+     * @param int $categoryId
+     * @param string|int $store
+     * @return Mage_Catalog_Model_Category
+     */
+    protected function _initCategory($categoryId, $store = null)
+    {
+        $category = Mage::getModel('Mage_Catalog_Model_Category')
+            ->setStoreId($this->_getStoreId($store))
+            ->load($categoryId);
+
+        if (!$category->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        return $category;
+    }
+
+    /**
+     * Retrieve category data
+     *
+     * @param int $categoryId
+     * @param string|int $store
+     * @param array $attributes
+     * @return array
+     */
+    public function info($categoryId, $store = null, $attributes = null)
+    {
+        $category = $this->_initCategory($categoryId, $store);
+
+        // Basic category data
+        $result = array();
+        $result['category_id'] = $category->getId();
+
+        $result['is_active']   = $category->getIsActive();
+        $result['position']    = $category->getPosition();
+        $result['level']       = $category->getLevel();
+
+        foreach ($category->getAttributes() as $attribute) {
+            if ($this->_isAllowedAttribute($attribute, $attributes)) {
+                $result[$attribute->getAttributeCode()] = $category->getData($attribute->getAttributeCode());
+            }
+        }
+        $result['parent_id']   = $category->getParentId();
+        $result['children']           = $category->getChildren();
+        $result['all_children']       = $category->getAllChildren();
+
+        return $result;
+    }
+
+    /**
+     * Create new category
+     *
+     * @param int $parentId
+     * @param array $categoryData
+     * @param int|string|null $store
+     * @return int
+     */
+    public function create($parentId, $categoryData, $store = null)
+    {
+        $parent_category = $this->_initCategory($parentId, $store);
+        $category = Mage::getModel('Mage_Catalog_Model_Category')
+            ->setStoreId($this->_getStoreId($store));
+
+        $category->addData(array('path'=>implode('/',$parent_category->getPathIds())));
+
+        $category ->setAttributeSetId($category->getDefaultAttributeSetId());
+        /* @var $category Mage_Catalog_Model_Category */
+
+        foreach ($category->getAttributes() as $attribute) {
+            if ($this->_isAllowedAttribute($attribute)
+                && isset($categoryData[$attribute->getAttributeCode()])) {
+                $category->setData(
+                    $attribute->getAttributeCode(),
+                    $categoryData[$attribute->getAttributeCode()]
+                );
+            }
+        }
+
+        $category->setParentId($parent_category->getId());
+
+        try {
+            $validate = $category->validate();
+            if ($validate !== true) {
+                foreach ($validate as $code => $error) {
+                    if ($error === true) {
+                        Mage::throwException(Mage::helper('Mage_Catalog_Helper_Data')->__('Attribute "%s" is required.', $code));
+                    }
+                    else {
+                        Mage::throwException($error);
+                    }
+                }
+            }
+
+            $category->save();
+        }
+        catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return $category->getId();
+    }
+
+    /**
+     * Update category data
+     *
+     * @param int $categoryId
+     * @param array $categoryData
+     * @param string|int $store
+     * @return boolean
+     */
+    public function update($categoryId, $categoryData, $store = null)
+    {
+        $category = $this->_initCategory($categoryId, $store);
+
+        foreach ($category->getAttributes() as $attribute) {
+            if ($this->_isAllowedAttribute($attribute)
+                && isset($categoryData[$attribute->getAttributeCode()])) {
+                $category->setData(
+                    $attribute->getAttributeCode(),
+                    $categoryData[$attribute->getAttributeCode()]
+                );
+            }
+        }
+
+        try {
+            $validate = $category->validate();
+            if ($validate !== true) {
+                foreach ($validate as $code => $error) {
+                    if ($error === true) {
+                        Mage::throwException(Mage::helper('Mage_Catalog_Helper_Data')->__('Attribute "%s" is required.', $code));
+                    }
+                    else {
+                        Mage::throwException($error);
+                    }
+                }
+            }
+
+            $category->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        } catch (Mage_Eav_Model_Entity_Attribute_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Move category in tree
+     *
+     * @param int $categoryId
+     * @param int $parentId
+     * @param int $afterId
+     * @return boolean
+     */
+    public function move($categoryId, $parentId, $afterId = null)
+    {
+        $category = $this->_initCategory($categoryId);
+        $parent_category = $this->_initCategory($parentId);
+
+        // if $afterId is null - move category to the down
+        if ($afterId === null && $parent_category->hasChildren()) {
+            $parentChildren = $parent_category->getChildren();
+            $afterId = array_pop(explode(',', $parentChildren));
+        }
+
+        if( strpos($parent_category->getPath(), $category->getPath()) === 0) {
+            $this->_fault('not_moved', "Operation do not allow to move a parent category to any of children category");
+        }
+
+        try {
+            $category->move($parentId, $afterId);
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_moved', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Delete category
+     *
+     * @param int $categoryId
+     * @return boolean
+     */
+    public function delete($categoryId)
+    {
+        if (Mage_Catalog_Model_Category::TREE_ROOT_ID == $categoryId) {
+            $this->_fault('not_deleted', 'Cannot remove the system category.');
+        }
+
+        $category = $this->_initCategory($categoryId);
+
+        try {
+            $category->delete();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_deleted', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Get product Id from sku or from product id
+     *
+     * @param int|string $productId
+     * @param string $identifierType
+     * @return int
+     */
+    protected function _getProductId($productId, $identifierType = null)
+    {
+        $product = Mage::helper('Mage_Catalog_Helper_Product')->getProduct($productId, null, $identifierType);
+        if (!$product->getId()) {
+            $this->_fault('product_not_exists', 'Product not exists.');
+        }
+        return $product->getId();
+    }
+
+
+    /**
+     * Retrieve list of assigned products to category
+     *
+     * @param int $categoryId
+     * @param string|int $store
+     * @return array
+     */
+    public function assignedProducts($categoryId, $store = null)
+    {
+        $category = $this->_initCategory($categoryId);
+
+        $storeId = $this->_getStoreId($store);
+        $collection = $category->setStoreId($storeId)->getProductCollection();
+        ($storeId == 0)? $collection->addOrder('position', 'asc') : $collection->setOrder('position', 'asc');;
+
+        $result = array();
+
+        foreach ($collection as $product) {
+            $result[] = array(
+                'product_id' => $product->getId(),
+                'type'       => $product->getTypeId(),
+                'set'        => $product->getAttributeSetId(),
+                'sku'        => $product->getSku(),
+                'position'   => $product->getCatIndexPosition()
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Assign product to category
+     *
+     * @param int $categoryId
+     * @param int $productId
+     * @param int $position
+     * @param string|null $identifierType
+     * @return boolean
+     */
+    public function assignProduct($categoryId, $productId, $position = null, $identifierType = null)
+    {
+        $category = $this->_initCategory($categoryId);
+        $positions = $category->getProductsPosition();
+        $productId = $this->_getProductId($productId, $identifierType);
+        $positions[$productId] = $position;
+        $category->setPostedProducts($positions);
+
+        try {
+            $category->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Update product assignment
+     *
+     * @param int $categoryId
+     * @param int $productId
+     * @param int $position
+     * @param string|null $identifierType
+     * @return boolean
+     */
+    public function updateProduct($categoryId, $productId, $position = null, $identifierType = null)
+    {
+        $category = $this->_initCategory($categoryId);
+        $positions = $category->getProductsPosition();
+        $productId = $this->_getProductId($productId, $identifierType);
+        if (!isset($positions[$productId])) {
+            $this->_fault('product_not_assigned');
+        }
+        $positions[$productId] = $position;
+        $category->setPostedProducts($positions);
+
+        try {
+            $category->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Remove product assignment from category
+     *
+     * @param int $categoryId
+     * @param int $productId
+     * @param string|null $identifierType
+     * @return boolean
+     */
+    public function removeProduct($categoryId, $productId, $identifierType = null)
+    {
+        $category = $this->_initCategory($categoryId);
+        $positions = $category->getProductsPosition();
+        $productId = $this->_getProductId($productId, $identifierType);
+        if (!isset($positions[$productId])) {
+            $this->_fault('product_not_assigned');
+        }
+
+        unset($positions[$productId]);
+        $category->setPostedProducts($positions);
+
+        try {
+            $category->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+}
diff --git a/app/code/core/Mage/Catalog/Model/Category/Api/V2.php b/app/code/core/Mage/Catalog/Model/Category/Api/V2.php
new file mode 100644
index 00000000000..6a1179a77c0
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Category/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog category api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Category_Api_V2 extends Mage_Catalog_Model_Category_Api
+{
+    /**
+     * Retrieve category data
+     *
+     * @param int $categoryId
+     * @param string|int $store
+     * @param array $attributes
+     * @return array
+     */
+    public function info($categoryId, $store = null, $attributes = null)
+    {
+        $category = $this->_initCategory($categoryId, $store);
+
+        // Basic category data
+        $result = array();
+        $result['category_id'] = $category->getId();
+
+        $result['is_active']   = $category->getIsActive();
+        $result['position']    = $category->getPosition();
+        $result['level']       = $category->getLevel();
+
+        foreach ($category->getAttributes() as $attribute) {
+            if ($this->_isAllowedAttribute($attribute, $attributes)) {
+                $result[$attribute->getAttributeCode()] = $category->getDataUsingMethod($attribute->getAttributeCode());
+            }
+        }
+        $result['parent_id']   = $category->getParentId();
+        $result['children']           = $category->getChildren();
+        $result['all_children']       = $category->getAllChildren();
+
+        return $result;
+    }
+
+    /**
+     * Create new category
+     *
+     * @param int $parentId
+     * @param array $categoryData
+     * @return int
+     */
+    public function create($parentId, $categoryData, $store = null)
+    {
+        $parent_category = $this->_initCategory($parentId, $store);
+
+        /* @var $category Mage_Catalog_Model_Category */
+        $category = Mage::getModel('Mage_Catalog_Model_Category')
+            ->setStoreId($this->_getStoreId($store));
+
+        $category->addData(array('path'=>implode('/',$parent_category->getPathIds())));
+
+        $category ->setAttributeSetId($category->getDefaultAttributeSetId());
+
+
+        foreach ($category->getAttributes() as $attribute) {
+            $_attrCode = $attribute->getAttributeCode();
+            if ($this->_isAllowedAttribute($attribute)
+                && isset($categoryData->$_attrCode)) {
+                $category->setData(
+                    $attribute->getAttributeCode(),
+                    $categoryData->$_attrCode
+                );
+            }
+        }
+        $category->setParentId($parent_category->getId());
+        try {
+            $validate = $category->validate();
+            if ($validate !== true) {
+                foreach ($validate as $code => $error) {
+                    if ($error === true) {
+                        Mage::throwException(Mage::helper('Mage_Catalog_Helper_Data')->__('Attribute "%s" is required.', $code));
+                    }
+                    else {
+                        Mage::throwException($error);
+                    }
+                }
+            }
+
+            $category->save();
+        }
+        catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return $category->getId();
+    }
+
+    /**
+     * Update category data
+     *
+     * @param int $categoryId
+     * @param array $categoryData
+     * @param string|int $store
+     * @return boolean
+     */
+    public function update($categoryId, $categoryData, $store = null)
+    {
+        $category = $this->_initCategory($categoryId, $store);
+
+        foreach ($category->getAttributes() as $attribute) {
+            $_attrCode = $attribute->getAttributeCode();
+            if ($this->_isAllowedAttribute($attribute)
+                && isset($categoryData->$_attrCode)) {
+                $category->setData(
+                    $attribute->getAttributeCode(),
+                    $categoryData->$_attrCode
+                );
+            }
+        }
+
+        try {
+            $validate = $category->validate();
+            if ($validate !== true) {
+                foreach ($validate as $code => $error) {
+                    if ($error === true) {
+                        Mage::throwException(Mage::helper('Mage_Catalog_Helper_Data')->__('Attribute "%s" is required.', $code));
+                    }
+                    else {
+                        Mage::throwException($error);
+                    }
+                }
+            }
+            $category->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        } catch (Mage_Eav_Model_Entity_Attribute_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Model/Category/Attribute/Api.php b/app/code/core/Mage/Catalog/Model/Category/Attribute/Api.php
new file mode 100644
index 00000000000..4aa133612a0
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Category/Attribute/Api.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog category attribute api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Category_Attribute_Api extends Mage_Catalog_Model_Api_Resource
+{
+    public function __construct()
+    {
+        $this->_storeIdSessionField = 'category_store_id';
+    }
+
+    /**
+     * Retrieve category attributes
+     *
+     * @return array
+     */
+    public function items()
+    {
+        $attributes = Mage::getModel('Mage_Catalog_Model_Category')->getAttributes();
+        $result = array();
+
+        foreach ($attributes as $attribute) {
+            /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
+            if ($this->_isAllowedAttribute($attribute)) {
+                if (!$attribute->getId() || $attribute->isScopeGlobal()) {
+                    $scope = 'global';
+                } elseif ($attribute->isScopeWebsite()) {
+                    $scope = 'website';
+                } else {
+                    $scope = 'store';
+                }
+
+                $result[] = array(
+                    'attribute_id' => $attribute->getId(),
+                    'code'         => $attribute->getAttributeCode(),
+                    'type'         => $attribute->getFrontendInput(),
+                    'required'     => $attribute->getIsRequired(),
+                    'scope'        => $scope
+                );
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve category attribute options
+     *
+     * @param int|string $attributeId
+     * @param string|int $store
+     * @return array
+     */
+    public function options($attributeId, $store = null)
+    {
+        $attribute = Mage::getModel('Mage_Catalog_Model_Category')
+            ->setStoreId($this->_getStoreId($store))
+            ->getResource()
+            ->getAttribute($attributeId);
+
+        if (!$attribute) {
+            $this->_fault('not_exists');
+        }
+
+        $result = array();
+        if ($attribute->usesSource()) {
+            foreach ($attribute->getSource()->getAllOptions(false) as $optionId=>$optionValue) {
+                if (is_array($optionValue)) {
+                    $result[] = $optionValue;
+                } else {
+                    $result[] = array(
+                        'value' => $optionId,
+                        'label' => $optionValue
+                    );
+                }
+            }
+        }
+
+        return $result;
+    }
+} // Class Mage_Catalog_Model_Category_Attribute_Api End
diff --git a/app/code/core/Mage/Catalog/Model/Category/Attribute/Api/V2.php b/app/code/core/Mage/Catalog/Model/Category/Attribute/Api/V2.php
new file mode 100644
index 00000000000..771d370171f
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Category/Attribute/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog category attribute api V2
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Category_Attribute_Api_V2 extends Mage_Catalog_Model_Category_Attribute_Api
+{
+}
diff --git a/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php b/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php
index 1218dd955f8..ba8fc9dbc79 100644
--- a/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php
+++ b/app/code/core/Mage/Catalog/Model/Category/Attribute/Backend/Image.php
@@ -71,7 +71,6 @@ class Mage_Catalog_Model_Category_Attribute_Backend_Image extends Mage_Eav_Model
             if ($e->getCode() != Mage_Core_Model_File_Uploader::TMP_NAME_EMPTY) {
                 Mage::logException($e);
             }
-            /** @TODO ??? */
         }
         return $this;
     }
diff --git a/app/code/core/Mage/Catalog/Model/Config.php b/app/code/core/Mage/Catalog/Model/Config.php
index 4e6989b12f3..1943108295d 100644
--- a/app/code/core/Mage/Catalog/Model/Config.php
+++ b/app/code/core/Mage/Catalog/Model/Config.php
@@ -28,6 +28,7 @@
 class Mage_Catalog_Model_Config extends Mage_Eav_Model_Config
 {
     const XML_PATH_LIST_DEFAULT_SORT_BY     = 'catalog/frontend/default_sort_by';
+    const XML_PATH_GROUPED_ALLOWED_PRODUCT_TYPES = 'global/catalog/product/type/grouped/allow_product_types';
 
     protected $_attributeSetsById;
     protected $_attributeSetsByName;
diff --git a/app/code/core/Mage/Catalog/Model/Product/Api.php b/app/code/core/Mage/Catalog/Model/Product/Api.php
new file mode 100644
index 00000000000..cacdb4d57ca
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Api.php
@@ -0,0 +1,528 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Api extends Mage_Catalog_Model_Api_Resource
+{
+    protected $_filtersMap = array(
+        'product_id' => 'entity_id',
+        'set'        => 'attribute_set_id',
+        'type'       => 'type_id'
+    );
+
+    protected $_defaultProductAttributeList = array(
+        'type_id',
+        'category_ids',
+        'website_ids',
+        'name',
+        'description',
+        'short_description',
+        'sku',
+        'weight',
+        'status',
+        'url_key',
+        'url_path',
+        'visibility',
+        'has_options',
+        'gift_message_available',
+        'price',
+        'special_price',
+        'special_from_date',
+        'special_to_date',
+        'tax_class_id',
+        'tier_price',
+        'meta_title',
+        'meta_keyword',
+        'meta_description',
+        'custom_design',
+        'custom_layout_update',
+        'options_container',
+        'image_label',
+        'small_image_label',
+        'thumbnail_label',
+        'created_at',
+        'updated_at'
+    );
+
+    public function __construct()
+    {
+        $this->_storeIdSessionField = 'product_store_id';
+        $this->_ignoredAttributeTypes[] = 'gallery';
+        $this->_ignoredAttributeTypes[] = 'media_image';
+    }
+
+    /**
+     * Retrieve list of products with basic info (id, sku, type, set, name)
+     *
+     * @param null|object|array $filters
+     * @param string|int $store
+     * @return array
+     */
+    public function items($filters = null, $store = null)
+    {
+        $collection = Mage::getModel('Mage_Catalog_Model_Product')->getCollection()
+            ->addStoreFilter($this->_getStoreId($store))
+            ->addAttributeToSelect('name');
+
+        /** @var $apiHelper Mage_Api_Helper_Data */
+        $apiHelper = Mage::helper('Mage_Api_Helper_Data');
+        $filters = $apiHelper->parseFilters($filters, $this->_filtersMap);
+        try {
+            foreach ($filters as $field => $value) {
+                $collection->addFieldToFilter($field, $value);
+            }
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('filters_invalid', $e->getMessage());
+        }
+        $result = array();
+        foreach ($collection as $product) {
+            $result[] = array(
+                'product_id' => $product->getId(),
+                'sku'        => $product->getSku(),
+                'name'       => $product->getName(),
+                'set'        => $product->getAttributeSetId(),
+                'type'       => $product->getTypeId(),
+                'category_ids' => $product->getCategoryIds(),
+                'website_ids'  => $product->getWebsiteIds()
+            );
+        }
+        return $result;
+    }
+
+    /**
+     * Retrieve product info
+     *
+     * @param int|string $productId
+     * @param string|int $store
+     * @param array $attributes
+     * @return array
+     */
+    public function info($productId, $store = null, $attributes = null, $identifierType = null)
+    {
+        $product = $this->_getProduct($productId, $store, $identifierType);
+
+
+        $result = array( // Basic product data
+            'product_id' => $product->getId(),
+            'sku'        => $product->getSku(),
+            'set'        => $product->getAttributeSetId(),
+            'type'       => $product->getTypeId(),
+            'categories' => $product->getCategoryIds(),
+            'websites'   => $product->getWebsiteIds()
+        );
+
+        foreach ($product->getTypeInstance()->getEditableAttributes($product) as $attribute) {
+            if ($this->_isAllowedAttribute($attribute, $attributes)) {
+                $result[$attribute->getAttributeCode()] = $product->getData(
+                                                                $attribute->getAttributeCode());
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Create new product.
+     *
+     * @param string $type
+     * @param int $set
+     * @param string $sku
+     * @param array $productData
+     * @param string $store
+     * @return int
+     */
+    public function create($type, $set, $sku, $productData, $store = null)
+    {
+        if (!$type || !$set || !$sku) {
+            $this->_fault('data_invalid');
+        }
+
+        $this->_checkProductTypeExists($type);
+        $this->_checkProductAttributeSet($set);
+
+        /** @var $product Mage_Catalog_Model_Product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->setStoreId($this->_getStoreId($store))
+            ->setAttributeSetId($set)
+            ->setTypeId($type)
+            ->setSku($sku);
+
+        if (!isset($productData['stock_data']) || !is_array($productData['stock_data'])) {
+            //Set default stock_data if not exist in product data
+            $product->setStockData(array('use_config_manage_stock' => 0));
+        }
+
+        foreach ($product->getMediaAttributes() as $mediaAttribute) {
+            $mediaAttrCode = $mediaAttribute->getAttributeCode();
+            $product->setData($mediaAttrCode, 'no_selection');
+        }
+
+        $this->_prepareDataForSave($product, $productData);
+
+        try {
+            /**
+             * @todo implement full validation process with errors returning which are ignoring now
+             * @todo see Mage_Catalog_Model_Product::validate()
+             */
+            if (is_array($errors = $product->validate())) {
+                $strErrors = array();
+                foreach($errors as $code => $error) {
+                    if ($error === true) {
+                        $error = Mage::helper('Mage_Catalog_Helper_Data')->__('Attribute "%s" is invalid.', $code);
+                    }
+                    $strErrors[] = $error;
+                }
+                $this->_fault('data_invalid', implode("\n", $strErrors));
+            }
+
+            $product->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return $product->getId();
+    }
+
+    /**
+     * Update product data
+     *
+     * @param int|string $productId
+     * @param array $productData
+     * @param string|int $store
+     * @return boolean
+     */
+    public function update($productId, $productData, $store = null, $identifierType = null)
+    {
+        $product = $this->_getProduct($productId, $store, $identifierType);
+
+        $this->_prepareDataForSave($product, $productData);
+
+        try {
+            /**
+             * @todo implement full validation process with errors returning which are ignoring now
+             * @todo see Mage_Catalog_Model_Product::validate()
+             */
+            if (is_array($errors = $product->validate())) {
+                $strErrors = array();
+                foreach($errors as $code => $error) {
+                    if ($error === true) {
+                        $error = Mage::helper('Mage_Catalog_Helper_Data')->__('Value for "%s" is invalid.', $code);
+                    } else {
+                        $error = Mage::helper('Mage_Catalog_Helper_Data')->__('Value for "%s" is invalid: %s', $code, $error);
+                    }
+                    $strErrors[] = $error;
+                }
+                $this->_fault('data_invalid', implode("\n", $strErrors));
+            }
+
+            $product->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     *  Set additional data before product saved
+     *
+     *  @param    Mage_Catalog_Model_Product $product
+     *  @param    array $productData
+     *  @return   object
+     */
+    protected function _prepareDataForSave($product, $productData)
+    {
+        if (isset($productData['website_ids']) && is_array($productData['website_ids'])) {
+            $product->setWebsiteIds($productData['website_ids']);
+        }
+
+        foreach ($product->getTypeInstance()->getEditableAttributes($product) as $attribute) {
+            //Unset data if object attribute has no value in current store
+            if (Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID !== (int) $product->getStoreId()
+                && !$product->getExistsStoreValueFlag($attribute->getAttributeCode())
+                && !$attribute->isScopeGlobal()
+            ) {
+                $product->setData($attribute->getAttributeCode(), false);
+            }
+
+            if ($this->_isAllowedAttribute($attribute)) {
+                if (isset($productData[$attribute->getAttributeCode()])) {
+                    $product->setData(
+                        $attribute->getAttributeCode(),
+                        $productData[$attribute->getAttributeCode()]
+                    );
+                } elseif (isset($productData['additional_attributes']['single_data'][$attribute->getAttributeCode()])) {
+                    $product->setData(
+                        $attribute->getAttributeCode(),
+                        $productData['additional_attributes']['single_data'][$attribute->getAttributeCode()]
+                    );
+                } elseif (isset($productData['additional_attributes']['multi_data'][$attribute->getAttributeCode()])) {
+                    $product->setData(
+                        $attribute->getAttributeCode(),
+                        $productData['additional_attributes']['multi_data'][$attribute->getAttributeCode()]
+                    );
+                }
+            }
+        }
+
+        if (isset($productData['categories']) && is_array($productData['categories'])) {
+            $product->setCategoryIds($productData['categories']);
+        }
+
+        if (isset($productData['websites']) && is_array($productData['websites'])) {
+            foreach ($productData['websites'] as &$website) {
+                if (is_string($website)) {
+                    try {
+                        $website = Mage::app()->getWebsite($website)->getId();
+                    } catch (Exception $e) { }
+                }
+            }
+            $product->setWebsiteIds($productData['websites']);
+        }
+
+        if (Mage::app()->hasSingleStore()) {
+            $product->setWebsiteIds(array(Mage::app()->getStore(true)->getWebsite()->getId()));
+        }
+
+        if (isset($productData['stock_data']) && is_array($productData['stock_data'])) {
+            $product->setStockData($productData['stock_data']);
+        }
+
+        if (isset($productData['tier_price']) && is_array($productData['tier_price'])) {
+             $tierPrices = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Tierprice_Api')
+                 ->prepareTierPrices($product, $productData['tier_price']);
+             $product->setData(Mage_Catalog_Model_Product_Attribute_Tierprice_Api::ATTRIBUTE_CODE, $tierPrices);
+        }
+        $this->_prepareConfigurableAttributes($product, $productData);
+    }
+
+    /**
+     * Process configurable attributes
+     *
+     * @param Mage_Catalog_Model_Product $product
+     * @param array $saveData
+     */
+    protected function _prepareConfigurableAttributes(Mage_Catalog_Model_Product $product, array $saveData)
+    {
+        if ($product->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
+            if ($product->isObjectNew()) {
+                $this->_prepareConfigurableAttributesForCreate($product, $saveData);
+            } else {
+                // TODO: Implement part related to product update
+            }
+        }
+    }
+
+    /**
+     * Process configurable attributes for product create
+     *
+     * @param Mage_Catalog_Model_Product $product
+     * @param array $saveData
+     */
+    protected function _prepareConfigurableAttributesForCreate(Mage_Catalog_Model_Product $product, array $saveData)
+    {
+        $usedConfigurableAttributeIds = array();
+        $configurableAttributesData = array();
+        if (isset($saveData['configurable_attributes']) && is_array($saveData['configurable_attributes'])) {
+            foreach ($saveData['configurable_attributes'] as $configurableData) {
+                if (!isset($configurableData['attribute_code'])) {
+                    continue;
+                }
+                /** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
+                $attribute = Mage::getResourceModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+                $attribute->load($configurableData['attribute_code'], 'attribute_code');
+                if ($attribute->getId()) {
+                    $usedConfigurableAttributeIds[] = $attribute->getId();
+                    $configurableAttributesData[$attribute->getAttributeCode()] = array(
+                        'attribute_id' => $attribute->getId(),
+                        'attribute_code' => $attribute->getAttributeCode(),
+                        'label' => (isset($configurableData['frontend_label']) && $configurableData['frontend_label'])
+                            ? trim((string) $configurableData['frontend_label']) : null,
+                        'use_default' => (isset($configurableData['frontend_label_use_default'])
+                            && $configurableData['frontend_label_use_default']) ? 1 : 0,
+                        'position' => (isset($configurableData['position']) && $configurableData['position'])
+                            ? (int) $configurableData['position'] : 0,
+                    );
+
+                    // save information about configurable options' prices
+                    if (isset($configurableData['prices']) && is_array($configurableData['prices'])) {
+                        $formattedOptions = array();
+                        foreach ($configurableData['prices'] as $optionPrice) {
+                            if (isset($optionPrice['option_value']) && isset($optionPrice['price'])
+                                && isset($optionPrice['price_type'])
+                            ) {
+                                $formattedOptions[] = array(
+                                    'value_index' => $optionPrice['option_value'],
+                                    'pricing_value' => $optionPrice['price'],
+                                    'is_percent' => ($optionPrice['price_type'] == 'percent')
+                                );
+                            }
+                        }
+                        $configurableAttributesData[$attribute->getAttributeCode()]['values'] = $formattedOptions;
+                    }
+                }
+            }
+        }
+        $product->setConfigurableAttributesData($configurableAttributesData);
+        /** @var $configurableType Mage_Catalog_Model_Product_Type_Configurable */
+        $configurableType = $product->getTypeInstance();
+        $configurableType->setUsedProductAttributeIds($usedConfigurableAttributeIds, $product);
+    }
+
+    /**
+     * Update product special price
+     *
+     * @param int|string $productId
+     * @param float $specialPrice
+     * @param string $fromDate
+     * @param string $toDate
+     * @param string|int $store
+     * @return boolean
+     */
+    public function setSpecialPrice($productId, $specialPrice = null, $fromDate = null, $toDate = null, $store = null)
+    {
+        return $this->update($productId, array(
+            'special_price'     => $specialPrice,
+            'special_from_date' => $fromDate,
+            'special_to_date'   => $toDate
+        ), $store);
+    }
+
+    /**
+     * Retrieve product special price
+     *
+     * @param int|string $productId
+     * @param string|int $store
+     * @return array
+     */
+    public function getSpecialPrice($productId, $store = null)
+    {
+        return $this->info($productId, $store, array('special_price', 'special_from_date', 'special_to_date'));
+    }
+
+    /**
+     * Delete product
+     *
+     * @param int|string $productId
+     * @return boolean
+     */
+    public function delete($productId, $identifierType = null)
+    {
+        $product = $this->_getProduct($productId, null, $identifierType);
+
+        try {
+            $product->delete();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_deleted', $e->getMessage());
+        }
+
+        return true;
+    }
+
+   /**
+    * Get list of additional attributes which are not in default create/update list
+    *
+    * @param  $productType
+    * @param  $attributeSetId
+    * @return array
+    */
+    public function getAdditionalAttributes($productType, $attributeSetId)
+    {
+        $this->_checkProductTypeExists($productType);
+        $this->_checkProductAttributeSet($attributeSetId);
+
+        /** @var $product Mage_Catalog_Model_Product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $productAttributes = $product->setAttributeSetId($attributeSetId)
+            ->setTypeId($productType)
+            ->getTypeInstance()
+            ->getEditableAttributes($product);
+
+        $result = array();
+        foreach ($productAttributes as $attribute) {
+            /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
+            if ($attribute->isInSet($attributeSetId) && $this->_isAllowedAttribute($attribute)
+                && !in_array($attribute->getAttributeCode(), $this->_defaultProductAttributeList)) {
+
+                if ($attribute->isScopeGlobal()) {
+                    $scope = 'global';
+                } elseif ($attribute->isScopeWebsite()) {
+                    $scope = 'website';
+                } else {
+                    $scope = 'store';
+                }
+
+                $result[] = array(
+                    'attribute_id' => $attribute->getId(),
+                    'code' => $attribute->getAttributeCode(),
+                    'type' => $attribute->getFrontendInput(),
+                    'required' => $attribute->getIsRequired(),
+                    'scope' => $scope
+                );
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Check if product type exists
+     *
+     * @param  $productType
+     * @throw Mage_Api_Exception
+     * @return void
+     */
+    protected function _checkProductTypeExists($productType)
+    {
+        if (!in_array($productType, array_keys(Mage::getModel('Mage_Catalog_Model_Product_Type')->getOptionArray()))) {
+            $this->_fault('product_type_not_exists');
+        }
+    }
+
+    /**
+     * Check if attributeSet is exits and in catalog_product entity group type
+     *
+     * @param  $attributeSetId
+     * @throw Mage_Api_Exception
+     * @return void
+     */
+    protected function _checkProductAttributeSet($attributeSetId)
+    {
+        $attributeSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set')->load($attributeSetId);
+        if (is_null($attributeSet->getId())) {
+            $this->_fault('product_attribute_set_not_exists');
+        }
+        if (Mage::getModel('Mage_Catalog_Model_Product')->getResource()->getTypeId() != $attributeSet->getEntityTypeId()) {
+            $this->_fault('product_attribute_set_not_valid');
+        }
+    }
+} // Class Mage_Catalog_Model_Product_Api End
diff --git a/app/code/core/Mage/Catalog/Model/Product/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Api/V2.php
new file mode 100644
index 00000000000..d74389daea7
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Api/V2.php
@@ -0,0 +1,308 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product api V2
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Api_V2 extends Mage_Catalog_Model_Product_Api
+{
+    /**
+     * Retrieve product info
+     *
+     * @param int|string $productId
+     * @param string|int $store
+     * @param stdClass $attributes
+     * @return array
+     */
+    public function info($productId, $store = null, $attributes = null, $identifierType = null)
+    {
+        $product = $this->_getProduct($productId, $store, $identifierType);
+
+        $result = array( // Basic product data
+            'product_id' => $product->getId(),
+            'sku'        => $product->getSku(),
+            'set'        => $product->getAttributeSetId(),
+            'type'       => $product->getTypeId(),
+            'categories' => $product->getCategoryIds(),
+            'websites'   => $product->getWebsiteIds()
+        );
+
+        $allAttributes = array();
+        if (!empty($attributes->attributes)) {
+            $allAttributes = array_merge($allAttributes, $attributes->attributes);
+        } else {
+            foreach ($product->getTypeInstance()->getEditableAttributes($product) as $attribute) {
+                if ($this->_isAllowedAttribute($attribute, $attributes)) {
+                    $allAttributes[] = $attribute->getAttributeCode();
+                }
+            }
+        }
+
+        $_additionalAttributeCodes = array();
+        if (!empty($attributes->additional_attributes)) {
+            foreach ($attributes->additional_attributes as $k => $_attributeCode) {
+                $allAttributes[] = $_attributeCode;
+                $_additionalAttributeCodes[] = $_attributeCode;
+            }
+        }
+
+        $_additionalAttribute = 0;
+        foreach ($product->getTypeInstance()->getEditableAttributes($product) as $attribute) {
+            if ($this->_isAllowedAttribute($attribute, $allAttributes)) {
+                if (in_array($attribute->getAttributeCode(), $_additionalAttributeCodes)) {
+                    $result['additional_attributes'][$_additionalAttribute]['key'] = $attribute->getAttributeCode();
+                    $result['additional_attributes'][$_additionalAttribute]['value'] = $product
+                        ->getData($attribute->getAttributeCode());
+                    $_additionalAttribute++;
+                } else {
+                    $result[$attribute->getAttributeCode()] = $product->getData($attribute->getAttributeCode());
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Create new product.
+     *
+     * @param string $type
+     * @param int $set
+     * @param string $sku
+     * @param array $productData
+     * @param string $store
+     * @return int
+     */
+    public function create($type, $set, $sku, $productData, $store = null)
+    {
+        if (!$type || !$set || !$sku) {
+            $this->_fault('data_invalid');
+        }
+
+        $this->_checkProductTypeExists($type);
+        $this->_checkProductAttributeSet($set);
+
+        /** @var $product Mage_Catalog_Model_Product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->setStoreId($this->_getStoreId($store))
+            ->setAttributeSetId($set)
+            ->setTypeId($type)
+            ->setSku($sku);
+
+        if (!property_exists($productData, 'stock_data')) {
+            //Set default stock_data if not exist in product data
+            $_stockData = array('use_config_manage_stock' => 0);
+            $product->setStockData($_stockData);
+        }
+
+        foreach ($product->getMediaAttributes() as $mediaAttribute) {
+            $mediaAttrCode = $mediaAttribute->getAttributeCode();
+            $product->setData($mediaAttrCode, 'no_selection');
+        }
+
+        $this->_prepareDataForSave($product, $productData);
+
+        try {
+            $product->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return $product->getId();
+    }
+
+    /**
+     * Update product data
+     *
+     * @param int|string $productId
+     * @param array $productData
+     * @param string|int $store
+     * @return boolean
+     */
+    public function update($productId, $productData, $store = null, $identifierType = null)
+    {
+        $product = $this->_getProduct($productId, $store, $identifierType);
+
+        $this->_prepareDataForSave($product, $productData);
+
+        try {
+            /**
+             * @todo implement full validation process with errors returning which are ignoring now
+             * @todo see Mage_Catalog_Model_Product::validate()
+             */
+            if (is_array($errors = $product->validate())) {
+                $strErrors = array();
+                foreach($errors as $code => $error) {
+                    if ($error === true) {
+                        $error = Mage::helper('Mage_Catalog_Helper_Data')->__('Value for "%s" is invalid.', $code);
+                    } else {
+                        $error = Mage::helper('Mage_Catalog_Helper_Data')->__('Value for "%s" is invalid: %s', $code, $error);
+                    }
+                    $strErrors[] = $error;
+                }
+                $this->_fault('data_invalid', implode("\n", $strErrors));
+            }
+
+            $product->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     *  Set additional data before product saved
+     *
+     *  @param    Mage_Catalog_Model_Product $product
+     *  @param    array $productData
+     *  @return   object
+     */
+    protected function _prepareDataForSave ($product, $productData)
+    {
+        if (property_exists($productData, 'website_ids') && is_array($productData->website_ids)) {
+            $product->setWebsiteIds($productData->website_ids);
+        }
+
+        if (property_exists($productData, 'additional_attributes')) {
+            if (property_exists($productData->additional_attributes, 'single_data')) {
+                foreach ($productData->additional_attributes->single_data as $_attribute) {
+                    $_attrCode = $_attribute->key;
+                    $productData->$_attrCode = $_attribute->value;
+                }
+            }
+            if (property_exists($productData->additional_attributes, 'multi_data')) {
+                foreach ($productData->additional_attributes->multi_data as $_attribute) {
+                    $_attrCode = $_attribute->key;
+                    $productData->$_attrCode = $_attribute->value;
+                }
+            }
+            unset($productData->additional_attributes);
+        }
+
+        foreach ($product->getTypeInstance()->getEditableAttributes($product) as $attribute) {
+            $_attrCode = $attribute->getAttributeCode();
+
+            //Unset data if object attribute has no value in current store
+            if (Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID !== (int) $product->getStoreId()
+                && !$product->getExistsStoreValueFlag($_attrCode)
+                && !$attribute->isScopeGlobal()
+            ) {
+                $product->setData($_attrCode, false);
+            }
+
+            if ($this->_isAllowedAttribute($attribute) && (isset($productData->$_attrCode))) {
+                $product->setData(
+                    $_attrCode,
+                    $productData->$_attrCode
+                );
+            }
+        }
+
+        if (property_exists($productData, 'categories') && is_array($productData->categories)) {
+            $product->setCategoryIds($productData->categories);
+        }
+
+        if (property_exists($productData, 'websites') && is_array($productData->websites)) {
+            foreach ($productData->websites as &$website) {
+                if (is_string($website)) {
+                    try {
+                        $website = Mage::app()->getWebsite($website)->getId();
+                    } catch (Exception $e) { }
+                }
+            }
+            $product->setWebsiteIds($productData->websites);
+        }
+
+        if (Mage::app()->hasSingleStore()) {
+            $product->setWebsiteIds(array(Mage::app()->getStore(true)->getWebsite()->getId()));
+        }
+
+        if (property_exists($productData, 'stock_data')) {
+            $_stockData = array();
+            foreach ($productData->stock_data as $key => $value) {
+                $_stockData[$key] = $value;
+            }
+            $product->setStockData($_stockData);
+        }
+
+        if (property_exists($productData, 'tier_price')) {
+             $tierPrices = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2')
+                 ->prepareTierPrices($product, $productData->tier_price);
+             $product->setData(Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2::ATTRIBUTE_CODE, $tierPrices);
+        }
+
+        /** @var $helper Mage_Api_Helper_Data */
+        $helper = Mage::helper('Mage_Api_Helper_Data');
+        $helper->v2AssociativeArrayUnpacker($productData);
+        $helper->toArray($productData);
+        $this->_prepareConfigurableAttributes($product, $productData);
+    }
+
+    /**
+     * Update product special price
+     *
+     * @param int|string $productId
+     * @param float $specialPrice
+     * @param string $fromDate
+     * @param string $toDate
+     * @param string|int $store
+     * @param string $identifierType OPTIONAL If 'sku' - search product by SKU, if any except for NULL - search by ID,
+     *                                        otherwise - try to determine identifier type automatically
+     * @return boolean
+     */
+    public function setSpecialPrice($productId, $specialPrice = null, $fromDate = null, $toDate = null, $store = null,
+        $identifierType = null
+    ) {
+        $obj = new stdClass();
+        $obj->special_price = $specialPrice;
+        $obj->special_from_date = $fromDate;
+        $obj->special_to_date = $toDate;
+        return $this->update($productId, $obj, $store, $identifierType);
+    }
+
+    /**
+     * Retrieve product special price
+     *
+     * @param int|string $productId
+     * @param string|int $store
+     * @return array
+     */
+    public function getSpecialPrice($productId, $store = null)
+    {
+        $attributes = new stdClass();
+        $attributes->attributes = array(
+            'special_price',
+            'special_from_date',
+            'special_to_date'
+        );
+        return $this->info($productId, $store, $attributes);
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Api.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Api.php
new file mode 100644
index 00000000000..53ca84511ff
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Api.php
@@ -0,0 +1,526 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product attribute api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Attribute_Api extends Mage_Catalog_Model_Api_Resource
+{
+    /**
+     * Product entity type id
+     *
+     * @var int
+     */
+    protected $_entityTypeId;
+
+    /**
+     * Constructor. Initializes default values.
+     */
+    public function __construct()
+    {
+        $this->_storeIdSessionField = 'product_store_id';
+        $this->_ignoredAttributeCodes[] = 'type_id';
+        $this->_ignoredAttributeTypes[] = 'gallery';
+        $this->_ignoredAttributeTypes[] = 'media_image';
+        $this->_entityTypeId = Mage::getModel('Mage_Eav_Model_Entity')->setType('catalog_product')->getTypeId();
+    }
+
+    /**
+     * Retrieve attributes from specified attribute set
+     *
+     * @param int $setId
+     * @return array
+     */
+    public function items($setId)
+    {
+        $attributes = Mage::getModel('Mage_Catalog_Model_Product')->getResource()
+                ->loadAllAttributes()
+                ->getSortedAttributes($setId);
+        $result = array();
+
+        foreach ($attributes as $attribute) {
+            /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
+            if ((!$attribute->getId() || $attribute->isInSet($setId))
+                    && $this->_isAllowedAttribute($attribute)) {
+
+                if (!$attribute->getId() || $attribute->isScopeGlobal()) {
+                    $scope = 'global';
+                } elseif ($attribute->isScopeWebsite()) {
+                    $scope = 'website';
+                } else {
+                    $scope = 'store';
+                }
+
+                $result[] = array(
+                    'attribute_id' => $attribute->getId(),
+                    'code' => $attribute->getAttributeCode(),
+                    'type' => $attribute->getFrontendInput(),
+                    'required' => $attribute->getIsRequired(),
+                    'scope' => $scope
+                );
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve attribute options
+     *
+     * @param int $attributeId
+     * @param string|int $store
+     * @return array
+     */
+    public function options($attributeId, $store = null)
+    {
+        $storeId = $this->_getStoreId($store);
+        $attribute = Mage::getModel('Mage_Catalog_Model_Product')
+                ->setStoreId($storeId)
+                ->getResource()
+                ->getAttribute($attributeId);
+
+        /* @var $attribute Mage_Catalog_Model_Entity_Attribute */
+        if (!$attribute) {
+            $this->_fault('not_exists');
+        }
+        $options = array();
+        if ($attribute->usesSource()) {
+            foreach ($attribute->getSource()->getAllOptions() as $optionId => $optionValue) {
+                if (is_array($optionValue)) {
+                    $options[] = $optionValue;
+                } else {
+                    $options[] = array(
+                        'value' => $optionId,
+                        'label' => $optionValue
+                    );
+                }
+            }
+        }
+
+        return $options;
+    }
+
+    /**
+     * Retrieve list of possible attribute types
+     *
+     * @return array
+     */
+    public function types()
+    {
+        return Mage::getModel('Mage_Catalog_Model_Product_Attribute_Source_Inputtype')->toOptionArray();
+    }
+
+    /**
+     * Create new product attribute
+     *
+     * @param array $data input data
+     * @return integer
+     */
+    public function create($data)
+    {
+        /** @var $model Mage_Catalog_Model_Resource_Eav_Attribute */
+        $model = Mage::getModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+        /** @var $helper Mage_Catalog_Helper_Product */
+        $helper = Mage::helper('Mage_Catalog_Helper_Product');
+
+        if (empty($data['attribute_code']) || !is_array($data['frontend_label'])) {
+            $this->_fault('invalid_parameters');
+        }
+
+        //validate attribute_code
+        if (!preg_match('/^[a-z][a-z_0-9]{0,254}$/', $data['attribute_code'])) {
+            $this->_fault('invalid_code');
+        }
+
+        //validate frontend_input
+        $allowedTypes = array();
+        foreach ($this->types() as $type) {
+            $allowedTypes[] = $type['value'];
+        }
+        if (!in_array($data['frontend_input'], $allowedTypes)) {
+            $this->_fault('invalid_frontend_input');
+        }
+
+        $data['source_model'] = $helper->getAttributeSourceModelByInputType($data['frontend_input']);
+        $data['backend_model'] = $helper->getAttributeBackendModelByInputType($data['frontend_input']);
+        if (is_null($model->getIsUserDefined()) || $model->getIsUserDefined() != 0) {
+            $data['backend_type'] = $model->getBackendTypeByInput($data['frontend_input']);
+        }
+
+        $this->_prepareDataForSave($data);
+
+        $model->addData($data);
+        $model->setEntityTypeId($this->_entityTypeId);
+        $model->setIsUserDefined(1);
+
+        try {
+            $model->save();
+            // clear translation cache because attribute labels are stored in translation
+            Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
+        } catch (Exception $e) {
+            $this->_fault('unable_to_save', $e->getMessage());
+        }
+
+        return (int) $model->getId();
+    }
+
+    /**
+     * Update product attribute
+     *
+     * @param string|integer $attribute attribute code or ID
+     * @param array $data
+     * @return boolean
+     */
+    public function update($attribute, $data)
+    {
+        $model = $this->_getAttribute($attribute);
+
+        if ($model->getEntityTypeId() != $this->_entityTypeId) {
+            $this->_fault('can_not_edit');
+        }
+
+        $data['attribute_code'] = $model->getAttributeCode();
+        $data['is_user_defined'] = $model->getIsUserDefined();
+        $data['frontend_input'] = $model->getFrontendInput();
+
+        $this->_prepareDataForSave($data);
+
+        $model->addData($data);
+        try {
+            $model->save();
+            // clear translation cache because attribute labels are stored in translation
+            Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
+            return true;
+        } catch (Exception $e) {
+            $this->_fault('unable_to_save', $e->getMessage());
+        }
+    }
+
+    /**
+     * Remove attribute
+     *
+     * @param integer|string $attribute attribute ID or code
+     * @return boolean
+     */
+    public function remove($attribute)
+    {
+        $model = $this->_getAttribute($attribute);
+
+        if ($model->getEntityTypeId() != $this->_entityTypeId) {
+            $this->_fault('can_not_delete');
+        }
+
+        try {
+            $model->delete();
+            return true;
+        } catch (Exception $e) {
+            $this->_fault('can_not_delete', $e->getMessage());
+        }
+    }
+
+    /**
+     * Get full information about attribute with list of options
+     *
+     * @param integer|string $attribute attribute ID or code
+     * @return array
+     */
+    public function info($attribute)
+    {
+        $model = $this->_getAttribute($attribute);
+
+        if ($model->isScopeGlobal()) {
+            $scope = 'global';
+        } elseif ($model->isScopeWebsite()) {
+            $scope = 'website';
+        } else {
+            $scope = 'store';
+        }
+
+        $frontendLabels = array(
+            array(
+                'store_id' => 0,
+                'label' => $model->getFrontendLabel()
+            )
+        );
+        foreach ($model->getStoreLabels() as $store_id => $label) {
+            $frontendLabels[] = array(
+                'store_id' => $store_id,
+                'label' => $label
+            );
+        }
+
+        $result = array(
+            'attribute_id' => $model->getId(),
+            'attribute_code' => $model->getAttributeCode(),
+            'frontend_input' => $model->getFrontendInput(),
+            'default_value' => $model->getDefaultValue(),
+            'is_unique' => $model->getIsUnique(),
+            'is_required' => $model->getIsRequired(),
+            'apply_to' => $model->getApplyTo(),
+            'is_configurable' => $model->getIsConfigurable(),
+            'is_searchable' => $model->getIsSearchable(),
+            'is_visible_in_advanced_search' => $model->getIsVisibleInAdvancedSearch(),
+            'is_comparable' => $model->getIsComparable(),
+            'is_used_for_promo_rules' => $model->getIsUsedForPromoRules(),
+            'is_visible_on_front' => $model->getIsVisibleOnFront(),
+            'used_in_product_listing' => $model->getUsedInProductListing(),
+            'frontend_label' => $frontendLabels
+        );
+        if ($model->getFrontendInput() != 'price') {
+            $result['scope'] = $scope;
+        }
+
+        // set additional fields to different types
+        switch ($model->getFrontendInput()) {
+            case 'text':
+                    $result['additional_fields'] = array(
+                        'frontend_class' => $model->getFrontendClass(),
+                        'is_html_allowed_on_front' => $model->getIsHtmlAllowedOnFront(),
+                        'used_for_sort_by' => $model->getUsedForSortBy()
+                    );
+                    break;
+            case 'textarea':
+                    $result['additional_fields'] = array(
+                        'is_wysiwyg_enabled' => $model->getIsWysiwygEnabled(),
+                        'is_html_allowed_on_front' => $model->getIsHtmlAllowedOnFront(),
+                    );
+                    break;
+            case 'date':
+            case 'boolean':
+                    $result['additional_fields'] = array(
+                        'used_for_sort_by' => $model->getUsedForSortBy()
+                    );
+                    break;
+            case 'multiselect':
+                    $result['additional_fields'] = array(
+                        'is_filterable' => $model->getIsFilterable(),
+                        'is_filterable_in_search' => $model->getIsFilterableInSearch(),
+                        'position' => $model->getPosition()
+                    );
+                    break;
+            case 'select':
+            case 'price':
+                    $result['additional_fields'] = array(
+                        'is_filterable' => $model->getIsFilterable(),
+                        'is_filterable_in_search' => $model->getIsFilterableInSearch(),
+                        'position' => $model->getPosition(),
+                        'used_for_sort_by' => $model->getUsedForSortBy()
+                    );
+                    break;
+            default:
+                    $result['additional_fields'] = array();
+                    break;
+        }
+
+        // set options
+        $options = $this->options($model->getId());
+        // remove empty first element
+        if ($model->getFrontendInput() != 'boolean') {
+            array_shift($options);
+        }
+
+        if (count($options) > 0) {
+            $result['options'] = $options;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Add option to select or multiselect attribute
+     *
+     * @param  integer|string $attribute attribute ID or code
+     * @param  array $data
+     * @return bool
+     */
+    public function addOption($attribute, $data)
+    {
+        $model = $this->_getAttribute($attribute);
+
+        if (!$model->usesSource()) {
+            $this->_fault('invalid_frontend_input');
+        }
+
+        /** @var $helperCatalog Mage_Catalog_Helper_Data */
+        $helperCatalog = Mage::helper('Mage_Catalog_Helper_Data');
+
+        $optionLabels = array();
+        foreach ($data['label'] as $label) {
+            $storeId = $label['store_id'];
+            $labelText = $helperCatalog->stripTags($label['value']);
+            if (is_array($storeId)) {
+                foreach ($storeId as $multiStoreId) {
+                    $optionLabels[$multiStoreId] = $labelText;
+                }
+            } else {
+                $optionLabels[$storeId] = $labelText;
+            }
+        }
+        // data in the following format is accepted by the model
+        // it simulates parameters of the request made to
+        // Mage_Adminhtml_Catalog_Product_AttributeController::saveAction()
+        $modelData = array(
+            'option' => array(
+                'value' => array(
+                    'option_1' => $optionLabels
+                ),
+                'order' => array(
+                    'option_1' => (int) $data['order']
+                )
+            )
+        );
+        if ($data['is_default']) {
+            $modelData['default'][] = 'option_1';
+        }
+
+        $model->addData($modelData);
+        try {
+            $model->save();
+        } catch (Exception $e) {
+            $this->_fault('unable_to_add_option', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Remove option from select or multiselect attribute
+     *
+     * @param  integer|string $attribute attribute ID or code
+     * @param  integer $optionId option to remove ID
+     * @return bool
+     */
+    public function removeOption($attribute, $optionId)
+    {
+        $model = $this->_getAttribute($attribute);
+
+        if (!$model->usesSource()) {
+            $this->_fault('invalid_frontend_input');
+        }
+
+        // data in the following format is accepted by the model
+        // it simulates parameters of the request made to
+        // Mage_Adminhtml_Catalog_Product_AttributeController::saveAction()
+        $modelData = array(
+            'option' => array(
+                'value' => array(
+                    $optionId => array()
+                ),
+                'delete' => array(
+                    $optionId => '1'
+                )
+            )
+        );
+        $model->addData($modelData);
+        try {
+            $model->save();
+        } catch (Exception $e) {
+            $this->_fault('unable_to_remove_option', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Prepare request input data for saving
+     *
+     * @param array $data input data
+     * @return void
+     */
+    protected function _prepareDataForSave(&$data)
+    {
+        /** @var $helperCatalog Mage_Catalog_Helper_Data */
+        $helperCatalog = Mage::helper('Mage_Catalog_Helper_Data');
+
+        if ($data['scope'] == 'global') {
+            $data['is_global'] = Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL;
+        } else if ($data['scope'] == 'website') {
+            $data['is_global'] = Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_WEBSITE;
+        } else {
+            $data['is_global'] = Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE;
+        }
+        if (!isset($data['is_configurable'])) {
+            $data['is_configurable'] = 0;
+        }
+        if (!isset($data['is_filterable'])) {
+            $data['is_filterable'] = 0;
+        }
+        if (!isset($data['is_filterable_in_search'])) {
+            $data['is_filterable_in_search'] = 0;
+        }
+        if (!isset($data['apply_to'])) {
+            $data['apply_to'] = array();
+        }
+        // set frontend labels array with store_id as keys
+        if (isset($data['frontend_label']) && is_array($data['frontend_label'])) {
+            $labels = array();
+            foreach ($data['frontend_label'] as $label) {
+                $storeId = $label['store_id'];
+                $labelText = $helperCatalog->stripTags($label['label']);
+                $labels[$storeId] = $labelText;
+            }
+            $data['frontend_label'] = $labels;
+        }
+        // set additional fields
+        if (isset($data['additional_fields']) && is_array($data['additional_fields'])) {
+            $data = array_merge($data, $data['additional_fields']);
+            unset($data['additional_fields']);
+        }
+        //default value
+        if (!empty($data['default_value'])) {
+            $data['default_value'] = $helperCatalog->stripTags($data['default_value']);
+        }
+    }
+
+    /**
+     * Load model by attribute ID or code
+     *
+     * @param integer|string $attribute
+     * @return Mage_Catalog_Model_Resource_Eav_Attribute
+     */
+    protected function _getAttribute($attribute)
+    {
+        $model = Mage::getResourceModel('Mage_Catalog_Model_Resource_Eav_Attribute')
+            ->setEntityTypeId($this->_entityTypeId);
+
+        if (is_numeric($attribute)) {
+            $model->load(intval($attribute));
+        } else {
+            $model->load($attribute, 'attribute_code');
+        }
+
+        if (!$model->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        return $model;
+    }
+
+} // Class Mage_Catalog_Model_Product_Attribute_Api End
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Api/V2.php
new file mode 100644
index 00000000000..b9098d61408
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Api/V2.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product attribute api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Attribute_Api_V2 extends Mage_Catalog_Model_Product_Attribute_Api
+{
+    /**
+     * Create new product attribute
+     *
+     * @param array $data input data
+     * @return integer
+     */
+    public function create($data)
+    {
+        $helper = Mage::helper('Mage_Api_Helper_Data');
+        $helper->v2AssociativeArrayUnpacker($data);
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::create($data);
+    }
+
+    /**
+     * Update product attribute
+     *
+     * @param string|integer $attribute attribute code or ID
+     * @param array $data
+     * @return boolean
+     */
+    public function update($attribute, $data)
+    {
+        $helper = Mage::helper('Mage_Api_Helper_Data');
+        $helper->v2AssociativeArrayUnpacker($data);
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::update($attribute, $data);
+    }
+
+    /**
+     * Add option to select or multiselect attribute
+     *
+     * @param  integer|string $attribute attribute ID or code
+     * @param  array $data
+     * @return bool
+     */
+    public function addOption($attribute, $data)
+    {
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::addOption($attribute, $data);
+    }
+
+    /**
+     * Get full information about attribute with list of options
+     *
+     * @param integer|string $attribute attribute ID or code
+     * @return array
+     */
+    public function info($attribute)
+    {
+        $result = parent::info($attribute);
+        if (!empty($result['additional_fields'])){
+            $keys = array_keys($result['additional_fields']);
+            foreach ($keys as $key ) {
+                $result['additional_fields'][] = array(
+                    'key' => $key,
+                    'value' => $result['additional_fields'][$key]
+                );
+                unset($result['additional_fields'][$key]);
+            }
+        }
+        return $result;
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php
index e4c946c1779..c04904896e8 100644
--- a/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Backend/Media.php
@@ -42,6 +42,11 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
      */
     protected $_resourceModel;
 
+    /**
+     * @var Mage_Catalog_Model_Product_Media_Config
+     */
+    protected $_mediaConfig;
+
     /**
      * @var Magento_Filesystem $filesystem
      */
@@ -60,19 +65,26 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
     /**
      * Constructor to inject dependencies
      *
+     * @param Mage_Catalog_Model_Product_Media_Config $mediaConfig
+     * @param Mage_Core_Model_Dir $dirs
      * @param Magento_Filesystem $filesystem
      * @param array $data
      */
-    public function __construct(Magento_Filesystem $filesystem, $data = array())
-    {
+    public function __construct(
+        Mage_Catalog_Model_Product_Media_Config $mediaConfig,
+        Mage_Core_Model_Dir $dirs,
+        Magento_Filesystem $filesystem,
+        $data = array()
+    ) {
         if (isset($data['resourceModel'])) {
             $this->_resourceModel = $data['resourceModel'];
         }
+        $this->_mediaConfig = $mediaConfig;
         $this->_filesystem = $filesystem;
         $this->_filesystem->setIsAllowCreateDirectories(true);
-        $this->_filesystem->setWorkingDirectory(Mage::getBaseDir('media'));
-        $this->_baseMediaPath = $this->_getConfig()->getBaseMediaPath();
-        $this->_baseTmpMediaPath = $this->_getConfig()->getBaseTmpMediaPath();
+        $this->_filesystem->setWorkingDirectory($dirs->getDir(Mage_Core_Model_Dir::MEDIA));
+        $this->_baseMediaPath = $this->_mediaConfig->getBaseMediaPath();
+        $this->_baseTmpMediaPath = $this->_mediaConfig->getBaseTmpMediaPath();
         $this->_filesystem->ensureDirectoryExists($this->_baseMediaPath);
         $this->_filesystem->ensureDirectoryExists($this->_baseTmpMediaPath);
     }
@@ -329,7 +341,7 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
 
         $fileName = $this->_getNotDuplicatedFilename($fileName, $dispretionPath);
 
-        $destinationFile = $this->_getConfig()->getTmpMediaPath($fileName);
+        $destinationFile = $this->_mediaConfig->getTmpMediaPath($fileName);
 
         try {
             /** @var $storageHelper Mage_Core_Helper_File_Storage_Database */
@@ -338,11 +350,11 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
                 $this->_filesystem->rename($file, $destinationFile, $this->_baseTmpMediaPath);
 
                 //If this is used, filesystem should be configured properly
-                $storageHelper->saveFile($this->_getConfig()->getTmpMediaShortUrl($fileName));
+                $storageHelper->saveFile($this->_mediaConfig->getTmpMediaShortUrl($fileName));
             } else {
                 $this->_filesystem->copy($file, $destinationFile, $this->_baseTmpMediaPath);
 
-                $storageHelper->saveFile($this->_getConfig()->getTmpMediaShortUrl($fileName));
+                $storageHelper->saveFile($this->_mediaConfig->getTmpMediaShortUrl($fileName));
                 $this->_filesystem->changePermissions($destinationFile, 0777, false, $this->_baseTmpMediaPath);
             }
         } catch (Exception $e) {
@@ -576,16 +588,6 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
         return $this->_resourceModel;
     }
 
-    /**
-     * Retrive media config
-     *
-     * @return Mage_Catalog_Model_Product_Media_Config
-     */
-    protected function _getConfig()
-    {
-        return Mage::getSingleton('Mage_Catalog_Model_Product_Media_Config');
-    }
-
     /**
      * Move image from temporary directory to normal
      *
@@ -604,16 +606,16 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
 
         if ($storageHelper->checkDbUsage()) {
             $storageHelper->renameFile(
-                $this->_getConfig()->getTmpMediaShortUrl($file),
-                $this->_getConfig()->getMediaShortUrl($destinationFile)
+                $this->_mediaConfig->getTmpMediaShortUrl($file),
+                $this->_mediaConfig->getMediaShortUrl($destinationFile)
             );
 
-            $this->_filesystem->delete($this->_getConfig()->getTmpMediaPath($file), $this->_baseTmpMediaPath);
-            $this->_filesystem->delete($this->_getConfig()->getMediaPath($destinationFile), $this->_baseMediaPath);
+            $this->_filesystem->delete($this->_mediaConfig->getTmpMediaPath($file), $this->_baseTmpMediaPath);
+            $this->_filesystem->delete($this->_mediaConfig->getMediaPath($destinationFile), $this->_baseMediaPath);
         } else {
             $this->_filesystem->rename(
-                $this->_getConfig()->getTmpMediaPath($file),
-                $this->_getConfig()->getMediaPath($destinationFile),
+                $this->_mediaConfig->getTmpMediaPath($file),
+                $this->_mediaConfig->getMediaPath($destinationFile),
                 $this->_baseTmpMediaPath,
                 $this->_baseMediaPath
             );
@@ -638,7 +640,7 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
                 );
         } else {
             $destFile = dirname($file) . DS
-                . Mage_Core_Model_File_Uploader::getNewFileName($this->_getConfig()->getMediaPath($file));
+                . Mage_Core_Model_File_Uploader::getNewFileName($this->_mediaConfig->getMediaPath($file));
         }
 
         return $destFile;
@@ -655,27 +657,27 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
         try {
             $destinationFile = $this->_getUniqueFileName($file);
 
-            if (!$this->_filesystem->isFile($this->_getConfig()->getMediaPath($file), $this->_baseMediaPath)) {
+            if (!$this->_filesystem->isFile($this->_mediaConfig->getMediaPath($file), $this->_baseMediaPath)) {
                 throw new Exception();
             }
 
             if (Mage::helper('Mage_Core_Helper_File_Storage_Database')->checkDbUsage()) {
                 Mage::helper('Mage_Core_Helper_File_Storage_Database')
-                    ->copyFile($this->_getConfig()->getMediaShortUrl($file),
-                               $this->_getConfig()->getMediaShortUrl($destinationFile));
+                    ->copyFile($this->_mediaConfig->getMediaShortUrl($file),
+                               $this->_mediaConfig->getMediaShortUrl($destinationFile));
 
-                $this->_filesystem->delete($this->_getConfig()->getMediaPath($destinationFile), $this->_baseMediaPath);
+                $this->_filesystem->delete($this->_mediaConfig->getMediaPath($destinationFile), $this->_baseMediaPath);
             } else {
                 $this->_filesystem->copy(
-                    $this->_getConfig()->getMediaPath($file),
-                    $this->_getConfig()->getMediaPath($destinationFile),
+                    $this->_mediaConfig->getMediaPath($file),
+                    $this->_mediaConfig->getMediaPath($destinationFile),
                     $this->_baseMediaPath
                 );
             }
 
             return str_replace(DS, '/', $destinationFile);
         } catch (Exception $e) {
-            $file = $this->_getConfig()->getMediaPath($file);
+            $file = $this->_mediaConfig->getMediaPath($file);
             Mage::throwException(
                 Mage::helper('Mage_Catalog_Helper_Data')
                     ->__('Failed to copy file %s. Please, delete media with non-existing images and try again.', $file)
@@ -712,9 +714,9 @@ class Mage_Catalog_Model_Product_Attribute_Backend_Media extends Mage_Eav_Model_
     protected function _getNotDuplicatedFilename($fileName, $dispretionPath)
     {
         $fileMediaName = $dispretionPath . DS
-                  . Mage_Core_Model_File_Uploader::getNewFileName($this->_getConfig()->getMediaPath($fileName));
+                  . Mage_Core_Model_File_Uploader::getNewFileName($this->_mediaConfig->getMediaPath($fileName));
         $fileTmpMediaName = $dispretionPath . DS
-                  . Mage_Core_Model_File_Uploader::getNewFileName($this->_getConfig()->getTmpMediaPath($fileName));
+                  . Mage_Core_Model_File_Uploader::getNewFileName($this->_mediaConfig->getTmpMediaPath($fileName));
 
         if ($fileMediaName != $fileTmpMediaName) {
             if ($fileMediaName != $fileName) {
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Media/Api.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Media/Api.php
new file mode 100644
index 00000000000..48665dc4ee0
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Media/Api.php
@@ -0,0 +1,421 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product media api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Attribute_Media_Api extends Mage_Catalog_Model_Api_Resource
+{
+    /**
+     * Attribute code for media gallery
+     *
+     */
+    const ATTRIBUTE_CODE = 'media_gallery';
+
+    /**
+     * Allowed mime types for image
+     *
+     * @var array
+     */
+    protected $_mimeTypes = array(
+        'image/jpeg' => 'jpg',
+        'image/gif'  => 'gif',
+        'image/png'  => 'png'
+    );
+
+    /** @var Mage_Catalog_Model_Product_Media_Config */
+    protected $_mediaConfig;
+
+    public function __construct(Mage_Catalog_Model_Product_Media_Config $mediaConfig)
+    {
+        $this->_mediaConfig = $mediaConfig;
+        $this->_storeIdSessionField = 'product_store_id';
+    }
+
+    /**
+     * Retrieve images for product
+     *
+     * @param int|string $productId
+     * @param string|int $store
+     * @return array
+     */
+    public function items($productId, $store = null, $identifierType = null)
+    {
+        $product = $this->_initProduct($productId, $store, $identifierType);
+
+        $gallery = $this->_getGalleryAttribute($product);
+
+        $galleryData = $product->getData(self::ATTRIBUTE_CODE);
+
+        if (!isset($galleryData['images']) || !is_array($galleryData['images'])) {
+            return array();
+        }
+
+        $result = array();
+
+        foreach ($galleryData['images'] as &$image) {
+            $result[] = $this->_imageToArray($image, $product);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve image data
+     *
+     * @param int|string $productId
+     * @param string $file
+     * @param string|int $store
+     * @return array
+     */
+    public function info($productId, $file, $store = null, $identifierType = null)
+    {
+        $product = $this->_initProduct($productId, $store, $identifierType);
+
+        $gallery = $this->_getGalleryAttribute($product);
+
+        if (!$image = $gallery->getBackend()->getImage($product, $file)) {
+            $this->_fault('not_exists');
+        }
+
+        return $this->_imageToArray($image, $product);
+    }
+
+    /**
+     * Create new image for product and return image filename
+     *
+     * @throws Mage_Api_Exception
+     * @param int|string $productId
+     * @param array $data
+     * @param string|int $store
+     * @return string
+     */
+    public function create($productId, $data, $store = null, $identifierType = null)
+    {
+        $data = $this->_prepareImageData($data);
+
+        $product = $this->_initProduct($productId, $store, $identifierType);
+
+        $gallery = $this->_getGalleryAttribute($product);
+
+        if (!isset($data['file']) || !isset($data['file']['mime']) || !isset($data['file']['content'])) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('The image is not specified.'));
+        }
+
+        if (!isset($this->_mimeTypes[$data['file']['mime']])) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Invalid image type.'));
+        }
+
+        $fileContent = @base64_decode($data['file']['content'], true);
+        if (!$fileContent) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('The image contents is not valid base64 data.'));
+        }
+
+        unset($data['file']['content']);
+
+        $tmpDirectory = $this->_mediaConfig->getBaseTmpMediaPath() . DS . microtime();
+
+        if (isset($data['file']['name']) && $data['file']['name']) {
+            $fileName  = $data['file']['name'];
+        } else {
+            $fileName  = 'image';
+        }
+        $fileName .= '.' . $this->_mimeTypes[$data['file']['mime']];
+
+        $ioAdapter = new Varien_Io_File();
+        try {
+            // Create temporary directory for api
+            $ioAdapter->checkAndCreateFolder($tmpDirectory);
+            $ioAdapter->open(array('path'=>$tmpDirectory));
+            // Write image file
+            $ioAdapter->write($fileName, $fileContent, 0666);
+            unset($fileContent);
+
+            // try to create Image object - it fails with Exception if image is not supported
+            try {
+                $adapter = Mage::helper('Mage_Core_Helper_Data')->getImageAdapterType();
+                new Varien_Image($tmpDirectory . DS . $fileName, $adapter);
+            } catch (Exception $e) {
+                // Remove temporary directory
+                $ioAdapter->rmdir($tmpDirectory, true);
+
+                throw new Mage_Core_Exception($e->getMessage());
+            }
+
+            // Adding image to gallery
+            $file = $gallery->getBackend()->addImage(
+                $product,
+                $tmpDirectory . DS . $fileName,
+                null,
+                true
+            );
+
+            // Remove temporary directory
+            $ioAdapter->rmdir($tmpDirectory, true);
+
+            $gallery->getBackend()->updateImage($product, $file, $data);
+
+            if (isset($data['types'])) {
+                $gallery->getBackend()->setMediaAttribute($product, $data['types'], $file);
+            }
+
+            $product->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_created', $e->getMessage());
+        } catch (Exception $e) {
+            $this->_fault('not_created', Mage::helper('Mage_Catalog_Helper_Data')->__('Cannot create image.'));
+        }
+
+        return $gallery->getBackend()->getRenamedImage($file);
+    }
+
+    /**
+     * Update image data
+     *
+     * @param int|string $productId
+     * @param string $file
+     * @param array $data
+     * @param string|int $store
+     * @return boolean
+     */
+    public function update($productId, $file, $data, $store = null, $identifierType = null)
+    {
+        $data = $this->_prepareImageData($data);
+
+        $product = $this->_initProduct($productId, $store, $identifierType);
+
+        $gallery = $this->_getGalleryAttribute($product);
+
+        if (!$gallery->getBackend()->getImage($product, $file)) {
+            $this->_fault('not_exists');
+        }
+
+        if (isset($data['file']['mime']) && isset($data['file']['content'])) {
+            if (!isset($this->_mimeTypes[$data['file']['mime']])) {
+                $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Invalid image type.'));
+            }
+
+            $fileContent = @base64_decode($data['file']['content'], true);
+            if (!$fileContent) {
+                $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Image content is not valid base64 data.'));
+            }
+
+            unset($data['file']['content']);
+
+            $ioAdapter = new Varien_Io_File();
+            try {
+                $fileName = $this->_mediaConfig->getMediaPath($file);
+                $ioAdapter->open(array('path'=>dirname($fileName)));
+                $ioAdapter->write(basename($fileName), $fileContent, 0666);
+
+            } catch(Exception $e) {
+                $this->_fault('not_created', Mage::helper('Mage_Catalog_Helper_Data')->__('Can\'t create image.'));
+            }
+        }
+
+        $gallery->getBackend()->updateImage($product, $file, $data);
+
+        if (isset($data['types']) && is_array($data['types'])) {
+            $oldTypes = array();
+            foreach ($product->getMediaAttributes() as $attribute) {
+                if ($product->getData($attribute->getAttributeCode()) == $file) {
+                     $oldTypes[] = $attribute->getAttributeCode();
+                }
+            }
+
+            $clear = array_diff($oldTypes, $data['types']);
+
+            if (count($clear) > 0) {
+                $gallery->getBackend()->clearMediaAttribute($product, $clear);
+            }
+
+            $gallery->getBackend()->setMediaAttribute($product, $data['types'], $file);
+        }
+
+        try {
+            $product->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_updated', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Remove image from product
+     *
+     * @param int|string $productId
+     * @param string $file
+     * @return boolean
+     */
+    public function remove($productId, $file, $identifierType = null)
+    {
+        $product = $this->_initProduct($productId, null, $identifierType);
+
+        $gallery = $this->_getGalleryAttribute($product);
+
+        if (!$gallery->getBackend()->getImage($product, $file)) {
+            $this->_fault('not_exists');
+        }
+
+        $gallery->getBackend()->removeImage($product, $file);
+
+        try {
+            $product->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_removed', $e->getMessage());
+        }
+
+        return true;
+    }
+
+
+    /**
+     * Retrieve image types (image, small_image, thumbnail, etc...)
+     *
+     * @param int $setId
+     * @return array
+     */
+    public function types($setId)
+    {
+        $attributes = Mage::getModel('Mage_Catalog_Model_Product')->getResource()
+                ->loadAllAttributes()
+                ->getSortedAttributes($setId);
+
+        $result = array();
+
+        foreach ($attributes as $attribute) {
+            /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
+            if ($attribute->isInSet($setId)
+                && $attribute->getFrontendInput() == 'media_image') {
+                if ($attribute->isScopeGlobal()) {
+                    $scope = 'global';
+                } elseif ($attribute->isScopeWebsite()) {
+                    $scope = 'website';
+                } else {
+                    $scope = 'store';
+                }
+
+                $result[] = array(
+                    'code'         => $attribute->getAttributeCode(),
+                    'scope'        => $scope
+                );
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Prepare data to create or update image
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function _prepareImageData($data)
+    {
+        return $data;
+    }
+
+    /**
+     * Retrieve gallery attribute from product
+     *
+     * @param Mage_Catalog_Model_Product $product
+     * @param Mage_Catalog_Model_Resource_Attribute|boolean
+     */
+    protected function _getGalleryAttribute($product)
+    {
+        $attributes = $product->getTypeInstance()
+            ->getSetAttributes($product);
+
+        if (!isset($attributes[self::ATTRIBUTE_CODE])) {
+            $this->_fault('not_media');
+        }
+
+        return $attributes[self::ATTRIBUTE_CODE];
+    }
+
+    /**
+     * Retrie
+     * ve media config
+     *
+     * @return Mage_Catalog_Model_Product_Media_Config
+     */
+    protected function _getMediaConfig()
+    {
+        return Mage::getSingleton('Mage_Catalog_Model_Product_Media_Config');
+    }
+
+    /**
+     * Converts image to api array data
+     *
+     * @param array $image
+     * @param Mage_Catalog_Model_Product $product
+     * @return array
+     */
+    protected function _imageToArray(&$image, $product)
+    {
+        $result = array(
+            'file'      => $image['file'],
+            'label'     => $image['label'],
+            'position'  => $image['position'],
+            'exclude'   => $image['disabled'],
+            'url'       => $this->_getMediaConfig()->getMediaUrl($image['file']),
+            'types'     => array()
+        );
+
+
+        foreach ($product->getMediaAttributes() as $attribute) {
+            if ($product->getData($attribute->getAttributeCode()) == $image['file']) {
+                $result['types'][] = $attribute->getAttributeCode();
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve product
+     *
+     * @param int|string $productId
+     * @param string|int $store
+     * @param  string $identifierType
+     * @return Mage_Catalog_Model_Product
+     */
+    protected function _initProduct($productId, $store = null, $identifierType = null)
+    {
+        $product = Mage::helper('Mage_Catalog_Helper_Product')->getProduct($productId, $this->_getStoreId($store), $identifierType);
+        if (!$product->getId()) {
+            $this->_fault('product_not_exists');
+        }
+
+        return $product;
+    }
+} // Class Mage_Catalog_Model_Product_Attribute_Media_Api End
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Media/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Media/Api/V2.php
new file mode 100644
index 00000000000..35a1abaf46e
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Media/Api/V2.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product media api V2
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Attribute_Media_Api_V2 extends Mage_Catalog_Model_Product_Attribute_Media_Api
+{
+    /**
+     * Prepare data to create or update image
+     *
+     * @param stdClass $data
+     * @return array
+     */
+    protected function _prepareImageData($data)
+    {
+        if( !is_object($data) ) {
+            return parent::_prepareImageData($data);
+        }
+        $_imageData = get_object_vars($data);
+        if( isset($data->file) && is_object($data->file) ) {
+            $_imageData['file'] = get_object_vars($data->file);
+        }
+        return parent::_prepareImageData($_imageData);
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Set/Api.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Set/Api.php
new file mode 100644
index 00000000000..66489bb9baf
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Set/Api.php
@@ -0,0 +1,287 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product attribute set api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Attribute_Set_Api extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Retrieve attribute set list
+     *
+     * @return array
+     */
+    public function items()
+    {
+        $entityType = Mage::getModel('Mage_Catalog_Model_Product')->getResource()->getEntityType();
+        $collection = Mage::getResourceModel('Mage_Eav_Model_Resource_Entity_Attribute_Set_Collection')
+            ->setEntityTypeFilter($entityType->getId());
+
+        $result = array();
+        foreach ($collection as $attributeSet) {
+            $result[] = array(
+                'set_id' => $attributeSet->getId(),
+                'name'   => $attributeSet->getAttributeSetName()
+            );
+
+        }
+
+        return $result;
+    }
+
+    /**
+     * Create new attribute set based on another set
+     *
+     * @param string $attributeSetName
+     * @param string $skeletonSetId
+     * @return integer
+     */
+    public function create($attributeSetName, $skeletonSetId)
+    {
+        // check if set with requested $skeletonSetId exists
+        if (!Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set')->load($skeletonSetId)->getId()){
+            $this->_fault('invalid_skeleton_set_id');
+        }
+        // get catalog product entity type id
+        $entityTypeId = Mage::getModel('Mage_Catalog_Model_Product')->getResource()->getTypeId();
+        /** @var $attributeSet Mage_Eav_Model_Entity_Attribute_Set */
+        $attributeSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set')
+                ->setEntityTypeId($entityTypeId)
+                ->setAttributeSetName($attributeSetName);
+        try {
+            // check if name is valid
+            $attributeSet->validate();
+            // copy parameters to new set from skeleton set
+            $attributeSet->save();
+            $attributeSet->initFromSkeleton($skeletonSetId)->save();
+        } catch (Mage_Eav_Exception $e) {
+            $this->_fault('invalid_data', $e->getMessage());
+        } catch (Exception $e) {
+            $this->_fault('create_attribute_set_error', $e->getMessage());
+        }
+        return (int)$attributeSet->getId();
+    }
+
+    /**
+     * Remove attribute set
+     *
+     * @param string $attributeSetId
+     * @param bool $forceProductsRemove
+     * @return bool
+     */
+    public function remove($attributeSetId, $forceProductsRemove = false)
+    {
+        // if attribute set has related goods and $forceProductsRemove is not set throw exception
+        if (!$forceProductsRemove) {
+            /** @var $catalogProductsCollection Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
+            $catalogProductsCollection = Mage::getModel('Mage_Catalog_Model_Product')->getCollection()
+                    ->addFieldToFilter('attribute_set_id', $attributeSetId);
+            if (count($catalogProductsCollection)) {
+                $this->_fault('attribute_set_has_related_products');
+            }
+        }
+        $attributeSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set')->load($attributeSetId);
+        // check if set with requested id exists
+        if (!$attributeSet->getId()){
+            $this->_fault('invalid_attribute_set_id');
+        }
+        try {
+            $attributeSet->delete();
+        } catch (Exception $e) {
+            $this->_fault('remove_attribute_set_error', $e->getMessage());
+        }
+        return true;
+    }
+
+    /**
+     * Add attribute to attribute set
+     *
+     * @param string $attributeId
+     * @param string $attributeSetId
+     * @param string|null $attributeGroupId
+     * @param string $sortOrder
+     * @return bool
+     */
+    public function attributeAdd($attributeId, $attributeSetId, $attributeGroupId = null, $sortOrder = '0')
+    {
+        // check if attribute with requested id exists
+        /** @var $attribute Mage_Eav_Model_Entity_Attribute */
+        $attribute = Mage::getModel('Mage_Eav_Model_Entity_Attribute')->load($attributeId);
+        if (!$attribute->getId()) {
+            $this->_fault('invalid_attribute_id');
+        }
+        // check if attribute set with requested id exists
+        /** @var $attributeSet Mage_Eav_Model_Entity_Attribute_Set */
+        $attributeSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set')->load($attributeSetId);
+        if (!$attributeSet->getId()) {
+            $this->_fault('invalid_attribute_set_id');
+        }
+        if (!empty($attributeGroupId)) {
+            // check if attribute group with requested id exists
+            if (!Mage::getModel('Mage_Eav_Model_Entity_Attribute_Group')->load($attributeGroupId)->getId()) {
+                $this->_fault('invalid_attribute_group_id');
+            }
+        } else {
+            // define default attribute group id for current attribute set
+            $attributeGroupId = $attributeSet->getDefaultGroupId();
+        }
+        $attribute->setAttributeSetId($attributeSet->getId())->loadEntityAttributeIdBySet();
+        if ($attribute->getEntityAttributeId()) {
+            $this->_fault('attribute_is_already_in_set');
+        }
+        try {
+           $attribute->setEntityTypeId($attributeSet->getEntityTypeId())
+                    ->setAttributeSetId($attributeSetId)
+                    ->setAttributeGroupId($attributeGroupId)
+                    ->setSortOrder($sortOrder)
+                    ->save();
+        } catch (Exception $e) {
+            $this->_fault('add_attribute_error', $e->getMessage());
+        }
+        return true;
+    }
+
+    /**
+     * Remove attribute from attribute set
+     *
+     * @param string $attributeId
+     * @param string $attributeSetId
+     * @return bool
+     */
+    public function attributeRemove($attributeId, $attributeSetId)
+    {
+        // check if attribute with requested id exists
+        /** @var $attribute Mage_Eav_Model_Entity_Attribute */
+        $attribute = Mage::getModel('Mage_Eav_Model_Entity_Attribute')->load($attributeId);
+        if (!$attribute->getId()) {
+            $this->_fault('invalid_attribute_id');
+        }
+        // check if attribute set with requested id exists
+        /** @var $attributeSet Mage_Eav_Model_Entity_Attribute_Set */
+        $attributeSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set')->load($attributeSetId);
+        if (!$attributeSet->getId()) {
+            $this->_fault('invalid_attribute_set_id');
+        }
+        // check if attribute is in set
+        $attribute->setAttributeSetId($attributeSet->getId())->loadEntityAttributeIdBySet();
+        if (!$attribute->getEntityAttributeId()) {
+            $this->_fault('attribute_is_not_in_set');
+        }
+        try {
+            // delete record from eav_entity_attribute
+            // using entity_attribute_id loaded by loadEntityAttributeIdBySet()
+            $attribute->deleteEntity();
+        } catch (Exception $e) {
+            $this->_fault('remove_attribute_error', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Create group within existing attribute set
+     *
+     * @param  string|int $attributeSetId
+     * @param  string $groupName
+     * @return int
+     */
+    public function groupAdd($attributeSetId, $groupName)
+    {
+        /** @var $group Mage_Eav_Model_Entity_Attribute_Group */
+        $group = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Group');
+        $group->setAttributeSetId($attributeSetId)
+                ->setAttributeGroupName(
+                    Mage::helper('Mage_Catalog_Helper_Data')->stripTags($groupName)
+                );
+        if ($group->itemExists()) {
+            $this->_fault('group_already_exists');
+        }
+        try {
+            $group->save();
+        } catch (Exception $e) {
+            $this->_fault('group_add_error', $e->getMessage());
+        }
+        return (int)$group->getId();
+    }
+
+    /**
+     * Rename existing group
+     *
+     * @param string|int $groupId
+     * @param string $groupName
+     * @return boolean
+     */
+    public function groupRename($groupId, $groupName)
+    {
+        $model = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Group')->load($groupId);
+
+        if (!$model->getAttributeGroupName()) {
+            $this->_fault('invalid_attribute_group_id');
+        }
+
+        $model->setAttributeGroupName(
+                Mage::helper('Mage_Catalog_Helper_Data')->stripTags($groupName)
+        );
+        try {
+            $model->save();
+        } catch (Exception $e) {
+            $this->_fault('group_rename_error', $e->getMessage());
+        }
+        return true;
+    }
+
+    /**
+        * Remove group from existing attribute set
+        *
+        * @param  string|int $attributeGroupId
+        * @return bool
+        */
+       public function groupRemove($attributeGroupId)
+       {
+           /** @var $group Mage_Catalog_Model_Product_Attribute_Group */
+           $group = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Group')->load($attributeGroupId);
+           if (!$group->getId()) {
+               $this->_fault('invalid_attribute_group_id');
+           }
+           if ($group->hasConfigurableAttributes()) {
+               $this->_fault('group_has_configurable_attributes');
+           }
+           if ($group->hasSystemAttributes()) {
+               $this->_fault('group_has_system_attributes');
+           }
+           try {
+               $group->delete();
+           } catch (Exception $e) {
+               $this->_fault('group_remove_error', $e->getMessage());
+           }
+           return true;
+       }
+
+} // Class Mage_Catalog_Model_Product_Attribute_Set_Api End
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Set/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Set/Api/V2.php
new file mode 100644
index 00000000000..d3569545110
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Set/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product attribute set api V2
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Attribute_Set_Api_V2 extends Mage_Catalog_Model_Product_Attribute_Set_Api
+{
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api.php
new file mode 100644
index 00000000000..14e4080bbac
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog Product tier price api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Attribute_Tierprice_Api extends Mage_Catalog_Model_Api_Resource
+{
+    const ATTRIBUTE_CODE = 'tier_price';
+
+    public function __construct()
+    {
+        $this->_storeIdSessionField = 'product_store_id';
+    }
+
+    public function info($productId, $identifierType = null)
+    {
+        $product = $this->_initProduct($productId, $identifierType);
+        $tierPrices = $product->getData(self::ATTRIBUTE_CODE);
+
+        if (!is_array($tierPrices)) {
+            return array();
+        }
+
+        $result = array();
+
+        foreach ($tierPrices as $tierPrice) {
+            $row = array();
+            $row['customer_group_id'] = (empty($tierPrice['all_groups']) ? $tierPrice['cust_group'] : 'all' );
+            $row['website']           = ($tierPrice['website_id'] ?
+                            Mage::app()->getWebsite($tierPrice['website_id'])->getCode() :
+                            'all'
+                    );
+            $row['qty']               = $tierPrice['price_qty'];
+            $row['price']             = $tierPrice['price'];
+
+            $result[] = $row;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Update tier prices of product
+     *
+     * @param int|string $productId
+     * @param array $tierPrices
+     * @return boolean
+     */
+    public function update($productId, $tierPrices, $identifierType = null)
+    {
+        $product = $this->_initProduct($productId, $identifierType);
+
+        $updatedTierPrices = $this->prepareTierPrices($product, $tierPrices);
+        if (is_null($updatedTierPrices)) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Invalid Tier Prices'));
+        }
+
+        $product->setData(self::ATTRIBUTE_CODE, $updatedTierPrices);
+        try {
+            /**
+             * @todo implement full validation process with errors returning which are ignoring now
+             * @todo see Mage_Catalog_Model_Product::validate()
+             */
+            if (is_array($errors = $product->validate())) {
+                $strErrors = array();
+                foreach($errors as $code=>$error) {
+                    $strErrors[] = ($error === true)? Mage::helper('Mage_Catalog_Helper_Data')->__('Value for "%s" is invalid.', $code) : Mage::helper('Mage_Catalog_Helper_Data')->__('Value for "%s" is invalid: %s', $code, $error);
+                }
+                $this->_fault('data_invalid', implode("\n", $strErrors));
+            }
+
+            $product->save();
+        } catch (Mage_Api_Exception $e) {
+            throw $e;
+        }catch (Mage_Core_Exception $e) {
+            $this->_fault('not_updated', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     *  Prepare tier prices for save
+     *
+     *  @param      Mage_Catalog_Model_Product $product
+     *  @param      array $tierPrices
+     *  @return     array
+     */
+    public function prepareTierPrices($product, $tierPrices = null)
+    {
+        if (!is_array($tierPrices)) {
+            return null;
+        }
+
+        if (!is_array($tierPrices)) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Invalid Tier Prices'));
+        }
+
+        $updateValue = array();
+
+        foreach ($tierPrices as $tierPrice) {
+            if (!is_array($tierPrice)
+                || !isset($tierPrice['qty'])
+                || !isset($tierPrice['price'])) {
+                $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Invalid Tier Prices'));
+            }
+
+            if (!isset($tierPrice['website']) || $tierPrice['website'] == 'all') {
+                $tierPrice['website'] = 0;
+            } else {
+                try {
+                    $tierPrice['website'] = Mage::app()->getWebsite($tierPrice['website'])->getId();
+                } catch (Mage_Core_Exception $e) {
+                    $tierPrice['website'] = 0;
+                }
+            }
+
+            if (intval($tierPrice['website']) > 0 && !in_array($tierPrice['website'], $product->getWebsiteIds())) {
+                $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Invalid tier prices. The product is not associated to the requested website.'));
+            }
+
+            if (!isset($tierPrice['customer_group_id'])) {
+                $tierPrice['customer_group_id'] = 'all';
+            }
+
+            if ($tierPrice['customer_group_id'] == 'all') {
+                $tierPrice['customer_group_id'] = Mage_Customer_Model_Group::CUST_GROUP_ALL;
+            }
+
+            $updateValue[] = array(
+                'website_id' => $tierPrice['website'],
+                'cust_group' => $tierPrice['customer_group_id'],
+                'price_qty'  => $tierPrice['qty'],
+                'price'      => $tierPrice['price']
+            );
+        }
+
+        return $updateValue;
+    }
+
+    /**
+     * Retrieve product
+     *
+     * @param int $productId
+     * @param  string $identifierType
+     * @return Mage_Catalog_Model_Product
+     */
+    protected function _initProduct($productId, $identifierType = null)
+    {
+        $product = Mage::helper('Mage_Catalog_Helper_Product')->getProduct($productId, $this->_getStoreId(), $identifierType);
+        if (!$product->getId()) {
+            $this->_fault('product_not_exists');
+        }
+
+        return $product;
+    }
+} // Class Mage_Catalog_Model_Product_Attribute_Tierprice End
diff --git a/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php
new file mode 100644
index 00000000000..1ac81133875
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog Product tier price api V2
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2 extends Mage_Catalog_Model_Product_Attribute_Tierprice_Api
+{
+    /**
+     *  Prepare tier prices for save
+     *
+     *  @param      Mage_Catalog_Model_Product $product
+     *  @param      array $tierPrices
+     *  @return     array
+     */
+    public function prepareTierPrices($product, $tierPrices = null)
+    {
+        if (!is_array($tierPrices)) {
+            return null;
+        }
+
+        $updateValue = array();
+
+        foreach ($tierPrices as $tierPrice) {
+            if (!is_object($tierPrice)
+                || !isset($tierPrice->qty)
+                || !isset($tierPrice->price)) {
+                $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Invalid Tier Prices'));
+            }
+
+            if (!isset($tierPrice->website) || $tierPrice->website == 'all') {
+                $tierPrice->website = 0;
+            } else {
+                try {
+                    $tierPrice->website = Mage::app()->getWebsite($tierPrice->website)->getId();
+                } catch (Mage_Core_Exception $e) {
+                    $tierPrice->website = 0;
+                }
+            }
+
+            if (intval($tierPrice->website) > 0 && !in_array($tierPrice->website, $product->getWebsiteIds())) {
+                $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Invalid tier prices. The product is not associated to the requested website.'));
+            }
+
+            if (!isset($tierPrice->customer_group_id)) {
+                $tierPrice->customer_group_id = 'all';
+            }
+
+            if ($tierPrice->customer_group_id == 'all') {
+                $tierPrice->customer_group_id = Mage_Customer_Model_Group::CUST_GROUP_ALL;
+            }
+
+            $updateValue[] = array(
+                'website_id' => $tierPrice->website,
+                'cust_group' => $tierPrice->customer_group_id,
+                'price_qty'  => $tierPrice->qty,
+                'price'      => $tierPrice->price
+            );
+
+        }
+
+        return $updateValue;
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Link/Api.php b/app/code/core/Mage/Catalog/Model/Product/Link/Api.php
new file mode 100644
index 00000000000..bee8a8ae908
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Link/Api.php
@@ -0,0 +1,349 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product link api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Link_Api extends Mage_Catalog_Model_Api_Resource
+{
+    /**
+     * Product link type mapping, used for references and validation
+     *
+     * @var array
+     */
+    protected $_typeMap = array(
+        'related'       => Mage_Catalog_Model_Product_Link::LINK_TYPE_RELATED,
+        'up_sell'       => Mage_Catalog_Model_Product_Link::LINK_TYPE_UPSELL,
+        'cross_sell'    => Mage_Catalog_Model_Product_Link::LINK_TYPE_CROSSSELL,
+        'grouped'       => Mage_Catalog_Model_Product_Link::LINK_TYPE_GROUPED
+    );
+
+    public function __construct()
+    {
+        $this->_storeIdSessionField = 'product_store_id';
+    }
+
+    /**
+     * Retrieve product link associations
+     *
+     * @param string $type
+     * @param int|sku $productId
+     * @param  string $identifierType
+     * @return array
+     */
+    public function items($type, $productId, $identifierType = null)
+    {
+        $typeId = $this->_getTypeId($type);
+
+        $product = $this->_initProduct($productId, $identifierType);
+
+        $link = $product->getLinkInstance()
+            ->setLinkTypeId($typeId);
+
+        $collection = $this->_initCollection($link, $product);
+
+        $result = array();
+
+        foreach ($collection as $linkedProduct) {
+            $row = array(
+                'product_id' => $linkedProduct->getId(),
+                'type'       => $linkedProduct->getTypeId(),
+                'set'        => $linkedProduct->getAttributeSetId(),
+                'sku'        => $linkedProduct->getSku()
+            );
+
+            foreach ($link->getAttributes() as $attribute) {
+                $row[$attribute['code']] = $linkedProduct->getData($attribute['code']);
+            }
+
+            $result[] = $row;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Add product link association
+     *
+     * @param string $type
+     * @param int|string $productId
+     * @param int|string $linkedProductId
+     * @param array $data
+     * @param  string $identifierType
+     * @return boolean
+     */
+    public function assign($type, $productId, $linkedProductId, $data = array(), $identifierType = null)
+    {
+        $typeId = $this->_getTypeId($type);
+
+        $product = $this->_initProduct($productId, $identifierType);
+
+        $link = $product->getLinkInstance()
+            ->setLinkTypeId($typeId);
+
+        $collection = $this->_initCollection($link, $product);
+        $idBySku = $product->getIdBySku($linkedProductId);
+        if ($idBySku) {
+            $linkedProductId = $idBySku;
+        }
+
+        $links = $this->_collectionToEditableArray($collection);
+
+        $links[(int)$linkedProductId] = array();
+
+        foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
+            if (isset($data[$attribute['code']])) {
+                $links[(int)$linkedProductId][$attribute['code']] = $data[$attribute['code']];
+            }
+        }
+
+        try {
+            if ($type == 'grouped') {
+                $link->getResource()->saveGroupedLinks($product, $links, $typeId);
+            } else {
+                $link->getResource()->saveProductLinks($product, $links, $typeId);
+            }
+
+            $_linkInstance = Mage::getSingleton('Mage_Catalog_Model_Product_Link');
+            $_linkInstance->saveProductRelations($product);
+
+            $indexerStock = Mage::getModel('Mage_CatalogInventory_Model_Stock_Status');
+            $indexerStock->updateStatus($productId);
+
+            $indexerPrice = Mage::getResourceModel('Mage_Catalog_Model_Resource_Product_Indexer_Price');
+            $indexerPrice->reindexProductIds($productId);
+        } catch (Exception $e) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Link product does not exist.'));
+        }
+
+        return true;
+    }
+
+    /**
+     * Update product link association info
+     *
+     * @param string $type
+     * @param int|string $productId
+     * @param int|string $linkedProductId
+     * @param array $data
+     * @param  string $identifierType
+     * @return boolean
+     */
+    public function update($type, $productId, $linkedProductId, $data = array(), $identifierType = null)
+    {
+        $typeId = $this->_getTypeId($type);
+
+        $product = $this->_initProduct($productId, $identifierType);
+
+        $link = $product->getLinkInstance()
+            ->setLinkTypeId($typeId);
+
+        $collection = $this->_initCollection($link, $product);
+
+        $links = $this->_collectionToEditableArray($collection);
+
+        $idBySku = $product->getIdBySku($linkedProductId);
+        if ($idBySku) {
+            $linkedProductId = $idBySku;
+        }
+
+        foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
+            if (isset($data[$attribute['code']])) {
+                $links[(int)$linkedProductId][$attribute['code']] = $data[$attribute['code']];
+            }
+        }
+
+        try {
+            if ($type == 'grouped') {
+                $link->getResource()->saveGroupedLinks($product, $links, $typeId);
+            } else {
+                $link->getResource()->saveProductLinks($product, $links, $typeId);
+            }
+
+            $_linkInstance = Mage::getSingleton('Mage_Catalog_Model_Product_Link');
+            $_linkInstance->saveProductRelations($product);
+
+            $indexerStock = Mage::getModel('Mage_CatalogInventory_Model_Stock_Status');
+            $indexerStock->updateStatus($productId);
+
+            $indexerPrice = Mage::getResourceModel('Mage_Catalog_Model_Resource_Product_Indexer_Price');
+            $indexerPrice->reindexProductIds($productId);
+        } catch (Exception $e) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Link product does not exist.'));
+        }
+
+        return true;
+    }
+
+    /**
+     * Remove product link association
+     *
+     * @param string $type
+     * @param int|string $productId
+     * @param int|string $linkedProductId
+     * @param  string $identifierType
+     * @return boolean
+     */
+    public function remove($type, $productId, $linkedProductId, $identifierType = null)
+    {
+        $typeId = $this->_getTypeId($type);
+
+        $product = $this->_initProduct($productId, $identifierType);
+
+        $link = $product->getLinkInstance()
+            ->setLinkTypeId($typeId);
+
+        $collection = $this->_initCollection($link, $product);
+
+        $idBySku = $product->getIdBySku($linkedProductId);
+        if ($idBySku) {
+            $linkedProductId = $idBySku;
+        }
+
+        $links = $this->_collectionToEditableArray($collection);
+
+        if (isset($links[$linkedProductId])) {
+            unset($links[$linkedProductId]);
+        }
+
+        try {
+            $link->getResource()->saveProductLinks($product, $links, $typeId);
+        } catch (Exception $e) {
+            $this->_fault('not_removed');
+        }
+
+        return true;
+    }
+
+    /**
+     * Retrieve attribute list for specified type
+     *
+     * @param string $type
+     * @return array
+     */
+    public function attributes($type)
+    {
+        $typeId = $this->_getTypeId($type);
+
+        $attributes = Mage::getModel('Mage_Catalog_Model_Product_Link')
+            ->getAttributes($typeId);
+
+        $result = array();
+
+        foreach ($attributes as $attribute) {
+            $result[] = array(
+                'code'  => $attribute['code'],
+                'type'  => $attribute['type']
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve link types
+     *
+     * @return array
+     */
+    public function types()
+    {
+        return array_keys($this->_typeMap);
+    }
+
+    /**
+     * Retrieve link type id by code
+     *
+     * @param string $type
+     * @return int
+     */
+    protected function _getTypeId($type)
+    {
+        if (!isset($this->_typeMap[$type])) {
+            $this->_fault('type_not_exists');
+        }
+
+        return $this->_typeMap[$type];
+    }
+
+    /**
+     * Initialize and return product model
+     *
+     * @param int $productId
+     * @param  string $identifierType
+     * @return Mage_Catalog_Model_Product
+     */
+    protected function _initProduct($productId, $identifierType = null)
+    {
+        $product = Mage::helper('Mage_Catalog_Helper_Product')->getProduct($productId, null, $identifierType);
+        if (!$product->getId()) {
+            $this->_fault('product_not_exists');
+        }
+
+        return $product;
+    }
+
+    /**
+     * Initialize and return linked products collection
+     *
+     * @param Mage_Catalog_Model_Product_Link $link
+     * @param Mage_Catalog_Model_Product $product
+     * @return Mage_Catalog_Model_Resource_Product_Link_Product_Collection
+     */
+    protected function _initCollection($link, $product)
+    {
+        $collection = $link
+            ->getProductCollection()
+            ->setIsStrongMode()
+            ->setProduct($product);
+
+        return $collection;
+    }
+
+    /**
+     * Export collection to editable array
+     *
+     * @param Mage_Catalog_Model_Resource_Product_Link_Product_Collection $collection
+     * @return array
+     */
+    protected function _collectionToEditableArray($collection)
+    {
+        $result = array();
+
+        foreach ($collection as $linkedProduct) {
+            $result[$linkedProduct->getId()] = array();
+
+            foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
+                $result[$linkedProduct->getId()][$attribute['code']] = $linkedProduct->getData($attribute['code']);
+            }
+        }
+
+        return $result;
+    }
+} // Class Mage_Catalog_Model_Product_Link_Api End
diff --git a/app/code/core/Mage/Catalog/Model/Product/Link/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Link/Api/V2.php
new file mode 100644
index 00000000000..d7a6717c2d6
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Link/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product link api V2
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Link_Api_V2 extends Mage_Catalog_Model_Product_Link_Api
+{
+    /**
+     * Add product link association
+     *
+     * @param string $type
+     * @param int|string $productId
+     * @param int|string $linkedProductId
+     * @param array $data
+     * @return boolean
+     */
+    public function assign($type, $productId, $linkedProductId, $data = array(), $identifierType = null)
+    {
+        $typeId = $this->_getTypeId($type);
+
+        $product = $this->_initProduct($productId, $identifierType);
+
+        $link = $product->getLinkInstance()
+            ->setLinkTypeId($typeId);
+
+        $collection = $this->_initCollection($link, $product);
+        $idBySku = $product->getIdBySku($linkedProductId);
+        if ($idBySku) {
+            $linkedProductId = $idBySku;
+        }
+
+        $links = $this->_collectionToEditableArray($collection);
+
+        $links[(int)$linkedProductId] = array();
+        foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
+            if (isset($data->$attribute['code'])) {
+                $links[(int)$linkedProductId][$attribute['code']] = $data->$attribute['code'];
+            }
+        }
+
+        try {
+            $link->getResource()->saveProductLinks($product, $links, $typeId);
+        } catch (Exception $e) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Link product does not exist.'));
+        }
+
+        return true;
+    }
+
+    /**
+     * Update product link association info
+     *
+     * @param string $type
+     * @param int|string $productId
+     * @param int|string $linkedProductId
+     * @param array $data
+     * @return boolean
+     */
+    public function update($type, $productId, $linkedProductId, $data = array(), $identifierType = null)
+    {
+        $typeId = $this->_getTypeId($type);
+
+        $product = $this->_initProduct($productId, $identifierType);
+
+        $link = $product->getLinkInstance()
+            ->setLinkTypeId($typeId);
+
+        $collection = $this->_initCollection($link, $product);
+
+        $links = $this->_collectionToEditableArray($collection);
+
+        $idBySku = $product->getIdBySku($linkedProductId);
+        if ($idBySku) {
+            $linkedProductId = $idBySku;
+        }
+
+        foreach ($collection->getLinkModel()->getAttributes() as $attribute) {
+            if (isset($data->$attribute['code'])) {
+                $links[(int)$linkedProductId][$attribute['code']] = $data->$attribute['code'];
+            }
+        }
+
+        try {
+            $link->getResource()->saveProductLinks($product, $links, $typeId);
+        } catch (Exception $e) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Catalog_Helper_Data')->__('Link product does not exist.'));
+        }
+
+        return true;
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Option/Api.php b/app/code/core/Mage/Catalog/Model/Product/Option/Api.php
new file mode 100644
index 00000000000..836a1273877
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Option/Api.php
@@ -0,0 +1,331 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product options api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Option_Api extends Mage_Catalog_Model_Api_Resource
+{
+
+    /**
+     * Add custom option to product
+     *
+     * @param string $productId
+     * @param array $data
+     * @param int|string|null $store
+     * @return bool $isAdded
+     */
+    public function add($productId, $data, $store = null)
+    {
+        $product = $this->_getProduct($productId, $store, null);
+        if (!(is_array($data['additional_fields']) and count($data['additional_fields']))) {
+            $this->_fault('invalid_data');
+        }
+        if (!$this->_isTypeAllowed($data['type'])) {
+            $this->_fault('invalid_type');
+        }
+        $this->_prepareAdditionalFields(
+            $data,
+            $product->getOptionInstance()->getGroupByType($data['type'])
+        );
+        $this->_saveProductCustomOption($product, $data);
+        return true;
+    }
+
+    /**
+     * Update product custom option data
+     *
+     * @param string $optionId
+     * @param array $data
+     * @param int|string|null $store
+     * @return bool
+     */
+    public function update($optionId, $data, $store = null)
+    {
+        /** @var $option Mage_Catalog_Model_Product_Option */
+        $option = Mage::getModel('Mage_Catalog_Model_Product_Option')->load($optionId);
+        if (!$option->getId()) {
+            $this->_fault('option_not_exists');
+        }
+        $product = $this->_getProduct($option->getProductId(), $store, null);
+        $option = $product->getOptionById($optionId);
+        if (isset($data['type']) and !$this->_isTypeAllowed($data['type'])) {
+            $this->_fault('invalid_type');
+        }
+        if (isset($data['additional_fields'])) {
+            $this->_prepareAdditionalFields(
+                $data,
+                $option->getGroupByType()
+            );
+        }
+        foreach ($option->getValues() as $valueId => $value) {
+            if(isset($data['values'][$valueId])) {
+                $data['values'][$valueId] = array_merge($value->getData(), $data['values'][$valueId]);
+            }
+        }
+        $data = array_merge($option->getData(), $data);
+        $this->_saveProductCustomOption($product, $data);
+        return true;
+    }
+
+    /**
+     * Prepare custom option data for saving by model. Used for custom option add and update
+     *
+     * @param array $data
+     * @param string $groupType
+     * @return void
+     */
+    protected function _prepareAdditionalFields(&$data, $groupType)
+    {
+        if (is_array($data['additional_fields'])) {
+            if ($groupType != Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT) {
+                // reset can be used as there should be the only
+                // element in 'additional_fields' for options of all types except those from Select group
+                $field = reset($data['additional_fields']);
+                if (!(is_array($field) and count($field))) {
+                    $this->_fault('invalid_data');
+                } else {
+                    foreach ($field as $key => $value) {
+                        $data[$key] = $value;
+                    }
+                }
+            } else {
+                // convert Select rows array to appropriate format for saving in the model
+                foreach ($data['additional_fields'] as $row) {
+                    if (!(is_array($row) and count($row))) {
+                        $this->_fault('invalid_data');
+                    } else {
+                        foreach ($row as $key => $value) {
+                            $row[$key] = Mage::helper('Mage_Catalog_Helper_Data')->stripTags($value);
+                        }
+                        if (!empty($row['value_id'])) {
+                            // map 'value_id' to 'option_type_id'
+                            $row['option_type_id'] = $row['value_id'];
+                            unset($row['value_id']);
+                            $data['values'][$row['option_type_id']] = $row;
+                        } else {
+                            $data['values'][] = $row;
+                        }
+                    }
+                }
+            }
+        }
+        unset($data['additional_fields']);
+    }
+
+    /**
+     * Save product custom option data. Used for custom option add and update.
+     *
+     * @param Mage_Catalog_Model_Product $product
+     * @param array $data
+     * @return void
+     */
+    protected function _saveProductCustomOption($product, $data)
+    {
+        foreach ($data as $key => $value) {
+            if (is_string($value)) {
+                $data[$key] = Mage::helper('Mage_Catalog_Helper_Data')->stripTags($value);
+            }
+        }
+
+        try {
+            if (!$product->getOptionsReadonly()) {
+                $product
+                    ->getOptionInstance()
+                    ->setOptions(array($data));
+
+                $product->setHasOptions(true);
+
+                // an empty request can be set as event parameter
+                // because it is not used for options changing in observers
+                Mage::dispatchEvent(
+                    'catalog_product_prepare_save',
+                    array('product' => $product, 'request' => new Mage_Core_Controller_Request_Http())
+                );
+
+                $product->save();
+            }
+        } catch (Exception $e) {
+            $this->_fault('save_option_error', $e->getMessage());
+        }
+    }
+
+    /**
+     * Read list of possible custom option types from module config
+     *
+     * @return array
+     */
+    public function types()
+    {
+        $path = Mage_Catalog_Model_Config_Source_Product_Options_Type::PRODUCT_OPTIONS_GROUPS_PATH;
+        $types = array();
+        foreach (Mage::getConfig()->getNode($path)->children() as $group) {
+            $groupTypes = Mage::getConfig()->getNode($path . '/' . $group->getName() . '/types')->children();
+            /** @var $type Mage_Core_Model_Config_Element */
+            foreach($groupTypes as $type){
+                $labelPath = $path . '/' . $group->getName() . '/types/' . $type->getName() . '/label';
+                $types[] = array(
+                    'label' => (string) Mage::getConfig()->getNode($labelPath),
+                    'value' => $type->getName()
+                );
+            }
+        }
+        return $types;
+    }
+
+    /**
+     * Get full information about custom option in product
+     *
+     * @param int|string $optionId
+     * @param  int|string|null $store
+     * @return array
+     */
+    public function info($optionId, $store = null)
+    {
+        /** @var $option Mage_Catalog_Model_Product_Option */
+        $option = Mage::getModel('Mage_Catalog_Model_Product_Option')->load($optionId);
+        if (!$option->getId()) {
+            $this->_fault('option_not_exists');
+        }
+        /** @var $product Mage_Catalog_Model_Product */
+        $product = $this->_getProduct($option->getProductId(), $store, null);
+        $option = $product->getOptionById($optionId);
+        $result = array(
+            'title' => $option->getTitle(),
+            'type' => $option->getType(),
+            'is_require' => $option->getIsRequire(),
+            'sort_order' => $option->getSortOrder(),
+            // additional_fields should be two-dimensional array for all option types
+            'additional_fields' => array(
+                array(
+                    'price' => $option->getPrice(),
+                    'price_type' => $option->getPriceType(),
+                    'sku' => $option->getSku()
+                )
+            )
+        );
+        // Set additional fields to each type group
+        switch ($option->getGroupByType()) {
+            case Mage_Catalog_Model_Product_Option::OPTION_GROUP_TEXT:
+                $result['additional_fields'][0]['max_characters'] = $option->getMaxCharacters();
+                break;
+            case Mage_Catalog_Model_Product_Option::OPTION_GROUP_FILE:
+                $result['additional_fields'][0]['file_extension'] = $option->getFileExtension();
+                $result['additional_fields'][0]['image_size_x'] = $option->getImageSizeX();
+                $result['additional_fields'][0]['image_size_y'] = $option->getImageSizeY();
+                break;
+            case Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT:
+                $result['additional_fields'] = array();
+                foreach ($option->getValuesCollection() as $value) {
+                    $result['additional_fields'][] = array(
+                        'value_id' => $value->getId(),
+                        'title' => $value->getTitle(),
+                        'price' => $value->getPrice(),
+                        'price_type' => $value->getPriceType(),
+                        'sku' => $value->getSku(),
+                        'sort_order' => $value->getSortOrder()
+                    );
+                }
+                break;
+            default:
+                break;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve list of product custom options
+     *
+     * @param  string $productId
+     * @param  int|string|null $store
+     * @return array
+     */
+    public function items($productId, $store = null)
+    {
+        $result = array();
+        $product = $this->_getProduct($productId, $store, null);
+        /** @var $option Mage_Catalog_Model_Product_Option */
+        foreach ($product->getProductOptionsCollection() as $option) {
+            $result[] = array(
+                'option_id' => $option->getId(),
+                'title' => $option->getTitle(),
+                'type' => $option->getType(),
+                'is_require' => $option->getIsRequire(),
+                'sort_order' => $option->getSortOrder()
+            );
+        }
+        return $result;
+    }
+
+    /**
+     * Remove product custom option
+     *
+     * @param string $optionId
+     * @return boolean
+     */
+    public function remove($optionId)
+    {
+        /** @var $option Mage_Catalog_Model_Product_Option */
+        $option = Mage::getModel('Mage_Catalog_Model_Product_Option')->load($optionId);
+        if (!$option->getId()) {
+            $this->_fault('option_not_exists');
+        }
+        try {
+            $option->getValueInstance()->deleteValue($optionId);
+            $option->deletePrices($optionId);
+            $option->deleteTitles($optionId);
+            $option->delete();
+        } catch (Exception $e){
+            $this->fault('delete_option_error');
+        }
+        return true;
+    }
+
+    /**
+     * Check is type in allowed set
+     *
+     * @param string $type
+     * @return bool
+     */
+    protected function _isTypeAllowed($type)
+    {
+        $allowedTypes = array();
+        foreach($this->types() as $optionType){
+            $allowedTypes[] = $optionType['value'];
+        }
+
+        if (!in_array($type, $allowedTypes)) {
+            return false;
+        }
+        return true;
+    }
+
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Option/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Option/Api/V2.php
new file mode 100644
index 00000000000..7078a21b216
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Option/Api/V2.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product options api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Option_Api_V2 extends Mage_Catalog_Model_Product_Option_Api
+{
+
+    /**
+     * Add custom option to product
+     *
+     * @param string $productId
+     * @param array $data
+     * @param int|string|null $store
+     * @return bool
+     */
+    public function add($productId, $data, $store = null)
+    {
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::add($productId, $data, $store);
+    }
+
+    /**
+     * Update product custom option data
+     *
+     * @param string $optionId
+     * @param array $data
+     * @param int|string|null $store
+     * @return bool
+     */
+    public function update($optionId, $data, $store = null)
+    {
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::update($optionId, $data, $store);
+    }
+
+    /**
+     * Retrieve list of product custom options
+     *
+     * @param string $productId
+     * @param int|string|null $store
+     * @return array
+     */
+    public function items($productId, $store = null)
+    {
+        $result = parent::items($productId, $store);
+        foreach ($result as $key => $option) {
+            $result[$key] = Mage::helper('Mage_Api_Helper_Data')->wsiArrayPacker($option);
+        }
+        return $result;
+    }
+
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Option/Value/Api.php b/app/code/core/Mage/Catalog/Model/Product/Option/Value/Api.php
new file mode 100644
index 00000000000..5d8d0f4af1a
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Option/Value/Api.php
@@ -0,0 +1,226 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product option values api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Option_Value_Api extends Mage_Catalog_Model_Api_Resource
+{
+    /**
+     * Retrieve values from specified option
+     *
+     * @param string $optionId
+     * @param int|string|null $store
+     * @return array
+     */
+    public function items($optionId, $store = null)
+    {
+        /** @var $option Mage_Catalog_Model_Product_Option */
+        $option = $this->_prepareOption($optionId, $store);
+        $productOptionValues = $option->getValuesCollection();
+        $result = array();
+        foreach($productOptionValues as $value){
+            $result[] = array(
+                'value_id' => $value->getId(),
+                'title' => $value->getTitle(),
+                'price' => $value->getPrice(),
+                'price_type' => $value->getPriceType(),
+                'sku' => $value->getSku(),
+                'sort_order' => $value->getSortOrder()
+            );
+        }
+        return $result;
+    }
+
+    /**
+     * Retrieve specified option value info
+     *
+     * @param string $valueId
+     * @param int|string|null $store
+     * @return array
+     */
+    public function info($valueId, $store = null)
+    {
+        /** @var $productOptionValue Mage_Catalog_Model_Product_Option_Value */
+        $productOptionValue = Mage::getModel('Mage_Catalog_Model_Product_Option_Value')->load($valueId);
+        if (!$productOptionValue->getId()) {
+            $this->_fault('value_not_exists');
+        }
+        $storeId = $this->_getStoreId($store);
+        $productOptionValues = $productOptionValue
+                ->getValuesByOption(
+                    array($valueId),
+                    $productOptionValue->getOptionId(),
+                    $storeId
+                )
+                ->addTitleToResult($storeId)
+                ->addPriceToResult($storeId);
+
+        $result = $productOptionValues->toArray();
+        // reset can be used as the only item is expected
+        $result = reset($result['items']);
+        if (empty($result)) {
+            $this->_fault('value_not_exists');
+        }
+        // map option_type_id to value_id
+        $result['value_id'] = $result['option_type_id'];
+        unset($result['option_type_id']);
+        return $result;
+    }
+
+    /**
+     * Add new values to select option
+     *
+     * @param string $optionId
+     * @param array $data
+     * @param int|string|null $store
+     * @return bool
+     */
+    public function add($optionId, $data, $store = null)
+    {
+        /** @var $option Mage_Catalog_Model_Product_Option */
+        $option = $this->_prepareOption($optionId, $store);
+        /** @var $optionValueModel Mage_Catalog_Model_Product_Option_Value */
+        $optionValueModel = Mage::getModel('Mage_Catalog_Model_Product_Option_Value');
+        $optionValueModel->setOption($option);
+        foreach ($data as &$optionValue) {
+            foreach ($optionValue as &$value) {
+                $value = Mage::helper('Mage_Catalog_Helper_Data')->stripTags($value);
+            }
+        }
+        $optionValueModel->setValues($data);
+        try {
+            $optionValueModel->saveValues();
+        } catch (Exception $e) {
+            $this->_fault('add_option_value_error', $e->getMessage());
+        }
+        return true;
+    }
+
+    /**
+     * Update value to select option
+     *
+     * @param string $valueId
+     * @param array $data
+     * @param int|string|null $store
+     * @return bool
+     */
+    public function update($valueId, $data, $store = null)
+    {
+        /** @var $productOptionValue Mage_Catalog_Model_Product_Option_Value */
+        $productOptionValue = Mage::getModel('Mage_Catalog_Model_Product_Option_Value')->load($valueId);
+        if (!$productOptionValue->getId()) {
+            $this->_fault('value_not_exists');
+        }
+
+        /** @var $option Mage_Catalog_Model_Product_Option */
+        $option = $this->_prepareOption($productOptionValue->getOptionId(), $store);
+        if (!$option->getId()) {
+            $this->_fault('option_not_exists');
+        }
+        $productOptionValue->setOption($option);
+        // Sanitize data
+        foreach ($data as $key => $value) {
+            $data[$key] = Mage::helper('Mage_Catalog_Helper_Data')->stripTags($value);
+        }
+        if (!isset($data['title']) OR empty($data['title'])) {
+            $this->_fault('option_value_title_required');
+        }
+        $data['option_type_id'] = $valueId;
+        $data['store_id'] = $this->_getStoreId($store);
+        $productOptionValue->addValue($data);
+        $productOptionValue->setData($data);
+
+        try {
+            $productOptionValue->save()->saveValues();
+        } catch (Exception $e) {
+            $this->_fault('update_option_value_error', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Delete value from select option
+     *
+     * @param int $valueId
+     * @return boolean
+     */
+    public function remove($valueId)
+    {
+        /** @var $optionValue Mage_Catalog_Model_Product_Option_Value */
+        $optionValue = Mage::getModel('Mage_Catalog_Model_Product_Option_Value')->load($valueId);
+        if (!$optionValue->getId()) {
+            $this->_fault('value_not_exists');
+        }
+
+        // check values count
+        if(count($this->items($optionValue->getOptionId())) <= 1){
+            $this->_fault('cant_delete_last_value');
+        }
+
+        try {
+            $optionValue->delete();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_deleted', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Load option by id and store
+     *
+     * @param string $optionId
+     * @param int|string|null $store
+     * @return Mage_Catalog_Model_Product_Option
+     */
+    protected function _prepareOption($optionId, $store = null)
+    {
+        /** @var $option Mage_Catalog_Model_Product_Option */
+        $option = Mage::getModel('Mage_Catalog_Model_Product_Option');
+        if (is_string($store) || is_integer($store)) {
+            $storeId = $this->_getStoreId($store);
+            $option->setStoreId($storeId);
+        }
+        $option->load($optionId);
+        if (isset($storeId)) {
+            $option->setData('store_id', $storeId);
+        }
+        if (!$option->getId()) {
+            $this->_fault('option_not_exists');
+        }
+        if ($option->getGroupByType() != Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT) {
+            $this->_fault('invalid_option_type');
+        }
+        return $option;
+    }
+
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Option/Value/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Option/Value/Api/V2.php
new file mode 100644
index 00000000000..44bc37a2ce8
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Option/Value/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product option values api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Option_Value_Api_V2 extends Mage_Catalog_Model_Product_Option_Value_Api
+{
+    /**
+     * Retrieve values from specified option
+     *
+     * @param string $optionId
+     * @param int|string|null $store
+     * @return array
+     */
+    public function items($optionId, $store = null)
+    {
+        $result = parent::items($optionId, $store);
+        foreach ($result as $key => $optionValue) {
+            $result[$key] = Mage::helper('Mage_Api_Helper_Data')->wsiArrayPacker($optionValue);
+        }
+        return $result;
+    }
+
+    /**
+     * Retrieve specified option value info
+     *
+     * @param string $valueId
+     * @param int|string|null $store
+     * @return array
+     */
+    public function info($valueId, $store = null)
+    {
+        return Mage::helper('Mage_Api_Helper_Data')->wsiArrayPacker(
+            parent::info($valueId, $store)
+        );
+    }
+
+    /**
+     * Add new values to select option
+     *
+     * @param string $optionId
+     * @param array $data
+     * @param int|string|null $store
+     * @return bool
+     */
+    public function add($optionId, $data, $store = null)
+    {
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::add($optionId, $data, $store);
+    }
+
+    /**
+     * Update value to select option
+     *
+     * @param string $valueId
+     * @param array $data
+     * @param int|string|null $store
+     * @return bool
+     */
+    public function update($valueId, $data, $store = null)
+    {
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::update($valueId, $data, $store);
+    }
+
+    /**
+     * Delete value from select option
+     *
+     * @param int $valueId
+     * @return boolean
+     */
+    public function remove($valueId)
+    {
+        return parent::remove($valueId);
+    }
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Api.php b/app/code/core/Mage/Catalog/Model/Product/Type/Api.php
new file mode 100644
index 00000000000..7413553be01
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Type/Api.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product type api
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Type_Api extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Retrieve product type list
+     *
+     * @return array
+     */
+    public function items()
+    {
+        $result = array();
+
+        foreach (Mage_Catalog_Model_Product_Type::getOptionArray() as $type=>$label) {
+            $result[] = array(
+                'type'  => $type,
+                'label' => $label
+            );
+        }
+
+        return $result;
+    }
+} // Class Mage_Catalog_Model_Product_Type_Api End
diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Api/V2.php b/app/code/core/Mage/Catalog/Model/Product/Type/Api/V2.php
new file mode 100644
index 00000000000..99f91899ccf
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Product/Type/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog product type api V2
+ *
+ * @category   Mage
+ * @package    Mage_Catalog
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Product_Type_Api_V2 extends Mage_Catalog_Model_Product_Type_Api
+{
+}
diff --git a/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php b/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php
index 0f96e0dbb3e..13091964537 100644
--- a/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php
+++ b/app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php
@@ -865,16 +865,6 @@ class Mage_Catalog_Model_Product_Type_Configurable extends Mage_Catalog_Model_Pr
             ->getConfigurableOptions($product, $this->getUsedProductAttributes($product));
     }
 
-    /**
-     * Check that product of this type has weight
-     *
-     * @return bool
-     */
-    public function hasWeight()
-    {
-        return false;
-    }
-
     /**
      * Delete data specific for Configurable product type
      *
diff --git a/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Grouped/AssociatedProductsCollection.php b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Grouped/AssociatedProductsCollection.php
new file mode 100644
index 00000000000..ffd986fc589
--- /dev/null
+++ b/app/code/core/Mage/Catalog/Model/Resource/Product/Type/Grouped/AssociatedProductsCollection.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.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Associated products collection
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Catalog_Model_Resource_Product_Type_Grouped_AssociatedProductsCollection
+    extends Mage_Catalog_Model_Resource_Product_Link_Product_Collection
+{
+
+    /**
+     * Retrieve currently edited product model
+     *
+     * @return Mage_Catalog_Model_Product
+     */
+    protected function _getProduct()
+    {
+        return Mage::registry('current_product');
+    }
+
+    /**
+     * Prepare select for load
+     *
+     * @param Varien_Db_Select $select
+     * @return string
+     */
+    public function _prepareSelect(Varien_Db_Select $select)
+    {
+        $allowProductTypes = array();
+        $allowProductTypeNodes = Mage::getConfig()
+            ->getNode(Mage_Catalog_Model_Config::XML_PATH_GROUPED_ALLOWED_PRODUCT_TYPES)->children();
+        foreach ($allowProductTypeNodes as $type) {
+            $allowProductTypes[] = $type->getName();
+        }
+
+        $this->setProduct($this->_getProduct())
+            ->addAttributeToSelect('*')
+            ->addFilterByRequiredOptions()
+            ->addAttributeToFilter('type_id', $allowProductTypes);
+
+        return parent::_prepareSelect($select);
+    }
+}
diff --git a/app/code/core/Mage/Catalog/etc/api.xml b/app/code/core/Mage/Catalog/etc/api.xml
new file mode 100644
index 00000000000..4034fb87856
--- /dev/null
+++ b/app/code/core/Mage/Catalog/etc/api.xml
@@ -0,0 +1,828 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <catalog_category translate="title" module="Mage_Catalog">
+                <model>Mage_Catalog_Model_Category_Api</model>
+                <title>Category API</title>
+                <acl>catalog/category</acl>
+                <methods>
+                    <currentStore>
+                        <title>Set/Get current store view</title>
+                    </currentStore>
+                    <tree translate="title" module="Mage_Catalog">
+                        <title>Retrieve hierarchical tree</title>
+                        <acl>catalog/category/tree</acl>
+                    </tree>
+                    <level translate="title" module="Mage_Catalog">
+                        <title>Retrieve one level of categories by website/store view/parent category</title>
+                    </level>
+                    <info translate="title" module="Mage_Catalog">
+                        <title>Retrieve category data</title>
+                        <acl>catalog/category/info</acl>
+                    </info>
+                    <create translate="title" module="Mage_Catalog">
+                        <title>Create new category</title>
+                        <acl>catalog/category/create</acl>
+                    </create>
+                    <update translate="title" module="Mage_Catalog">
+                        <title>Update category</title>
+                        <acl>catalog/category/update</acl>
+                    </update>
+                    <move translate="title" module="Mage_Catalog">
+                        <title>Move category in tree</title>
+                        <acl>catalog/category/move</acl>
+                    </move>
+                    <delete translate="title" module="Mage_Catalog">
+                        <title>Delete category</title>
+                        <acl>catalog/category/delete</acl>
+                    </delete>
+                    <assignedProducts translate="title" module="Mage_Catalog">
+                        <title>Retrieve list of assigned products</title>
+                        <acl>catalog/category/product</acl>
+                    </assignedProducts>
+                    <assignProduct translate="title" module="Mage_Catalog">
+                        <title>Assign product to category</title>
+                        <acl>catalog/category/product/assign</acl>
+                    </assignProduct>
+                    <updateProduct translate="title" module="Mage_Catalog">
+                        <title>Update assigned product</title>
+                        <acl>catalog/category/product/update</acl>
+                    </updateProduct>
+                    <removeProduct translate="title" module="Mage_Catalog">
+                        <title>Remove product assignment</title>
+                        <acl>catalog/category/product/remove</acl>
+                    </removeProduct>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <store_not_exists>
+                        <code>100</code>
+                        <message>Requested store view is not found.</message>
+                    </store_not_exists>
+                    <website_not_exists>
+                        <code>101</code>
+                        <message>Requested website is not found.</message>
+                    </website_not_exists>
+                    <not_exists>
+                        <code>102</code>
+                        <message>Category does not exist.</message>
+                    </not_exists>
+                    <data_invalid>
+                        <code>103</code>
+                        <message>Provided data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <not_moved>
+                        <code>104</code>
+                        <message>Category is not moved. Details are in error message.</message>
+                    </not_moved>
+                    <not_deleted>
+                        <code>105</code>
+                        <message>Category is not deleted. Details are in error message.</message>
+                    </not_deleted>
+                    <product_not_assigned>
+                        <code>106</code>
+                        <message>Requested product is not assigned to category.</message>
+                    </product_not_assigned>
+                </faults>
+            </catalog_category>
+            <catalog_category_attribute translate="title" module="Mage_Catalog">
+                <title>Category attributes API</title>
+                <model>Mage_Catalog_Model_Category_Attribute_Api</model>
+                <acl>catalog/category</acl>
+                <methods>
+                    <currentStore translate="title" module="Mage_Catalog">
+                        <title>Set/Get current store view</title>
+                    </currentStore>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve category attributes</title>
+                        <method>items</method>
+                    </list>
+                    <options translate="title" module="Mage_Catalog">
+                        <title>Retrieve attribute options</title>
+                    </options>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <store_not_exists>
+                        <code>100</code>
+                        <message>Requested store view is not found.</message>
+                    </store_not_exists>
+                    <not_exists>
+                        <code>101</code>
+                        <message>Requested attribute is not found.</message>
+                    </not_exists>
+                </faults>
+            </catalog_category_attribute>
+            <catalog_product translate="title" module="Mage_Catalog">
+                <title>Product API</title>
+                <model>Mage_Catalog_Model_Product_Api</model>
+                <acl>catalog/product</acl>
+                <methods>
+                    <currentStore translate="title" module="Mage_Catalog">
+                        <title>Set/Get current store view</title>
+                    </currentStore>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve products list by filters</title>
+                        <method>items</method>
+                        <acl>catalog/product/info</acl>
+                    </list>
+                    <info translate="title" module="Mage_Catalog">
+                        <title>Retrieve product</title>
+                        <acl>catalog/product/info</acl>
+                    </info>
+                    <create translate="title" module="Mage_Catalog">
+                        <title>Create new product</title>
+                        <acl>catalog/product/create</acl>
+                    </create>
+                    <update translate="title" module="Mage_Catalog">
+                        <title>Update product</title>
+                        <acl>catalog/product/update</acl>
+                    </update>
+                    <delete translate="title" module="Mage_Catalog">
+                        <title>Delete product</title>
+                        <acl>catalog/product/delete</acl>
+                    </delete>
+                    <getSpecialPrice translate="title" module="Mage_Catalog">
+                        <title>Get special price</title>
+                    </getSpecialPrice>
+                    <setSpecialPrice translate="title" module="Mage_Catalog">
+                        <title>Set special price</title>
+                        <acl>catalog/product/update</acl>
+                    </setSpecialPrice>
+                    <listOfAdditionalAttributes translate="title" module="Mage_Catalog">
+                        <title>Get list of additional attributes</title>
+                        <method>getAdditionalAttributes</method>
+                        <acl>catalog/product/info</acl>
+                    </listOfAdditionalAttributes>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <store_not_exists>
+                        <code>100</code>
+                        <message>Requested store view is not found.</message>
+                    </store_not_exists>
+                    <product_not_exists>
+                        <code>101</code>
+                        <message>Product does not exist.</message>
+                    </product_not_exists>
+                    <data_invalid>
+                        <code>102</code>
+                        <message>Provided data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <not_deleted>
+                        <code>103</code>
+                        <message>Product is not deleted. Details are in error message.</message>
+                    </not_deleted>
+                    <product_type_not_exists>
+                        <code>104</code>
+                        <message>Product type is not in range of allowed types.</message>
+                    </product_type_not_exists>
+                    <product_attribute_set_not_exists>
+                        <code>105</code>
+                        <message>Product attribute set does not exist.</message>
+                    </product_attribute_set_not_exists>
+                    <product_attribute_set_not_valid>
+                        <code>106</code>
+                        <message>Product attribute set does not belong to catalog product entity type.</message>
+                    </product_attribute_set_not_valid>
+                </faults>
+            </catalog_product>
+            <catalog_product_attribute translate="title" module="Mage_Catalog">
+                <title>Product attributes API</title>
+                <model>Mage_Catalog_Model_Product_Attribute_Api</model>
+                <acl>catalog/product</acl>
+                <methods>
+                    <currentStore translate="title" module="Mage_Catalog">
+                        <title>Set/Get current store view</title>
+                        <acl>catalog/product/attribute/write</acl>
+                    </currentStore>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve attribute list</title>
+                        <method>items</method>
+                        <acl>catalog/product/attribute/read</acl>
+                    </list>
+                    <options translate="title" module="Mage_Catalog">
+                        <title>Retrieve attribute options</title>
+                        <acl>catalog/product/attribute/read</acl>
+                    </options>
+                    <types translate="title" module="Mage_Catalog">
+                        <title>Get list of possible attribute types</title>
+                        <acl>catalog/product/attribute/types</acl>
+                    </types>
+                    <create translate="title" module="Mage_Catalog">
+                        <title>Create new attribute</title>
+                        <acl>catalog/product/attribute/create</acl>
+                    </create>
+                    <update translate="title" module="Mage_Catalog">
+                        <title>Update attribute</title>
+                        <acl>catalog/product/attribute/update</acl>
+                    </update>
+                    <remove translate="title" module="Mage_Catalog">
+                        <title>Delete attribute</title>
+                        <acl>catalog/product/attribute/remove</acl>
+                    </remove>
+                    <info translate="title" module="Mage_Catalog">
+                        <title>Get full information about attribute with list of options</title>
+                        <acl>catalog/product/attribute/info</acl>
+                    </info>
+                    <addOption translate="title" module="Mage_Catalog">
+                        <title>Add option</title>
+                        <acl>catalog/product/attribute/option/add</acl>
+                    </addOption>
+                    <removeOption translate="title" module="Mage_Catalog">
+                        <title>Remove option</title>
+                        <acl>catalog/product/attribute/option/remove</acl>
+                    </removeOption>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <store_not_exists>
+                        <code>100</code>
+                        <message>Requested store view is not found.</message>
+                    </store_not_exists>
+                    <not_exists>
+                        <code>101</code>
+                        <message>Requested attribute is not found.</message>
+                    </not_exists>
+                    <invalid_parameters>
+                       <code>102</code>
+                       <message>Provided request parameters are invalid.</message>
+                   </invalid_parameters>
+                   <invalid_code>
+                       <code>103</code>
+                       <message>Attribute code is invalid. Please use only letters (a-z), numbers (0-9), or underscore(_) in this field. First character should be a letter.</message>
+                   </invalid_code>
+                   <invalid_frontend_input>
+                       <code>104</code>
+                       <message>Attribute type is invalid.</message>
+                   </invalid_frontend_input>
+                   <unable_to_save>
+                       <code>105</code>
+                       <message>Unable to save attribute.</message>
+                   </unable_to_save>
+                   <can_not_delete>
+                       <code>106</code>
+                       <message>This attribute cannot be deleted.</message>
+                   </can_not_delete>
+                   <can_not_edit>
+                       <code>107</code>
+                       <message>This attribute cannot be edited.</message>
+                   </can_not_edit>
+                   <unable_to_add_option>
+                       <code>108</code>
+                       <message>Unable to add option.</message>
+                   </unable_to_add_option>
+                   <unable_to_remove_option>
+                       <code>109</code>
+                       <message>Unable to remove option.</message>
+                   </unable_to_remove_option>
+                </faults>
+            </catalog_product_attribute>
+            <catalog_product_attribute_set translate="title" module="Mage_Catalog">
+                <title>Product attribute sets API</title>
+                <model>Mage_Catalog_Model_Product_Attribute_Set_Api</model>
+                <acl>catalog/product/attribute/set</acl>
+                <methods>
+                    <create translate="title" module="Mage_Catalog">
+                        <title>Create attribute set based on another set</title>
+                        <acl>catalog/product/attribute/set/create</acl>
+                    </create>
+                    <remove translate="title" module="Mage_Catalog">
+                        <title>Remove attribute set</title>
+                        <acl>catalog/product/attribute/set/remove</acl>
+                    </remove>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve product attribute sets</title>
+                        <method>items</method>
+                        <acl>catalog/product/attribute/set/list</acl>
+                    </list>
+                    <attributeAdd translate="title" module="Mage_Catalog">
+                        <title>Add attribute into attribute set</title>
+                        <acl>catalog/product/attribute/set/attribute_add</acl>
+                    </attributeAdd>
+                    <attributeRemove translate="title" module="Mage_Catalog">
+                        <title>Remove attribute from attribute set</title>
+                        <acl>catalog/product/attribute/set/attribute_remove</acl>
+                    </attributeRemove>
+                    <groupAdd translate="title" module="Mage_Catalog">
+                        <title>Add group into attribute set</title>
+                        <acl>catalog/product/attribute/set/group_add</acl>
+                    </groupAdd>
+                    <groupRename translate="title" module="Mage_Catalog">
+                        <title>Rename existing group</title>
+                        <acl>catalog/product/attribute/set/group_rename</acl>
+                    </groupRename>
+                    <groupRemove translate="title" module="Mage_Catalog">
+                        <title>Remove group from attribute set</title>
+                        <acl>catalog/product/attribute/set/group_remove</acl>
+                    </groupRemove>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <invalid_skeleton_set_id>
+                        <code>100</code>
+                        <message>Attribute set with requested ID does not exist.</message>
+                    </invalid_skeleton_set_id>
+                    <invalid_data>
+                        <code>101</code>
+                        <message>Provided data is invalid.</message>
+                    </invalid_data>
+                    <create_attribute_set_error>
+                        <code>102</code>
+                        <message>Error occurred while creating attribute set. Details are in error message.</message>
+                    </create_attribute_set_error>
+                    <remove_attribute_set_error>
+                        <code>103</code>
+                        <message>Error occurred while removing attribute set. Details are in error message.</message>
+                    </remove_attribute_set_error>
+                    <invalid_attribute_set_id>
+                        <code>104</code>
+                        <message>Attribute set with requested ID does not exist.</message>
+                    </invalid_attribute_set_id>
+                    <attribute_set_has_related_products>
+                        <code>105</code>
+                        <message>Unable to remove attribute set as it has related items. Use forceProductsRemove parameter to remove attribute set with all items.</message>
+                    </attribute_set_has_related_products>
+                    <invalid_attribute_id>
+                        <code>106</code>
+                        <message>Attribute with requested ID does not exist.</message>
+                    </invalid_attribute_id>
+                    <add_attribute_error>
+                        <code>107</code>
+                        <message>Error occurred while adding attribute to attribute set. Details are in error message.</message>
+                    </add_attribute_error>
+                    <invalid_attribute_group_id>
+                        <code>108</code>
+                        <message>Attribute group with requested ID does not exist.</message>
+                    </invalid_attribute_group_id>
+                    <attribute_is_already_in_set>
+                        <code>109</code>
+                        <message>Requested attribute is already in requested attribute set.</message>
+                    </attribute_is_already_in_set>
+                    <remove_attribute_error>
+                        <code>110</code>
+                        <message>Error occurred while removing attribute from attribute set. Details are in error message.</message>
+                    </remove_attribute_error>
+                    <attribute_is_not_in_set>
+                        <code>111</code>
+                        <message>Requested attribute is not in requested attribute set.</message>
+                    </attribute_is_not_in_set>
+                    <group_already_exists>
+                        <code>112</code>
+                        <message>Requested group is already in requested attribute set.</message>
+                    </group_already_exists>
+                    <group_add_error>
+                        <code>113</code>
+                        <message>Error occurred while adding group to attribute set. Details are in error message.</message>
+                    </group_add_error>
+                    <group_rename_error>
+                        <code>114</code>
+                        <message>Error occurred while renaming group. Details are in error message.</message>
+                    </group_rename_error>
+                    <group_remove_error>
+                        <code>115</code>
+                        <message>Error occurred while removing group from attribute set. Details are in error message.</message>
+                    </group_remove_error>
+                    <group_has_system_attributes>
+                        <code>116</code>
+                        <message>Group cannot be removed as it contains system attributes.</message>
+                    </group_has_system_attributes>
+                    <group_has_configurable_attributes>
+                        <code>117</code>
+                        <message>Group cannot be removed as it contains attributes used in configurable products.</message>
+                    </group_has_configurable_attributes>
+                </faults>
+            </catalog_product_attribute_set>
+            <catalog_product_type translate="title" module="Mage_Catalog">
+                <title>Product types API</title>
+                <model>Mage_Catalog_Model_Product_Type_Api</model>
+                <acl>catalog/product</acl>
+                <methods>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve product types</title>
+                        <method>items</method>
+                    </list>
+                </methods>
+                <faults module="Mage_Catalog">
+                </faults>
+            </catalog_product_type>
+            <catalog_product_attribute_media translate="title" module="Mage_Catalog">
+                <title>Product Images API</title>
+                <model>Mage_Catalog_Model_Product_Attribute_Media_Api</model>
+                <acl>catalog/product/media</acl>
+                <methods>
+                    <currentStore translate="title" module="Mage_Catalog">
+                        <title>Set/Get current store view</title>
+                    </currentStore>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve product image list</title>
+                        <method>items</method>
+                    </list>
+                    <info translate="title" module="Mage_Catalog">
+                        <title>Retrieve product image</title>
+                    </info>
+                    <types translate="title" module="Mage_Catalog">
+                        <title>Retrieve product image types</title>
+                    </types>
+                    <create translate="title" module="Mage_Catalog">
+                        <title>Upload new product image </title>
+                        <acl>catalog/product/media/create</acl>
+                    </create>
+                    <update translate="title" module="Mage_Catalog">
+                        <title>Update product image</title>
+                        <acl>catalog/product/media/update</acl>
+                    </update>
+                    <remove translate="title" module="Mage_Catalog">
+                        <title>Remove product image</title>
+                        <acl>catalog/product/media/remove</acl>
+                    </remove>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <store_not_exists>
+                        <code>100</code>
+                        <message>Requested store view is not found.</message>
+                    </store_not_exists>
+                    <product_not_exists>
+                        <code>101</code>
+                        <message>Product does not exist.</message>
+                    </product_not_exists>
+                    <data_invalid>
+                        <code>102</code>
+                        <message>Provided data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <not_exists>
+                        <code>103</code>
+                        <message>Requested image does not exist in product images' gallery.</message>
+                    </not_exists>
+                    <not_created>
+                        <code>104</code>
+                        <message>Image creation failed. Details are in error message.</message>
+                    </not_created>
+                    <not_updated>
+                        <code>105</code>
+                        <message>Image is not updated. Details are in error message.</message>
+                    </not_updated>
+                    <not_removed>
+                        <code>106</code>
+                        <message>Image is not removed. Details are in error message.</message>
+                    </not_removed>
+                    <not_media>
+                        <code>107</code>
+                        <message>Requested product doesn't support images.</message>
+                    </not_media>
+                </faults>
+            </catalog_product_attribute_media>
+            <catalog_product_attribute_tier_price translate="title" module="Mage_Catalog">
+                <title>Product Tier Price API</title>
+                <model>Mage_Catalog_Model_Product_Attribute_Tierprice_Api</model>
+                <acl>catalog/product</acl>
+                <methods>
+                    <info translate="title" module="Mage_Catalog">
+                        <title>Retrieve product tier prices</title>
+                    </info>
+                    <update translate="title" module="Mage_Catalog">
+                        <title>Update product tier prices</title>
+                        <acl>catalog/product/update_tier_price</acl>
+                    </update>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <product_not_exists>
+                        <code>100</code>
+                        <message>Product does not exist.</message>
+                    </product_not_exists>
+                    <data_invalid>
+                        <code>101</code>
+                        <message>Provided data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <not_updated>
+                        <code>102</code>
+                        <message>Tier prices are not updated. Details are in error message.</message>
+                    </not_updated>
+                </faults>
+            </catalog_product_attribute_tier_price>
+            <catalog_product_link translate="title" module="Mage_Catalog">
+                <title>Product links API (related, cross sells, up sells)</title>
+                <model>Mage_Catalog_Model_Product_Link_Api</model>
+                <acl>catalog/product/link</acl>
+                <methods>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve linked products</title>
+                        <method>items</method>
+                    </list>
+                    <assign translate="title" module="Mage_Catalog">
+                        <title>Assign product link</title>
+                        <acl>catalog/product/link/assign</acl>
+                    </assign>
+                    <update translate="title" module="Mage_Catalog">
+                        <title>Update product link</title>
+                        <acl>catalog/product/link/update</acl>
+                    </update>
+                    <remove translate="title" module="Mage_Catalog">
+                        <title>Remove product link</title>
+                        <acl>catalog/product/link/remove</acl>
+                    </remove>
+                    <types translate="title" module="Mage_Catalog">
+                        <title>Retrieve product link types</title>
+                    </types>
+                    <attributes translate="title" module="Mage_Catalog">
+                        <title>Retrieve product link type attributes</title>
+                    </attributes>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <type_not_exists>
+                        <code>100</code>
+                        <message>Provided link type is invalid.</message>
+                    </type_not_exists>
+                    <product_not_exists>
+                        <code>101</code>
+                        <message>Product does not exist.</message>
+                    </product_not_exists>
+                    <data_invalid>
+                        <code>102</code>
+                        <message>Provided data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <not_removed>
+                        <code>104</code>
+                        <message>Product link is not removed.</message>
+                    </not_removed>
+                </faults>
+            </catalog_product_link>
+            <catalog_product_custom_option translate="title" module="Mage_Catalog">
+                <title>Catalog product custom options API</title>
+                <model>Mage_Catalog_Model_Product_Option_Api</model>
+                <acl>catalog/product/option</acl>
+                <methods>
+                    <add translate="title" module="Mage_Catalog">
+                        <title>Add new custom option into product</title>
+                        <acl>catalog/product/option/add</acl>
+                    </add>
+                    <update translate="title" module="Mage_Catalog">
+                        <title>Update custom option of product</title>
+                        <acl>catalog/product/option/update</acl>
+                    </update>
+                    <types translate="title" module="Mage_Catalog">
+                        <title>Get list of available custom option types</title>
+                        <acl>catalog/product/option/types</acl>
+                    </types>
+                    <info translate="title" module="Mage_Catalog">
+                        <title>Get full information about custom option in product</title>
+                        <acl>catalog/product/option/info</acl>
+                    </info>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve list of product custom options</title>
+                        <acl>catalog/product/option/list</acl>
+                        <method>items</method>
+                    </list>
+                    <remove translate="title" module="Mage_Catalog">
+                        <title>Remove custom option</title>
+                        <acl>catalog/product/option/remove</acl>
+                    </remove>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <product_not_exists>
+                        <code>101</code>
+                        <message>Product with requested ID does not exist.</message>
+                    </product_not_exists>
+                    <invalid_data>
+                        <code>102</code>
+                        <message>Provided data is invalid.</message>
+                    </invalid_data>
+                    <save_option_error>
+                        <code>103</code>
+                        <message>Error occurred while saving an option. Details are in error message.</message>
+                    </save_option_error>
+                    <store_not_exists>
+                        <code>104</code>
+                        <message>Store with requested code or ID does not exist.</message>
+                    </store_not_exists>
+                    <option_not_exists>
+                        <code>105</code>
+                        <message>Option with requested ID does not exist.</message>
+                    </option_not_exists>
+                    <invalid_type>
+                        <code>106</code>
+                        <message>Provided option type is invalid. Call 'types' to get list of allowed option types.</message>
+                    </invalid_type>
+                    <delete_option_error>
+                        <code>107</code>
+                        <message>Error occurred while deleting an option. Details are in error message.</message>
+                    </delete_option_error>
+                </faults>
+            </catalog_product_custom_option>
+            <catalog_product_custom_option_value translate="title" module="Mage_Catalog">
+                <title>Catalog product custom option values API</title>
+                <model>Mage_Catalog_Model_Product_Option_Value_Api</model>
+                <acl>catalog/product/option/value</acl>
+                <methods>
+                    <list translate="title" module="Mage_Catalog">
+                        <title>Retrieve list of option values</title>
+                        <method>items</method>
+                        <acl>catalog/product/option/value/list</acl>
+                    </list>
+                    <info translate="title" module="Mage_Catalog">
+                        <title>Retrieve option value info</title>
+                        <acl>catalog/product/option/value/info</acl>
+                    </info>
+                    <add translate="title" module="Mage_Catalog">
+                        <title>Add new values into custom option</title>
+                        <acl>catalog/product/option/value/add</acl>
+                    </add>
+                    <update translate="title" module="Mage_Catalog">
+                        <title>Update value of custom option</title>
+                        <acl>catalog/product/option/value/update</acl>
+                    </update>
+                    <remove translate="title" module="Mage_Catalog">
+                        <title>Remove value from custom option</title>
+                        <acl>catalog/product/option/value/remove</acl>
+                    </remove>
+                </methods>
+                <faults module="Mage_Catalog">
+                    <value_not_exists>
+                        <code>101</code>
+                        <message>Option value with requested ID does not exist.</message>
+                    </value_not_exists>
+                    <add_option_value_error>
+                        <code>102</code>
+                        <message>Error occurred while adding an option value. Details are in error message.</message>
+                    </add_option_value_error>
+                    <option_not_exists>
+                        <code>103</code>
+                        <message>Option with requested ID does not exist.</message>
+                    </option_not_exists>
+                    <invalid_option_type>
+                        <code>104</code>
+                        <message>Provided option type is invalid.</message>
+                    </invalid_option_type>
+                    <store_not_exists>
+                        <code>105</code>
+                        <message>Store with requested code or ID does not exist.</message>
+                    </store_not_exists>
+                    <can_not_delete>
+                        <code>106</code>
+                        <message>Cannot delete option.</message>
+                    </can_not_delete>
+                    <update_option_value_error>
+                        <code>107</code>
+                        <message>Error occurred while updating an option value. Details are in error message.</message>
+                    </update_option_value_error>
+                    <option_value_title_required>
+                        <code>108</code>
+                        <message>Title field is required.</message>
+                    </option_value_title_required>
+                    <cant_delete_last_value>
+                        <code>109</code>
+                        <message>Option should have at least one value. Cannot delete last value.</message>
+                    </cant_delete_last_value>
+                </faults>
+            </catalog_product_custom_option_value>
+        </resources>
+        <resources_alias>
+            <category>catalog_category</category>
+            <category_attribute>catalog_category_attribute</category_attribute>
+            <product>catalog_product</product>
+            <product_attribute>catalog_product_attribute</product_attribute>
+            <product_attribute_set>catalog_product_attribute_set</product_attribute_set>
+            <product_type>catalog_product_type</product_type>
+            <product_link>catalog_product_link</product_link>
+            <product_attribute_media>catalog_product_attribute_media</product_attribute_media>
+            <product_media>catalog_product_attribute_media</product_media>
+            <product_attribute_tier_price>catalog_product_attribute_tier_price</product_attribute_tier_price>
+            <product_tier_price>catalog_product_attribute_tier_price</product_tier_price>
+            <product_custom_option>catalog_product_custom_option</product_custom_option>
+            <product_custom_option_value>catalog_product_custom_option_value</product_custom_option_value>
+        </resources_alias>
+        <v2>
+            <resources_function_prefix>
+                <category>catalogCategory</category>
+                <category_attribute>catalogCategoryAttribute</category_attribute>
+                <product>catalogProduct</product>
+                <product_attribute>catalogProductAttribute</product_attribute>
+                <product_attribute_set>catalogProductAttributeSet</product_attribute_set>
+                <product_type>catalogProductType</product_type>
+                <product_tier_price>catalogProductAttributeTierPrice</product_tier_price>
+                <product_attribute_media>catalogProductAttributeMedia</product_attribute_media>
+                <product_link>catalogProductLink</product_link>
+                <product_custom_option>catalogProductCustomOption</product_custom_option>
+                <product_custom_option_value>catalogProductCustomOptionValue</product_custom_option_value>
+            </resources_function_prefix>
+        </v2>
+        <acl>
+            <resources>
+                <catalog translate="title" module="Mage_Catalog">
+                    <title>Catalog</title>
+                    <sort_order>1</sort_order>
+                    <category translate="title" module="Mage_Catalog">
+                        <title>Category</title>
+                        <create translate="title" module="Mage_Catalog">
+                            <title>Create</title>
+                        </create>
+                        <update translate="title" module="Mage_Catalog">
+                            <title>Update</title>
+                        </update>
+                        <move translate="title" module="Mage_Catalog">
+                            <title>Move</title>
+                        </move>
+                        <delete translate="title" module="Mage_Catalog">
+                            <title>Delete</title>
+                        </delete>
+                        <tree translate="title" module="Mage_Catalog">
+                            <title>Retrieve categories tree</title>
+                        </tree>
+                        <info translate="title" module="Mage_Catalog">
+                            <title>Retrieve category data</title>
+                        </info>
+                        <product translate="title" module="Mage_Catalog">
+                            <title>Assigned Products</title>
+                            <sort_order>100</sort_order>
+                            <assign translate="title" module="Mage_Catalog">
+                                <title>Assign</title>
+                            </assign>
+                            <update translate="title" module="Mage_Catalog">
+                                <title>Update</title>
+                            </update>
+                            <remove translate="title" module="Mage_Catalog">
+                                <title>Remove</title>
+                            </remove>
+                        </product>
+                    </category>
+                    <product translate="title" module="Mage_Catalog">
+                        <title>Product</title>
+                        <create translate="title" module="Mage_Catalog">
+                            <title>Create</title>
+                        </create>
+                        <update translate="title" module="Mage_Catalog">
+                            <title>Update</title>
+                        </update>
+                        <delete translate="title" module="Mage_Catalog">
+                            <title>Delete</title>
+                        </delete>
+                        <update_tier_price translate="title" module="Mage_Catalog">
+                            <title>Update Tier Price</title>
+                        </update_tier_price>
+                        <info translate="title" module="Mage_Catalog">
+                            <title>Retrieve products data</title>
+                        </info>
+                        <attribute translate="title" module="Mage_Catalog">
+                            <title>Product Attributes</title>
+                            <sort_order>100</sort_order>
+                            <read translate="title" module="Mage_Catalog">
+                                <title>Retrieve attribute data</title>
+                            </read>
+                            <write translate="title" module="Mage_Catalog">
+                                <title>Change or Retrieve attribute store view</title>
+                            </write>
+                        </attribute>
+                        <link translate="title" module="Mage_Catalog">
+                            <title>Link (Related, Up sell, Cross sell)</title>
+                            <sort_order>101</sort_order>
+                            <assign translate="title" module="Mage_Catalog">
+                                <title>Assign</title>
+                            </assign>
+                            <update translate="title" module="Mage_Catalog">
+                                <title>Update</title>
+                            </update>
+                            <remove translate="title" module="Mage_Catalog">
+                                <title>Remove</title>
+                            </remove>
+                        </link>
+                        <media translate="title" module="Mage_Catalog">
+                            <title>Product Images</title>
+                            <sort_order>102</sort_order>
+                            <create translate="title" module="Mage_Catalog">
+                                <title>Create (Upload)</title>
+                            </create>
+                            <update translate="title" module="Mage_Catalog">
+                                <title>Update</title>
+                            </update>
+                            <remove translate="title" module="Mage_Catalog">
+                                <title>Remove</title>
+                            </remove>
+                        </media>
+                    </product>
+                </catalog>
+            </resources>
+        </acl>
+    </api>
+</config>
diff --git a/app/code/core/Mage/Catalog/etc/wsdl.xml b/app/code/core/Mage/Catalog/etc/wsdl.xml
new file mode 100644
index 00000000000..d0bd149e308
--- /dev/null
+++ b/app/code/core/Mage/Catalog/etc/wsdl.xml
@@ -0,0 +1,2326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             xmlns="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/"
+                    schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"/>
+            <complexType name="catalogProductEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductAdditionalAttributesEntity">
+                <all>
+                    <element name="multi_data" type="typens:associativeMultiArray" minOccurs="0" />
+                    <element name="single_data" type="typens:associativeArray" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductConfigurableAttributesEntity">
+                <all>
+                    <element name="attribute_code" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="frontend_label" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="frontend_label_use_default" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <element name="position" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <element name="prices" type="typens:catalogProductConfigurableOptionPricesEntityArray" minOccurs="0" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductConfigurableAttributesEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductConfigurableAttributesEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductConfigurableOptionPricesEntity">
+                <all>
+                    <element name="option_value" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="use_default_value" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductConfigurableOptionPricesEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductConfigurableOptionPricesEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductEntity">
+                <all>
+                    <element name="product_id" type="xsd:string"/>
+                    <element name="sku" type="xsd:string"/>
+                    <element name="name" type="xsd:string"/>
+                    <element name="set" type="xsd:string"/>
+                    <element name="type" type="xsd:string"/>
+                    <element name="category_ids" type="typens:ArrayOfString"/>
+                    <element name="website_ids" type="typens:ArrayOfString"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductRequestAttributes">
+                <all>
+                    <element name="attributes" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="additional_attributes" type="typens:ArrayOfString" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductReturnEntity">
+                <all>
+                    <element name="product_id" type="xsd:string" minOccurs="0"/>
+                    <element name="sku" type="xsd:string" minOccurs="0"/>
+                    <element name="set" type="xsd:string" minOccurs="0"/>
+                    <element name="type" type="xsd:string" minOccurs="0"/>
+                    <element name="categories" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="websites" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <element name="type_id" type="xsd:string" minOccurs="0"/>
+                    <element name="name" type="xsd:string" minOccurs="0"/>
+                    <element name="description" type="xsd:string" minOccurs="0"/>
+                    <element name="short_description" type="xsd:string" minOccurs="0"/>
+                    <element name="weight" type="xsd:string" minOccurs="0"/>
+                    <element name="status" type="xsd:string" minOccurs="0"/>
+                    <element name="url_key" type="xsd:string" minOccurs="0"/>
+                    <element name="url_path" type="xsd:string" minOccurs="0"/>
+                    <element name="visibility" type="xsd:string" minOccurs="0"/>
+                    <element name="category_ids" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="website_ids" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="has_options" type="xsd:string" minOccurs="0"/>
+                    <element name="gift_message_available" type="xsd:string" minOccurs="0"/>
+                    <element name="price" type="xsd:string" minOccurs="0"/>
+                    <element name="special_price" type="xsd:string" minOccurs="0"/>
+                    <element name="special_from_date" type="xsd:string" minOccurs="0"/>
+                    <element name="special_to_date" type="xsd:string" minOccurs="0"/>
+                    <element name="tax_class_id" type="xsd:string" minOccurs="0"/>
+                    <element name="tier_price" type="typens:catalogProductTierPriceEntityArray" minOccurs="0"/>
+                    <element name="meta_title" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_keyword" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_description" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_design" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_layout_update" type="xsd:string" minOccurs="0"/>
+                    <element name="options_container" type="xsd:string" minOccurs="0"/>
+                    <element name="additional_attributes" type="typens:associativeArray" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductCreateEntity">
+                <all>
+                    <element name="categories" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="websites" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="name" type="xsd:string" minOccurs="0"/>
+                    <element name="description" type="xsd:string" minOccurs="0"/>
+                    <element name="short_description" type="xsd:string" minOccurs="0"/>
+                    <element name="weight" type="xsd:string" minOccurs="0"/>
+                    <element name="status" type="xsd:string" minOccurs="0"/>
+                    <element name="url_key" type="xsd:string" minOccurs="0"/>
+                    <element name="url_path" type="xsd:string" minOccurs="0"/>
+                    <element name="visibility" type="xsd:string" minOccurs="0"/>
+                    <element name="category_ids" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="website_ids" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="has_options" type="xsd:string" minOccurs="0"/>
+                    <element name="gift_message_available" type="xsd:string" minOccurs="0"/>
+                    <element name="price" type="xsd:string" minOccurs="0"/>
+                    <element name="special_price" type="xsd:string" minOccurs="0"/>
+                    <element name="special_from_date" type="xsd:string" minOccurs="0"/>
+                    <element name="special_to_date" type="xsd:string" minOccurs="0"/>
+                    <element name="tax_class_id" type="xsd:string" minOccurs="0"/>
+                    <element name="tier_price" type="typens:catalogProductTierPriceEntityArray" minOccurs="0"/>
+                    <element name="meta_title" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_keyword" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_description" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_design" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_layout_update" type="xsd:string" minOccurs="0"/>
+                    <element name="options_container" type="xsd:string" minOccurs="0"/>
+                    <element name="additional_attributes" type="typens:catalogProductAdditionalAttributesEntity" minOccurs="0"/>
+                    <element name="configurable_attributes" type="typens:catalogProductConfigurableAttributesEntityArray" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeSetEntity">
+                <all>
+                    <element name="set_id" type="xsd:int" minOccurs="0"/>
+                    <element name="name" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeSetEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductAttributeSetEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductTypeEntity">
+                <all>
+                    <element name="type" type="xsd:string" minOccurs="0"/>
+                    <element name="label" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductTypeEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductTypeEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductTierPriceEntity">
+                <all>
+                    <element name="customer_group_id" type="xsd:string" minOccurs="0"/>
+                    <element name="website" type="xsd:string" minOccurs="0"/>
+                    <element name="qty" type="xsd:int" minOccurs="0"/>
+                    <element name="price" type="xsd:double" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductTierPriceEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductTierPriceEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="ArrayOfCatalogCategoryEntities">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogCategoryEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogCategoryEntity">
+                <all>
+                    <element name="category_id" type="xsd:int"/>
+                    <element name="parent_id" type="xsd:int"/>
+                    <element name="name" type="xsd:string"/>
+                    <element name="is_active" type="xsd:int"/>
+                    <element name="position" type="xsd:int"/>
+                    <element name="level" type="xsd:int"/>
+                    <element name="children" type="typens:ArrayOfCatalogCategoryEntities"/>
+                </all>
+            </complexType>
+            <complexType name="catalogCategoryEntityNoChildren">
+                <all>
+                    <element name="category_id" type="xsd:int"/>
+                    <element name="parent_id" type="xsd:int"/>
+                    <element name="name" type="xsd:string"/>
+                    <element name="is_active" type="xsd:int"/>
+                    <element name="position" type="xsd:int"/>
+                    <element name="level" type="xsd:int"/>
+                </all>
+            </complexType>
+            <complexType name="ArrayOfCatalogCategoryEntitiesNoChildren">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogCategoryEntityNoChildren[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogCategoryTree">
+                <all>
+                    <element name="category_id" type="xsd:int"/>
+                    <element name="parent_id" type="xsd:int"/>
+                    <element name="name" type="xsd:string"/>
+                    <element name="position" type="xsd:int"/>
+                    <element name="level" type="xsd:int"/>
+                    <element name="children" type="typens:ArrayOfCatalogCategoryEntities"/>
+                </all>
+            </complexType>
+            <complexType name="catalogCategoryEntityCreate">
+                <all>
+                    <element name="name" type="xsd:string" minOccurs="0"/>
+                    <element name="is_active" type="xsd:int" minOccurs="0"/>
+                    <element name="position" type="xsd:int" minOccurs="0"/>
+                    <!-- position parameter is deprecated, category anyway will be positioned in the end of list
+                        and you can not set position directly, use catalog_category.move instead -->
+                    <element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="custom_design" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_design_apply" type="xsd:int" minOccurs="0"/>
+                    <element name="custom_design_from" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_design_to" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_layout_update" type="xsd:string" minOccurs="0"/>
+                    <element name="default_sort_by" type="xsd:string" minOccurs="0"/>
+                    <element name="description" type="xsd:string" minOccurs="0"/>
+                    <element name="display_mode" type="xsd:string" minOccurs="0"/>
+                    <element name="is_anchor" type="xsd:int" minOccurs="0"/>
+                    <element name="landing_page" type="xsd:int" minOccurs="0"/>
+                    <element name="meta_description" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_keywords" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_title" type="xsd:string" minOccurs="0"/>
+                    <element name="page_layout" type="xsd:string" minOccurs="0"/>
+                    <element name="url_key" type="xsd:string" minOccurs="0"/>
+                    <element name="include_in_menu" type="xsd:int" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogCategoryInfo">
+                <all>
+                    <element name="category_id" type="xsd:string"/>
+                    <element name="is_active" type="xsd:int"/>
+                    <element name="position" type="xsd:string"/>
+                    <element name="level" type="xsd:string"/>
+                    <element name="parent_id" type="xsd:string"/>
+                    <element name="all_children" type="xsd:string"/>
+                    <element name="children" type="xsd:string"/>
+                    <element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <element name="name" type="xsd:string" minOccurs="0"/>
+                    <element name="url_key" type="xsd:string" minOccurs="0"/>
+                    <element name="description" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_title" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_keywords" type="xsd:string" minOccurs="0"/>
+                    <element name="meta_description" type="xsd:string" minOccurs="0"/>
+                    <element name="path" type="xsd:string" minOccurs="0"/>
+                    <element name="url_path" type="xsd:string" minOccurs="0"/>
+                    <element name="children_count" type="xsd:int" minOccurs="0"/>
+                    <element name="display_mode" type="xsd:string" minOccurs="0"/>
+                    <element name="is_anchor" type="xsd:int" minOccurs="0"/>
+                    <element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="custom_design" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_design_apply" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_design_from" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_design_to" type="xsd:string" minOccurs="0"/>
+                    <element name="page_layout" type="xsd:string" minOccurs="0"/>
+                    <element name="custom_layout_update" type="xsd:string" minOccurs="0"/>
+                    <element name="default_sort_by" type="xsd:string" minOccurs="0"/>
+                    <element name="landing_page" type="xsd:int" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogAssignedProduct">
+                <all>
+                    <element name="product_id" type="xsd:int"/>
+                    <element name="type" type="xsd:string"/>
+                    <element name="set" type="xsd:int"/>
+                    <element name="sku" type="xsd:string"/>
+                    <element name="position" type="xsd:int"/>
+                </all>
+            </complexType>
+            <complexType name="catalogAssignedProductArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogAssignedProduct[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogAttributeEntity">
+                <all>
+                    <element name="attribute_id" type="xsd:int" minOccurs="0"/>
+                    <element name="code" type="xsd:string" minOccurs="0"/>
+                    <element name="type" type="xsd:string" minOccurs="0"/>
+                    <element name="required" type="xsd:string" minOccurs="0"/>
+                    <element name="scope" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogAttributeEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogAttributeEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogAttributeOptionEntity">
+                <all>
+                    <element name="label" type="xsd:string"/>
+                    <element name="value" type="xsd:string"/>
+                </all>
+            </complexType>
+            <complexType name="catalogAttributeOptionEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogAttributeOptionEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductImageEntity">
+                <all>
+                    <element name="file" type="xsd:string"/>
+                    <element name="label" type="xsd:string"/>
+                    <element name="position" type="xsd:string"/>
+                    <element name="exclude" type="xsd:string"/>
+                    <element name="url" type="xsd:string"/>
+                    <element name="types" type="typens:ArrayOfString"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductImageEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductImageEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductAttributeMediaTypeEntity">
+                <all>
+                    <element name="code" type="xsd:string"/>
+                    <element name="scope" type="xsd:string"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeMediaTypeEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType"
+                                   wsdl:arrayType="typens:catalogProductAttributeMediaTypeEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductImageFileEntity">
+                <all>
+                    <element name="content" type="xsd:string"/>
+                    <element name="mime" type="xsd:string"/>
+                    <element name="name" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeMediaCreateEntity">
+                <all>
+                    <element name="file" type="typens:catalogProductImageFileEntity" minOccurs="0"/>
+                    <element name="label" type="xsd:string" minOccurs="0"/>
+                    <element name="position" type="xsd:string" minOccurs="0"/>
+                    <element name="types" type="typens:ArrayOfString" minOccurs="0"/>
+                    <element name="exclude" type="xsd:string" minOccurs="0"/>
+                    <element name="remove" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductLinkEntity">
+                <all>
+                    <element name="product_id" type="xsd:string" minOccurs="0"/>
+                    <element name="type" type="xsd:string" minOccurs="0"/>
+                    <element name="set" type="xsd:string" minOccurs="0"/>
+                    <element name="sku" type="xsd:string" minOccurs="0"/>
+                    <element name="position" type="xsd:string" minOccurs="0"/>
+                    <element name="qty" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductLinkEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductLinkEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductLinkAttributeEntity">
+                <all>
+                    <element name="code" type="xsd:string" minOccurs="0"/>
+                    <element name="type" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductLinkAttributeEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductLinkAttributeEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductAttributeFrontendLabelEntity">
+                <all>
+                    <element name="store_id" type="xsd:string" />
+                    <element name="label" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeFrontendLabelArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductAttributeFrontendLabelEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductAttributeEntityToCreate">
+                <all>
+                    <element name="attribute_code" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="frontend_input" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="scope" type="xsd:string" minOccurs="0" />
+                    <element name="default_value" type="xsd:string" minOccurs="0" />
+                    <element name="is_unique" type="xsd:int" minOccurs="0" />
+                    <element name="is_required" type="xsd:int" minOccurs="0" />
+                    <element name="apply_to" type="typens:ArrayOfString" minOccurs="0" />
+                    <element name="is_configurable" type="xsd:int" minOccurs="0" />
+                    <element name="is_searchable" type="xsd:int" minOccurs="0" />
+                    <element name="is_visible_in_advanced_search" type="xsd:int" minOccurs="0" />
+                    <element name="is_comparable" type="xsd:int" minOccurs="0" />
+                    <element name="is_used_for_promo_rules" type="xsd:int" minOccurs="0" />
+                    <element name="is_visible_on_front" type="xsd:int" minOccurs="0" />
+                    <element name="used_in_product_listing" type="xsd:int" minOccurs="0" />
+                    <element name="additional_fields" type="typens:associativeArray" minOccurs="0"/>
+                    <element name="frontend_label" type="typens:catalogProductAttributeFrontendLabelArray" minOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeEntityToUpdate">
+                <all>
+                    <element name="scope" type="xsd:string" minOccurs="0" />
+                    <element name="default_value" type="xsd:string" minOccurs="0" />
+                    <element name="is_unique" type="xsd:int" minOccurs="0" />
+                    <element name="is_required" type="xsd:int" minOccurs="0" />
+                    <element name="apply_to" type="typens:ArrayOfString" minOccurs="0" />
+                    <element name="is_configurable" type="xsd:int" minOccurs="0" />
+                    <element name="is_searchable" type="xsd:int" minOccurs="0" />
+                    <element name="is_visible_in_advanced_search" type="xsd:int" minOccurs="0" />
+                    <element name="is_comparable" type="xsd:int" minOccurs="0" />
+                    <element name="is_used_for_promo_rules" type="xsd:int" minOccurs="0" />
+                    <element name="is_visible_on_front" type="xsd:int" minOccurs="0" />
+                    <element name="used_in_product_listing" type="xsd:int" minOccurs="0" />
+                    <element name="additional_fields" type="typens:associativeArray" minOccurs="0"/>
+                    <element name="frontend_label" type="typens:catalogProductAttributeFrontendLabelArray" minOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeEntity">
+                <all>
+                    <element name="attribute_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="attribute_code" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="frontend_input" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="scope" type="xsd:string" minOccurs="0" />
+                    <element name="default_value" type="xsd:string" minOccurs="0" />
+                    <element name="is_unique" type="xsd:int" minOccurs="0" />
+                    <element name="is_required" type="xsd:int" minOccurs="0" />
+                    <element name="apply_to" type="typens:ArrayOfString" minOccurs="0" />
+                    <element name="is_configurable" type="xsd:int" minOccurs="0" />
+                    <element name="is_searchable" type="xsd:int" minOccurs="0" />
+                    <element name="is_visible_in_advanced_search" type="xsd:int" minOccurs="0" />
+                    <element name="is_comparable" type="xsd:int" minOccurs="0" />
+                    <element name="is_used_for_promo_rules" type="xsd:int" minOccurs="0" />
+                    <element name="is_visible_on_front" type="xsd:int" minOccurs="0" />
+                    <element name="used_in_product_listing" type="xsd:int" minOccurs="0" />
+                    <element name="additional_fields" type="typens:associativeArray" minOccurs="0"/>
+                    <element name="options" type="typens:catalogAttributeOptionEntityArray" minOccurs="0"/>
+                    <element name="frontend_label" type="typens:catalogProductAttributeFrontendLabelArray" minOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeOptionLabelEntity">
+                <all>
+                    <element name="store_id" type="typens:ArrayOfString" />
+                    <element name="value" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductAttributeOptionLabelArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductAttributeOptionLabelEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductAttributeOptionEntityToAdd">
+                <all>
+                    <element name="label" type="typens:catalogProductAttributeOptionLabelArray" />
+                    <element name="order" type="xsd:int" />
+                    <element name="is_default" type="xsd:int" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionAdditionalFieldsEntity">
+                <all>
+                    <element name="title" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="price_type" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="sku" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="max_characters" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="file_extension" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="image_size_x" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="image_size_y" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="value_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionAdditionalFieldsArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductCustomOptionAdditionalFieldsEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductCustomOptionToAdd">
+                <all>
+                    <element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="is_require" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <element name="additional_fields" type="typens:catalogProductCustomOptionAdditionalFieldsArray" minOccurs="1" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionToUpdate">
+                <all>
+                    <element name="title" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="type" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <element name="is_require" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <element name="additional_fields" type="typens:catalogProductCustomOptionAdditionalFieldsArray" minOccurs="0" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionInfoEntity">
+                <all>
+                    <element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="is_require" type="xsd:int" minOccurs="1" maxOccurs="1" />
+                    <element name="additional_fields" type="typens:catalogProductCustomOptionAdditionalFieldsArray" minOccurs="1" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionListEntity">
+                <all>
+                    <element name="option_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="is_require" type="xsd:int" minOccurs="1" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionListArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductCustomOptionListEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductCustomOptionTypesEntity">
+                <all>
+                    <element name="label" type="xsd:string"/>
+                    <element name="value" type="xsd:string"/>
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionTypesArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductCustomOptionTypesEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductCustomOptionValueInfoEntity">
+                <all>
+                    <element name="value_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="option_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sku" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="default_price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="default_price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="store_price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="store_price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="default_title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="store_title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionValueListEntity">
+                <all>
+                    <element name="value_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sku" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionValueListArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductCustomOptionValueListEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductCustomOptionValueAddEntity">
+                <all>
+                    <element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sku" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCustomOptionValueAddArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductCustomOptionValueAddEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductCustomOptionValueUpdateEntity">
+                <all>
+                    <element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sku" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                </all>
+            </complexType>
+        </schema>
+    </types>
+    <message name="catalogProductCurrentStoreRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCurrentStoreResponse">
+        <part name="storeView" type="xsd:int"/>
+    </message>
+    <message name="catalogProductListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="filters" type="typens:filters"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogProductListResponse">
+        <part name="storeView" type="typens:catalogProductEntityArray"/>
+    </message>
+    <message name="catalogProductInfoRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="attributes" type="typens:catalogProductRequestAttributes"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductInfoResponse">
+        <part name="info" type="typens:catalogProductReturnEntity"/>
+    </message>
+    <message name="catalogProductCreateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="type" type="xsd:string"/>
+        <part name="set" type="xsd:string"/>
+        <part name="sku" type="xsd:string"/>
+        <part name="productData" type="typens:catalogProductCreateEntity"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCreateResponse">
+        <part name="result" type="xsd:int"/>
+    </message>
+    <message name="catalogProductUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="productData" type="typens:catalogProductCreateEntity"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductUpdateResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductSetSpecialPriceRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="specialPrice" type="xsd:string"/>
+        <part name="fromDate" type="xsd:string"/>
+        <part name="toDate" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductSetSpecialPriceResponse">
+        <part name="result" type="xsd:int"/>
+    </message>
+    <message name="catalogProductGetSpecialPriceRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductGetSpecialPriceResponse">
+        <part name="result" type="typens:catalogProductReturnEntity"/>
+    </message>
+    <message name="catalogProductDeleteRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductDeleteResponse">
+        <part name="result" type="xsd:int"/>
+    </message>
+    <message name="catalogProductAttributeCurrentStoreRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeCurrentStoreResponse">
+        <part name="storeView" type="xsd:int"/>
+    </message>
+    <message name="catalogProductListOfAdditionalAttributesRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="productType" type="xsd:string" />
+        <part name="attributeSetId" type="xsd:string" />
+    </message>
+    <message name="catalogProductListOfAdditionalAttributesResponse">
+        <part name="result" type="typens:catalogAttributeEntityArray" />
+    </message>
+    <message name="catalogProductAttributeListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="setId" type="xsd:int"/>
+    </message>
+    <message name="catalogProductAttributeListResponse">
+        <part name="result" type="typens:catalogAttributeEntityArray"/>
+    </message>
+    <message name="catalogProductAttributeOptionsRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attributeId" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeOptionsResponse">
+        <part name="result" type="typens:catalogAttributeOptionEntityArray"/>
+    </message>
+    <message name="catalogProductAttributeSetCreateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attributeSetName" type="xsd:string"/>
+        <part name="skeletonSetId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeSetCreateResponse">
+        <part name="setId" type="xsd:int"/>
+    </message>
+    <message name="catalogProductAttributeSetRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attributeSetId" type="xsd:string"/>
+        <part name="forceProductsRemove" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeSetRemoveResponse">
+        <part name="isRemoved" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductAttributeSetListRequest">
+        <part name="sessionId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeSetListResponse">
+        <part name="result" type="typens:catalogProductAttributeSetEntityArray"/>
+    </message>
+    <message name="catalogProductAttributeSetAttributeAddRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="attributeId" type="xsd:string" />
+        <part name="attributeSetId" type="xsd:string" />
+        <part name="attributeGroupId" type="xsd:string"/>
+        <part name="sortOrder" type="xsd:string" />
+    </message>
+    <message name="catalogProductAttributeSetAttributeAddResponse">
+        <part name="isAdded" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductAttributeSetAttributeRemoveRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="attributeId" type="xsd:string" />
+        <part name="attributeSetId" type="xsd:string" />
+    </message>
+    <message name="catalogProductAttributeSetAttributeRemoveResponse">
+        <part name="isRemoved" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductAttributeSetGroupAddRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="attributeSetId" type="xsd:string" />
+        <part name="groupName" type="xsd:string" />
+    </message>
+    <message name="catalogProductAttributeSetGroupAddResponse">
+        <part name="result" type="xsd:int" />
+    </message>
+    <message name="catalogProductAttributeSetGroupRenameRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="groupId" type="xsd:string" />
+        <part name="groupName" type="xsd:string" />
+    </message>
+    <message name="catalogProductAttributeSetGroupRenameResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductAttributeSetGroupRemoveRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="attributeGroupId" type="xsd:string" />
+    </message>
+    <message name="catalogProductAttributeSetGroupRemoveResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductAttributeTypesRequest">
+        <part name="sessionId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeTypesResponse">
+        <part name="result" type="typens:catalogAttributeOptionEntityArray" />
+    </message>
+    <message name="catalogProductAttributeCreateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductAttributeEntityToCreate"/>
+    </message>
+    <message name="catalogProductAttributeCreateResponse">
+        <part name="result" type="xsd:int" />
+    </message>
+    <message name="catalogProductAttributeRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attribute" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeRemoveResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductAttributeInfoRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attribute" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeInfoResponse">
+        <part name="result" type="typens:catalogProductAttributeEntity" />
+    </message>
+    <message name="catalogProductAttributeUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attribute" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductAttributeEntityToUpdate"/>
+    </message>
+    <message name="catalogProductAttributeUpdateResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductAttributeAddOptionRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attribute" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductAttributeOptionEntityToAdd"/>
+    </message>
+    <message name="catalogProductAttributeAddOptionResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductAttributeRemoveOptionRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attribute" type="xsd:string"/>
+        <part name="optionId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeRemoveOptionResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductTypeListRequest">
+        <part name="sessionId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductTypeListResponse">
+        <part name="result" type="typens:catalogProductTypeEntityArray"/>
+    </message>
+    <message name="catalogProductAttributeTierPriceInfoRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeTierPriceInfoResponse">
+        <part name="result" type="typens:catalogProductTierPriceEntityArray"/>
+    </message>
+    <message name="catalogProductAttributeTierPriceUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="tier_price" type="typens:catalogProductTierPriceEntityArray"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeTierPriceUpdateResponse">
+        <part name="result" type="xsd:int"/>
+    </message>
+    <message name="catalogProductAttributeMediaCurrentStoreRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeMediaCurrentStoreResponse">
+        <part name="storeView" type="xsd:int"/>
+    </message>
+    <message name="catalogProductAttributeMediaListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeMediaListResponse">
+        <part name="result" type="typens:catalogProductImageEntityArray"/>
+    </message>
+    <message name="catalogProductAttributeMediaInfoRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="file" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeMediaInfoResponse">
+        <part name="result" type="typens:catalogProductImageEntity"/>
+    </message>
+    <message name="catalogProductAttributeMediaTypesRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="setId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeMediaTypesResponse">
+        <part name="result" type="typens:catalogProductAttributeMediaTypeEntityArray"/>
+    </message>
+    <message name="catalogProductAttributeMediaCreateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductAttributeMediaCreateEntity"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeMediaCreateResponse">
+        <part name="result" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeMediaUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="file" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductAttributeMediaCreateEntity"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeMediaUpdateResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductAttributeMediaRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="file" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductAttributeMediaRemoveResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductLinkListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="type" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductLinkListResponse">
+        <part name="result" type="typens:catalogProductLinkEntityArray"/>
+    </message>
+    <message name="catalogProductLinkAssignRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="type" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="linkedProduct" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductLinkEntity"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductLinkAssignResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductLinkUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="type" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="linkedProduct" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductLinkEntity"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductLinkUpdateResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductLinkRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="type" type="xsd:string"/>
+        <part name="product" type="xsd:string"/>
+        <part name="linkedProduct" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductLinkRemoveResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductLinkTypesRequest">
+        <part name="sessionId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductLinkTypesResponse">
+        <part name="result" type="typens:ArrayOfString"/>
+    </message>
+    <message name="catalogProductLinkAttributesRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="type" type="xsd:string"/>
+    </message>
+    <message name="catalogProductLinkAttributesResponse">
+        <part name="result" type="typens:catalogProductLinkAttributeEntityArray"/>
+    </message>
+    <message name="catalogCategoryCurrentStoreRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryCurrentStoreResponse">
+        <part name="storeView" type="xsd:int"/>
+    </message>
+    <message name="catalogProductCustomOptionAddRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="productId" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductCustomOptionToAdd"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionAddResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductCustomOptionUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="optionId" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductCustomOptionToUpdate"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionUpdateResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductCustomOptionListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="productId" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionListResponse">
+        <part name="result" type="typens:catalogProductCustomOptionListArray"/>
+    </message>
+    <message name="catalogProductCustomOptionTypesRequest">
+        <part name="sessionId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionTypesResponse">
+        <part name="result" type="typens:catalogProductCustomOptionTypesArray"/>
+    </message>
+    <message name="catalogProductCustomOptionInfoRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="optionId" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionInfoResponse">
+        <part name="result" type="typens:catalogProductCustomOptionInfoEntity"/>
+    </message>
+    <message name="catalogProductCustomOptionRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="optionId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionRemoveResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductCustomOptionValueListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="optionId" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionValueListResponse">
+        <part name="result" type="typens:catalogProductCustomOptionValueListArray"/>
+    </message>
+    <message name="catalogProductCustomOptionValueInfoRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="valueId" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionValueInfoResponse">
+        <part name="result" type="typens:catalogProductCustomOptionValueInfoEntity"/>
+    </message>
+    <message name="catalogProductCustomOptionValueAddRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="optionId" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductCustomOptionValueAddArray"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionValueAddResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductCustomOptionValueUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="valueId" type="xsd:string"/>
+        <part name="data" type="typens:catalogProductCustomOptionValueUpdateEntity"/>
+        <part name="storeId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionValueUpdateResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogProductCustomOptionValueRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="valueId" type="xsd:string"/>
+    </message>
+    <message name="catalogProductCustomOptionValueRemoveResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogCategoryTreeRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="parentId" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryTreeResponse">
+        <part name="tree" type="typens:catalogCategoryTree"/>
+    </message>
+    <message name="catalogCategoryLevelRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="website" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="parentCategory" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryLevelResponse">
+        <part name="tree" type="typens:ArrayOfCatalogCategoryEntitiesNoChildren"/>
+    </message>
+    <message name="catalogCategoryInfoRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="categoryId" type="xsd:int"/>
+        <part name="storeView" type="xsd:string"/>
+        <part name="attributes" type="typens:ArrayOfString"/>
+    </message>
+    <message name="catalogCategoryInfoResponse">
+        <part name="info" type="typens:catalogCategoryInfo"/>
+    </message>
+    <message name="catalogCategoryCreateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="parentId" type="xsd:int"/>
+        <part name="categoryData" type="typens:catalogCategoryEntityCreate"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryCreateResponse">
+        <part name="attribute_id" type="xsd:int"/>
+    </message>
+    <message name="catalogCategoryUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="categoryId" type="xsd:int"/>
+        <part name="categoryData" type="typens:catalogCategoryEntityCreate"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryUpdateResponse">
+        <part name="id" type="xsd:boolean"/>
+    </message>
+    <message name="catalogCategoryMoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="categoryId" type="xsd:int"/>
+        <part name="parentId" type="xsd:int"/>
+        <part name="afterId" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryMoveResponse">
+        <part name="id" type="xsd:boolean"/>
+    </message>
+    <message name="catalogCategoryDeleteRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="categoryId" type="xsd:int"/>
+    </message>
+    <message name="catalogCategoryDeleteResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogCategoryAssignedProductsRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="categoryId" type="xsd:int"/>
+    </message>
+    <message name="catalogCategoryAssignedProductsResponse">
+        <part name="result" type="typens:catalogAssignedProductArray"/>
+    </message>
+    <message name="catalogCategoryAssignProductRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="categoryId" type="xsd:int"/>
+        <part name="product" type="xsd:string"/>
+        <part name="position" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryAssignProductResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogCategoryUpdateProductRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="categoryId" type="xsd:int"/>
+        <part name="product" type="xsd:string"/>
+        <part name="position" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryUpdateProductResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogCategoryRemoveProductRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="categoryId" type="xsd:int"/>
+        <part name="product" type="xsd:string"/>
+        <part name="productIdentifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryRemoveProductResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="catalogCategoryAttributeCurrentStoreRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryAttributeCurrentStoreResponse">
+        <part name="storeView" type="xsd:int"/>
+    </message>
+    <message name="catalogCategoryAttributeListRequest">
+        <part name="sessionId" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryAttributeListResponse">
+        <part name="result" type="typens:catalogAttributeEntityArray"/>
+    </message>
+    <message name="catalogCategoryAttributeOptionsRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="attributeId" type="xsd:string"/>
+        <part name="storeView" type="xsd:string"/>
+    </message>
+    <message name="catalogCategoryAttributeOptionsResponse">
+        <part name="result" type="typens:catalogAttributeOptionEntityArray"/>
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="catalogCategoryCurrentStore">
+            <documentation>Set_Get current store view</documentation>
+            <input message="typens:catalogCategoryCurrentStoreRequest"/>
+            <output message="typens:catalogCategoryCurrentStoreResponse"/>
+        </operation>
+        <operation name="catalogCategoryTree">
+            <documentation>Retrieve hierarchical tree of categories.</documentation>
+            <input message="typens:catalogCategoryTreeRequest"/>
+            <output message="typens:catalogCategoryTreeResponse"/>
+        </operation>
+        <operation name="catalogCategoryLevel">
+            <documentation>Retrieve hierarchical tree of categories.</documentation>
+            <input message="typens:catalogCategoryLevelRequest"/>
+            <output message="typens:catalogCategoryLevelResponse"/>
+        </operation>
+        <operation name="catalogCategoryInfo">
+            <documentation>Retrieve hierarchical tree of categories.</documentation>
+            <input message="typens:catalogCategoryInfoRequest"/>
+            <output message="typens:catalogCategoryInfoResponse"/>
+        </operation>
+        <operation name="catalogCategoryCreate">
+            <documentation>Create new category and return its id.</documentation>
+            <input message="typens:catalogCategoryCreateRequest"/>
+            <output message="typens:catalogCategoryCreateResponse"/>
+        </operation>
+        <operation name="catalogCategoryUpdate">
+            <documentation>Update category</documentation>
+            <input message="typens:catalogCategoryUpdateRequest"/>
+            <output message="typens:catalogCategoryUpdateResponse"/>
+        </operation>
+        <operation name="catalogCategoryMove">
+            <documentation>Move category in tree</documentation>
+            <input message="typens:catalogCategoryMoveRequest"/>
+            <output message="typens:catalogCategoryMoveResponse"/>
+        </operation>
+        <operation name="catalogCategoryDelete">
+            <documentation>Delete category</documentation>
+            <input message="typens:catalogCategoryDeleteRequest"/>
+            <output message="typens:catalogCategoryDeleteResponse"/>
+        </operation>
+        <operation name="catalogCategoryAssignedProducts">
+            <documentation>Retrieve list of assigned products</documentation>
+            <input message="typens:catalogCategoryAssignedProductsRequest"/>
+            <output message="typens:catalogCategoryAssignedProductsResponse"/>
+        </operation>
+        <operation name="catalogCategoryAssignProduct">
+            <documentation>Assign product to category</documentation>
+            <input message="typens:catalogCategoryAssignProductRequest"/>
+            <output message="typens:catalogCategoryAssignProductResponse"/>
+        </operation>
+        <operation name="catalogCategoryUpdateProduct">
+            <documentation>Update assigned product</documentation>
+            <input message="typens:catalogCategoryUpdateProductRequest"/>
+            <output message="typens:catalogCategoryUpdateProductResponse"/>
+        </operation>
+        <operation name="catalogCategoryRemoveProduct">
+            <documentation>Remove product assignment from category</documentation>
+            <input message="typens:catalogCategoryRemoveProductRequest"/>
+            <output message="typens:catalogCategoryRemoveProductResponse"/>
+        </operation>
+        <operation name="catalogCategoryAttributeCurrentStore">
+            <documentation>Set/Get current store view</documentation>
+            <input message="typens:catalogCategoryAttributeCurrentStoreRequest"/>
+            <output message="typens:catalogCategoryAttributeCurrentStoreResponse"/>
+        </operation>
+        <operation name="catalogCategoryAttributeList">
+            <documentation>Retrieve category attributes</documentation>
+            <input message="typens:catalogCategoryAttributeListRequest"/>
+            <output message="typens:catalogCategoryAttributeListResponse"/>
+        </operation>
+        <operation name="catalogCategoryAttributeOptions">
+            <documentation>Retrieve attribute options</documentation>
+            <input message="typens:catalogCategoryAttributeOptionsRequest"/>
+            <output message="typens:catalogCategoryAttributeOptionsResponse"/>
+        </operation>
+        <operation name="catalogProductCurrentStore">
+            <documentation>Set/Get current store view</documentation>
+            <input message="typens:catalogProductCurrentStoreRequest"/>
+            <output message="typens:catalogProductCurrentStoreResponse"/>
+        </operation>
+        <operation name="catalogProductList">
+            <documentation>Retrieve products list by filters</documentation>
+            <input message="typens:catalogProductListRequest"/>
+            <output message="typens:catalogProductListResponse"/>
+        </operation>
+        <operation name="catalogProductInfo">
+            <documentation>Retrieve product</documentation>
+            <input message="typens:catalogProductInfoRequest"/>
+            <output message="typens:catalogProductInfoResponse"/>
+        </operation>
+        <operation name="catalogProductCreate">
+            <documentation>Create new product and return product id</documentation>
+            <input message="typens:catalogProductCreateRequest"/>
+            <output message="typens:catalogProductCreateResponse"/>
+        </operation>
+        <operation name="catalogProductUpdate">
+            <documentation>Update product</documentation>
+            <input message="typens:catalogProductUpdateRequest"/>
+            <output message="typens:catalogProductUpdateResponse"/>
+        </operation>
+        <operation name="catalogProductSetSpecialPrice">
+            <documentation>Update product special price</documentation>
+            <input message="typens:catalogProductSetSpecialPriceRequest"/>
+            <output message="typens:catalogProductSetSpecialPriceResponse"/>
+        </operation>
+        <operation name="catalogProductGetSpecialPrice">
+            <documentation>Get product special price data</documentation>
+            <input message="typens:catalogProductGetSpecialPriceRequest"/>
+            <output message="typens:catalogProductGetSpecialPriceResponse"/>
+        </operation>
+        <operation name="catalogProductDelete">
+            <documentation>Delete product</documentation>
+            <input message="typens:catalogProductDeleteRequest"/>
+            <output message="typens:catalogProductDeleteResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeCurrentStore">
+            <documentation>Set/Get current store view</documentation>
+            <input message="typens:catalogProductAttributeCurrentStoreRequest"/>
+            <output message="typens:catalogProductAttributeCurrentStoreResponse"/>
+        </operation>
+        <operation name="catalogProductListOfAdditionalAttributes">
+            <documentation>Get list of additional attributes which are not in default create/update list</documentation>
+            <input message="typens:catalogProductListOfAdditionalAttributesRequest"/>
+            <output message="typens:catalogProductListOfAdditionalAttributesResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeList">
+            <documentation>Retrieve attribute list</documentation>
+            <input message="typens:catalogProductAttributeListRequest"/>
+            <output message="typens:catalogProductAttributeListResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeOptions">
+            <documentation>Retrieve attribute options</documentation>
+            <input message="typens:catalogProductAttributeOptionsRequest"/>
+            <output message="typens:catalogProductAttributeOptionsResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeSetCreate">
+            <documentation>Create product attribute set based on another set</documentation>
+            <input message="typens:catalogProductAttributeSetCreateRequest"/>
+            <output message="typens:catalogProductAttributeSetCreateResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeSetRemove">
+            <documentation>Remove product attribute set</documentation>
+            <input message="typens:catalogProductAttributeSetRemoveRequest"/>
+            <output message="typens:catalogProductAttributeSetRemoveResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeSetList">
+            <documentation>Retrieve product attribute sets</documentation>
+            <input message="typens:catalogProductAttributeSetListRequest"/>
+            <output message="typens:catalogProductAttributeSetListResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeSetAttributeAdd">
+            <documentation>Add attribute into attribute set</documentation>
+            <input message="typens:catalogProductAttributeSetAttributeAddRequest"/>
+            <output message="typens:catalogProductAttributeSetAttributeAddResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeSetAttributeRemove">
+            <documentation>Remove attribute from attribute set</documentation>
+            <input message="typens:catalogProductAttributeSetAttributeRemoveRequest"/>
+            <output message="typens:catalogProductAttributeSetAttributeRemoveResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeSetGroupAdd">
+            <documentation>Create group within existing attribute set</documentation>
+            <input message="typens:catalogProductAttributeSetGroupAddRequest"/>
+            <output message="typens:catalogProductAttributeSetGroupAddResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeSetGroupRename">
+            <documentation>Rename existing group</documentation>
+            <input message="typens:catalogProductAttributeSetGroupRenameRequest"/>
+            <output message="typens:catalogProductAttributeSetGroupRenameResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeSetGroupRemove">
+            <documentation>Remove group from attribute set</documentation>
+            <input message="typens:catalogProductAttributeSetGroupRemoveRequest"/>
+            <output message="typens:catalogProductAttributeSetGroupRemoveResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeTypes">
+            <documentation>Get list of possible attribute types</documentation>
+            <input message="typens:catalogProductAttributeTypesRequest"/>
+            <output message="typens:catalogProductAttributeTypesResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeCreate">
+            <documentation>Create new attribute</documentation>
+            <input message="typens:catalogProductAttributeCreateRequest"/>
+            <output message="typens:catalogProductAttributeCreateResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeRemove">
+            <documentation>Delete attribute</documentation>
+            <input message="typens:catalogProductAttributeRemoveRequest"/>
+            <output message="typens:catalogProductAttributeRemoveResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeInfo">
+            <documentation>Get full information about attribute with list of options</documentation>
+            <input message="typens:catalogProductAttributeInfoRequest"/>
+            <output message="typens:catalogProductAttributeInfoResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeUpdate">
+            <documentation>Update attribute</documentation>
+            <input message="typens:catalogProductAttributeUpdateRequest"/>
+            <output message="typens:catalogProductAttributeUpdateResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeAddOption">
+            <documentation>Add option to attribute</documentation>
+            <input message="typens:catalogProductAttributeAddOptionRequest"/>
+            <output message="typens:catalogProductAttributeAddOptionResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeRemoveOption">
+            <documentation>Remove option from attribute</documentation>
+            <input message="typens:catalogProductAttributeRemoveOptionRequest"/>
+            <output message="typens:catalogProductAttributeRemoveOptionResponse"/>
+        </operation>
+        <operation name="catalogProductTypeList">
+            <documentation>Retrieve product types</documentation>
+            <input message="typens:catalogProductTypeListRequest"/>
+            <output message="typens:catalogProductTypeListResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeTierPriceInfo">
+            <documentation>Retrieve product tier prices</documentation>
+            <input message="typens:catalogProductAttributeTierPriceInfoRequest"/>
+            <output message="typens:catalogProductAttributeTierPriceInfoResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeTierPriceUpdate">
+            <documentation>Update product tier prices</documentation>
+            <input message="typens:catalogProductAttributeTierPriceUpdateRequest"/>
+            <output message="typens:catalogProductAttributeTierPriceUpdateResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeMediaCurrentStore">
+            <documentation>Set/Get current store view</documentation>
+            <input message="typens:catalogProductAttributeMediaCurrentStoreRequest"/>
+            <output message="typens:catalogProductAttributeMediaCurrentStoreResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeMediaList">
+            <documentation>Retrieve product image list</documentation>
+            <input message="typens:catalogProductAttributeMediaListRequest"/>
+            <output message="typens:catalogProductAttributeMediaListResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeMediaInfo">
+            <documentation>Retrieve product image data</documentation>
+            <input message="typens:catalogProductAttributeMediaInfoRequest"/>
+            <output message="typens:catalogProductAttributeMediaInfoResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeMediaTypes">
+            <documentation>Retrieve product image types</documentation>
+            <input message="typens:catalogProductAttributeMediaTypesRequest"/>
+            <output message="typens:catalogProductAttributeMediaTypesResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeMediaCreate">
+            <documentation>Upload new product image</documentation>
+            <input message="typens:catalogProductAttributeMediaCreateRequest"/>
+            <output message="typens:catalogProductAttributeMediaCreateResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeMediaUpdate">
+            <documentation>Update product image</documentation>
+            <input message="typens:catalogProductAttributeMediaUpdateRequest"/>
+            <output message="typens:catalogProductAttributeMediaUpdateResponse"/>
+        </operation>
+        <operation name="catalogProductAttributeMediaRemove">
+            <documentation>Remove product image</documentation>
+            <input message="typens:catalogProductAttributeMediaRemoveRequest"/>
+            <output message="typens:catalogProductAttributeMediaRemoveResponse"/>
+        </operation>
+        <operation name="catalogProductLinkList">
+            <documentation>Retrieve linked products</documentation>
+            <input message="typens:catalogProductLinkListRequest"/>
+            <output message="typens:catalogProductLinkListResponse"/>
+        </operation>
+        <operation name="catalogProductLinkAssign">
+            <documentation>Assign product link</documentation>
+            <input message="typens:catalogProductLinkAssignRequest"/>
+            <output message="typens:catalogProductLinkAssignResponse"/>
+        </operation>
+        <operation name="catalogProductLinkUpdate">
+            <documentation>Update product link</documentation>
+            <input message="typens:catalogProductLinkUpdateRequest"/>
+            <output message="typens:catalogProductLinkUpdateResponse"/>
+        </operation>
+        <operation name="catalogProductLinkRemove">
+            <documentation>Remove product link</documentation>
+            <input message="typens:catalogProductLinkRemoveRequest"/>
+            <output message="typens:catalogProductLinkRemoveResponse"/>
+        </operation>
+        <operation name="catalogProductLinkTypes">
+            <documentation>Retrieve product link types</documentation>
+            <input message="typens:catalogProductLinkTypesRequest"/>
+            <output message="typens:catalogProductLinkTypesResponse"/>
+        </operation>
+        <operation name="catalogProductLinkAttributes">
+            <documentation>Retrieve product link type attributes</documentation>
+            <input message="typens:catalogProductLinkAttributesRequest"/>
+            <output message="typens:catalogProductLinkAttributesResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionAdd">
+            <documentation>Add new custom option into product</documentation>
+            <input message="typens:catalogProductCustomOptionAddRequest"/>
+            <output message="typens:catalogProductCustomOptionAddResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionUpdate">
+            <documentation>Update product custom option</documentation>
+            <input message="typens:catalogProductCustomOptionUpdateRequest"/>
+            <output message="typens:catalogProductCustomOptionUpdateResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionTypes">
+            <documentation>Get list of available custom option types</documentation>
+            <input message="typens:catalogProductCustomOptionTypesRequest"/>
+            <output message="typens:catalogProductCustomOptionTypesResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionInfo">
+            <documentation>Get full information about custom option in product</documentation>
+            <input message="typens:catalogProductCustomOptionInfoRequest"/>
+            <output message="typens:catalogProductCustomOptionInfoResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionList">
+            <documentation>Retrieve list of product custom options</documentation>
+            <input message="typens:catalogProductCustomOptionListRequest"/>
+            <output message="typens:catalogProductCustomOptionListResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionRemove">
+            <documentation>Remove custom option</documentation>
+            <input message="typens:catalogProductCustomOptionRemoveRequest"/>
+            <output message="typens:catalogProductCustomOptionRemoveResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionValueInfo">
+            <documentation>Retrieve custom option value info</documentation>
+            <input message="typens:catalogProductCustomOptionValueInfoRequest"/>
+            <output message="typens:catalogProductCustomOptionValueInfoResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionValueList">
+            <documentation>Retrieve custom option values list</documentation>
+            <input message="typens:catalogProductCustomOptionValueListRequest"/>
+            <output message="typens:catalogProductCustomOptionValueListResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionValueAdd">
+            <documentation>Add new custom option values</documentation>
+            <input message="typens:catalogProductCustomOptionValueAddRequest"/>
+            <output message="typens:catalogProductCustomOptionValueAddResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionValueUpdate">
+            <documentation>Update custom option value</documentation>
+            <input message="typens:catalogProductCustomOptionValueUpdateRequest"/>
+            <output message="typens:catalogProductCustomOptionValueUpdateResponse"/>
+        </operation>
+        <operation name="catalogProductCustomOptionValueRemove">
+            <documentation>Remove value from custom option</documentation>
+            <input message="typens:catalogProductCustomOptionValueRemoveRequest"/>
+            <output message="typens:catalogProductCustomOptionValueRemoveResponse"/>
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <operation name="catalogCategoryCurrentStore">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryTree">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryLevel">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryMove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryDelete">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryAssignedProducts">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryAssignProduct">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryUpdateProduct">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryRemoveProduct">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCurrentStore">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductListOfAdditionalAttributes">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductSetSpecialPrice">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductGetSpecialPrice">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductDelete">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeCurrentStore">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeSetCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeOptions">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeSetRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeSetList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeSetAttributeAdd">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeSetAttributeRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeSetGroupAdd">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeSetGroupRename">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeSetGroupRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeTypes">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryAttributeCurrentStore">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeMediaCurrentStore">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeAddOption">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeRemoveOption">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductTypeList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeTierPriceInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeTierPriceUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryAttributeList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogCategoryAttributeOptions">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeMediaList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeMediaInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeMediaTypes">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeMediaCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeMediaUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductAttributeMediaRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductLinkList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductLinkAssign">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductLinkUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductLinkRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductLinkTypes">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductLinkAttributes">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionAdd">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionTypes">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionValueInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionValueList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionValueAdd">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionValueUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionValueRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductCustomOptionRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+    </binding>
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}"/>
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/Catalog/etc/wsi.xml b/app/code/core/Mage/Catalog/etc/wsi.xml
new file mode 100644
index 00000000000..22ea67baa3d
--- /dev/null
+++ b/app/code/core/Mage/Catalog/etc/wsi.xml
@@ -0,0 +1,2866 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="catalogProductEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductEntity">
+                <xsd:sequence>
+                    <xsd:element name="product_id" type="xsd:string" />
+                    <xsd:element name="sku" type="xsd:string" />
+                    <xsd:element name="name" type="xsd:string" />
+                    <xsd:element name="set" type="xsd:string" />
+                    <xsd:element name="type" type="xsd:string" />
+                    <xsd:element name="category_ids" type="typens:ArrayOfString" />
+                    <xsd:element name="website_ids" type="typens:ArrayOfString" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductRequestAttributes">
+                <xsd:sequence>
+                    <xsd:element name="attributes" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="additional_attributes" type="typens:ArrayOfString" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductConfigurableAttributesEntity">
+                <xsd:sequence>
+                    <xsd:element name="attribute_code" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="frontend_label" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="frontend_label_use_default" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="position" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="prices" type="typens:catalogProductConfigurableOptionPricesEntityArray" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductConfigurableAttributesEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductConfigurableAttributesEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductConfigurableOptionPricesEntity">
+                <xsd:sequence>
+                    <xsd:element name="option_value" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="use_default_value" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductConfigurableOptionPricesEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductConfigurableOptionPricesEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductReturnEntity">
+                <xsd:sequence>
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="set" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="categories" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="websites" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="type_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="short_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weight" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="status" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="url_key" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="url_path" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="visibility" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="category_ids" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="website_ids" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="has_options" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_message_available" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="special_price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="special_from_date" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="special_to_date" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_class_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tier_price" type="typens:catalogProductTierPriceEntityArray" minOccurs="0" />
+                    <xsd:element name="meta_title" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_keyword" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_design" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_layout_update" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="options_container" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="additional_attributes" type="typens:associativeArray" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCreateEntity">
+                <xsd:sequence>
+                    <xsd:element name="categories" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="websites" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="short_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weight" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="status" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="url_key" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="url_path" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="visibility" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="category_ids" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="website_ids" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="has_options" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_message_available" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="special_price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="special_from_date" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="special_to_date" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_class_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tier_price" type="typens:catalogProductTierPriceEntityArray" minOccurs="0" />
+                    <xsd:element name="meta_title" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_keyword" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_design" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_layout_update" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="options_container" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="additional_attributes" type="typens:associativeArray" minOccurs="0" />
+                    <xsd:element name="configurable_attributes" type="typens:catalogProductConfigurableAttributesEntityArray" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductAttributeSetEntity">
+                <xsd:sequence>
+                    <xsd:element name="set_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductAttributeSetEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductAttributeSetEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductTypeEntity">
+                <xsd:sequence>
+                    <xsd:element name="type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="label" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductTypeEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductTypeEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductTierPriceEntity">
+                <xsd:sequence>
+                    <xsd:element name="customer_group_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="website" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="price" type="xsd:double" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductTierPriceEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductTierPriceEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="ArrayOfCatalogCategoryEntities">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogCategoryEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogCategoryEntity">
+                <xsd:sequence>
+                    <xsd:element name="category_id" type="xsd:int" />
+                    <xsd:element name="parent_id" type="xsd:int" />
+                    <xsd:element name="name" type="xsd:string" />
+                    <xsd:element name="is_active" type="xsd:int" />
+                    <xsd:element name="position" type="xsd:int" />
+                    <xsd:element name="level" type="xsd:int" />
+                    <xsd:element name="children" type="typens:ArrayOfCatalogCategoryEntities" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogCategoryEntityNoChildren">
+                <xsd:sequence>
+                    <xsd:element name="category_id" type="xsd:int" />
+                    <xsd:element name="parent_id" type="xsd:int" />
+                    <xsd:element name="name" type="xsd:string" />
+                    <xsd:element name="is_active" type="xsd:int" />
+                    <xsd:element name="position" type="xsd:int" />
+                    <xsd:element name="level" type="xsd:int" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="ArrayOfCatalogCategoryEntitiesNoChildren">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogCategoryEntityNoChildren" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogCategoryTree">
+                <xsd:sequence>
+                    <xsd:element name="category_id" type="xsd:int" />
+                    <xsd:element name="parent_id" type="xsd:int" />
+                    <xsd:element name="name" type="xsd:string" />
+                    <xsd:element name="position" type="xsd:int" />
+                    <xsd:element name="level" type="xsd:int" />
+                    <xsd:element name="children" type="typens:ArrayOfCatalogCategoryEntities" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogCategoryEntityCreate">
+                <xsd:sequence>
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="position" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="custom_design" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_design_apply" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="custom_design_from" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_design_to" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_layout_update" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="default_sort_by" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="display_mode" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_anchor" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="landing_page" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="meta_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_keywords" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_title" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="page_layout" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="url_key" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="include_in_menu" type="xsd:int" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogCategoryInfo">
+                <xsd:sequence>
+                    <xsd:element name="category_id" type="xsd:string" />
+                    <xsd:element name="is_active" type="xsd:int" />
+                    <xsd:element name="position" type="xsd:string" />
+                    <xsd:element name="level" type="xsd:string" />
+                    <xsd:element name="parent_id" type="xsd:string" />
+                    <xsd:element name="all_children" type="xsd:string" />
+                    <xsd:element name="children" type="xsd:string" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="url_key" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_title" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_keywords" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="meta_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="path" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="url_path" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="children_count" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="display_mode" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_anchor" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="custom_design" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_design_apply" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_design_from" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_design_to" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="page_layout" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="custom_layout_update" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="default_sort_by" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="landing_page" type="xsd:int" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogAssignedProduct">
+                <xsd:sequence>
+                    <xsd:element name="product_id" type="xsd:int" />
+                    <xsd:element name="type" type="xsd:string" />
+                    <xsd:element name="set" type="xsd:int" />
+                    <xsd:element name="sku" type="xsd:string" />
+                    <xsd:element name="position" type="xsd:int" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogAssignedProductArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogAssignedProduct" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogAttributeEntity">
+                <xsd:sequence>
+                    <xsd:element name="attribute_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="required" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="scope" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogAttributeEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogAttributeEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogAttributeOptionEntity">
+                <xsd:sequence>
+                    <xsd:element name="label" type="xsd:string" />
+                    <xsd:element name="value" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogAttributeOptionEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogAttributeOptionEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductImageEntity">
+                <xsd:sequence>
+                    <xsd:element name="file" type="xsd:string" />
+                    <xsd:element name="label" type="xsd:string" />
+                    <xsd:element name="position" type="xsd:string" />
+                    <xsd:element name="exclude" type="xsd:string" />
+                    <xsd:element name="url" type="xsd:string" />
+                    <xsd:element name="types" type="typens:ArrayOfString" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductImageEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductImageEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductAttributeMediaTypeEntity">
+                <xsd:sequence>
+                    <xsd:element name="code" type="xsd:string" />
+                    <xsd:element name="scope" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductAttributeMediaTypeEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductAttributeMediaTypeEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductImageFileEntity">
+                <xsd:sequence>
+                    <xsd:element name="content" type="xsd:string" />
+                    <xsd:element name="mime" type="xsd:string" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductAttributeMediaCreateEntity">
+                <xsd:sequence>
+                    <xsd:element name="file" type="typens:catalogProductImageFileEntity" minOccurs="0" />
+                    <xsd:element name="label" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="position" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="types" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="exclude" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="remove" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductLinkEntity">
+                <xsd:sequence>
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="set" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="position" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductLinkEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductLinkEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductLinkAttributeEntity">
+                <xsd:sequence>
+                    <xsd:element name="code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductLinkAttributeEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductLinkAttributeEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductAttributeFrontendLabelEntity">
+                <xsd:sequence>
+                    <xsd:element name="store_id" type="xsd:string" />
+                    <xsd:element name="label" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductAttributeFrontendLabelArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductAttributeFrontendLabelEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductAttributeEntityToCreate">
+                <xsd:sequence>
+                    <xsd:element name="attribute_code" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="frontend_input" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="scope" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="default_value" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_unique" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_required" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="apply_to" type="typens:ArrayOfString" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_configurable" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_searchable" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_visible_in_advanced_search" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_comparable" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_used_for_promo_rules" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_visible_on_front" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="used_in_product_listing" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="additional_fields" type="typens:associativeArray" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="frontend_label" type="typens:catalogProductAttributeFrontendLabelArray" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+
+            <xsd:complexType name="catalogProductCustomOptionAdditionalFieldsEntity">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="price_type" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="max_characters" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="file_extension" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="image_size_x" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="image_size_y" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="value_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionAdditionalFieldsArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="1" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductCustomOptionAdditionalFieldsEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionToAdd">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_require" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="additional_fields" type="typens:catalogProductCustomOptionAdditionalFieldsArray" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionToUpdate">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_require" type="xsd:int" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="additional_fields" type="typens:catalogProductCustomOptionAdditionalFieldsArray" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionInfoEntity">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="is_require" type="xsd:int" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="additional_fields" type="typens:catalogProductCustomOptionAdditionalFieldsArray" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionListEntity">
+                <xsd:sequence>
+                    <xsd:element name="option_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="is_require" type="xsd:int" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionListArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductCustomOptionListEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionTypesEntity">
+                <xsd:sequence>
+                    <xsd:element name="label" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="value" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionTypesArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductCustomOptionTypesEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionValueInfoEntity">
+                <xsd:sequence>
+                    <xsd:element name="value_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="option_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="default_price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="default_price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="store_price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="store_price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="default_title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="store_title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionValueListEntity">
+                <xsd:sequence>
+                    <xsd:element name="value_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionValueListArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductCustomOptionValueListEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionValueAddEntity">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionValueAddArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="1" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductCustomOptionValueAddEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCustomOptionValueUpdateEntity">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="price_type" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="sort_order" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:element name="catalogProductCurrentStoreRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCurrentStoreResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="filters" type="typens:filters" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="attributes" type="typens:catalogProductRequestAttributes" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductReturnEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="set" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sku" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productData" type="typens:catalogProductCreateEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productData" type="typens:catalogProductCreateEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductSetSpecialPriceRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="specialPrice" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="fromDate" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="toDate" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductSetSpecialPriceResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductGetSpecialPriceRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductGetSpecialPriceResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductReturnEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductDeleteRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductDeleteResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeCurrentStoreRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeCurrentStoreResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductListOfAdditionalAttributesRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productType" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeSetId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductListOfAdditionalAttributesResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogAttributeEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="setId" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogAttributeEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeOptionsRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeOptionsResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogAttributeOptionEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionAddRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductCustomOptionToAdd" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionAddResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="optionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductCustomOptionToUpdate" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionTypesRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionTypesResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductCustomOptionTypesArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductCustomOptionListArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="optionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductCustomOptionInfoEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="optionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="optionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductCustomOptionValueListArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="valueId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductCustomOptionValueInfoEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueAddRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="optionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductCustomOptionValueAddArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueAddResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="valueId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductCustomOptionValueUpdateEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="valueId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductCustomOptionValueRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeSetName" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="skeletonSetId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeSetId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="forceProductsRemove" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductAttributeSetEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetAttributeAddRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeSetId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="attributeGroupId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="sortOrder" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetAttributeAddResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetAttributeRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeSetId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetAttributeRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetGroupAddRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeSetId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="groupName" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetGroupAddResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+             <xsd:element name="catalogProductAttributeSetGroupRenameRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="groupId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="groupName" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetGroupRenameResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetGroupRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeGroupId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeSetGroupRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTypeListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTypeListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductTypeEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeTierPriceInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeTierPriceInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductTierPriceEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeTierPriceUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="tierPrices" type="typens:catalogProductTierPriceEntityArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeTierPriceUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaCurrentStoreRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaCurrentStoreResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductImageEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="file" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductImageEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaTypesRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="setId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaTypesResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductAttributeMediaTypeEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductAttributeMediaCreateEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="file" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductAttributeMediaCreateEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="file" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeMediaRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductLinkEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkAssignRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="linkedProductId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="data" type="typens:catalogProductLinkEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkAssignResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="linkedProductId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="data" type="typens:catalogProductLinkEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="linkedProductId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkTypesRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkTypesResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:ArrayOfString" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkAttributesRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductLinkAttributesResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductLinkAttributeEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryCurrentStoreRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryCurrentStoreResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryTreeRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="parentId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryTreeResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogCategoryTree" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryLevelRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="website" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="categoryId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryLevelResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:ArrayOfCatalogCategoryEntitiesNoChildren" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="attributes" type="typens:ArrayOfString" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogCategoryInfo" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="parentId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryData" type="typens:catalogCategoryEntityCreate" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryData" type="typens:catalogCategoryEntityCreate" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryMoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="parentId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="afterId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryMoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryDeleteRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryId" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryDeleteResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAssignedProductsRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAssignedProductsResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogAssignedProductArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAssignProductRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="position" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAssignProductResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryUpdateProductRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="position" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryUpdateProductResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryRemoveProductRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="categoryId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryRemoveProductResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAttributeListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAttributeListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogAttributeEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAttributeOptionsRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attributeId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAttributeOptionsResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogAttributeOptionEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAttributeCurrentStoreRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogCategoryAttributeCurrentStoreResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductAttributeEntityToCreate" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="attribute" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductAttributeRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="catalogProductCurrentStoreRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCurrentStoreRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCurrentStoreResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCurrentStoreResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductInfoRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductInfoResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCreateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCreateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductSetSpecialPriceRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductSetSpecialPriceRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductSetSpecialPriceResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductSetSpecialPriceResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductGetSpecialPriceRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductGetSpecialPriceRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductGetSpecialPriceResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductGetSpecialPriceResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductDeleteRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductDeleteRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductDeleteResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductDeleteResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeCurrentStoreRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeCurrentStoreRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeCurrentStoreResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeCurrentStoreResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductListOfAdditionalAttributesRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductListOfAdditionalAttributesRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductListOfAdditionalAttributesResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductListOfAdditionalAttributesResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeOptionsRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeOptionsRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeOptionsResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeOptionsResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionAddRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionAddRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionAddResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionAddResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionTypesRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionTypesRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionTypesResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionTypesResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionInfoRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionInfoResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueAddRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueAddRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueAddResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueAddResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueInfoRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueInfoResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductCustomOptionValueRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductCustomOptionValueRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetCreateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetCreateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetAttributeAddRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetAttributeAddRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetAttributeAddResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetAttributeAddResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetAttributeRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetAttributeRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetAttributeRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetAttributeRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetGroupAddRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetGroupAddRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetGroupAddResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetGroupAddResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetGroupRenameRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetGroupRenameRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetGroupRenameResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetGroupRenameResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetGroupRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetGroupRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeSetGroupRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeSetGroupRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTypeListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductTypeListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTypeListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductTypeListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeTierPriceInfoRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeTierPriceInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeTierPriceInfoResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeTierPriceInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeTierPriceUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeTierPriceUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeTierPriceUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeTierPriceUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaCurrentStoreRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaCurrentStoreRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaCurrentStoreResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaCurrentStoreResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaInfoRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaInfoResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaTypesRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaTypesRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaTypesResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaTypesResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaCreateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaCreateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeMediaRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeMediaRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkAssignRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkAssignRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkAssignResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkAssignResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkTypesRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkTypesRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkTypesResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkTypesResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkAttributesRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkAttributesRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductLinkAttributesResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductLinkAttributesResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryCurrentStoreRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryCurrentStoreRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryCurrentStoreResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryCurrentStoreResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryTreeRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryTreeRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryTreeResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryTreeResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryLevelRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryLevelRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryLevelResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryLevelResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryInfoRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryInfoResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryCreateRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryCreateResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryMoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryMoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryMoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryMoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryDeleteRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryDeleteRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryDeleteResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryDeleteResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAssignedProductsRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAssignedProductsRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAssignedProductsResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAssignedProductsResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAssignProductRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAssignProductRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAssignProductResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAssignProductResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryUpdateProductRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryUpdateProductRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryUpdateProductResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryUpdateProductResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryRemoveProductRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryRemoveProductRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryRemoveProductResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryRemoveProductResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAttributeCurrentStoreRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAttributeCurrentStoreRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAttributeCurrentStoreResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAttributeCurrentStoreResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAttributeListRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAttributeListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAttributeListResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAttributeListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAttributeOptionsRequest">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAttributeOptionsRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogCategoryAttributeOptionsResponse">
+        <wsdl:part name="parameters" element="typens:catalogCategoryAttributeOptionsResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeCreateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeCreateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductAttributeRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductAttributeRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="catalogCategoryCurrentStore">
+            <wsdl:documentation>Set_Get current store view</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryCurrentStoreRequest" />
+            <wsdl:output message="typens:catalogCategoryCurrentStoreResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryTree">
+            <wsdl:documentation>Retrieve hierarchical tree of categories.</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryTreeRequest" />
+            <wsdl:output message="typens:catalogCategoryTreeResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryLevel">
+            <wsdl:documentation>Retrieve hierarchical tree of categories.</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryLevelRequest" />
+            <wsdl:output message="typens:catalogCategoryLevelResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryInfo">
+            <wsdl:documentation>Retrieve hierarchical tree of categories.</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryInfoRequest" />
+            <wsdl:output message="typens:catalogCategoryInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryCreate">
+            <wsdl:documentation>Create new category and return its id.</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryCreateRequest" />
+            <wsdl:output message="typens:catalogCategoryCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryUpdate">
+            <wsdl:documentation>Update category</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryUpdateRequest" />
+            <wsdl:output message="typens:catalogCategoryUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryMove">
+            <wsdl:documentation>Move category in tree</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryMoveRequest" />
+            <wsdl:output message="typens:catalogCategoryMoveResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryDelete">
+            <wsdl:documentation>Delete category</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryDeleteRequest" />
+            <wsdl:output message="typens:catalogCategoryDeleteResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAssignedProducts">
+            <wsdl:documentation>Retrieve list of assigned products</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryAssignedProductsRequest" />
+            <wsdl:output message="typens:catalogCategoryAssignedProductsResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAssignProduct">
+            <wsdl:documentation>Assign product to category</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryAssignProductRequest" />
+            <wsdl:output message="typens:catalogCategoryAssignProductResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryUpdateProduct">
+            <wsdl:documentation>Update assigned product</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryUpdateProductRequest" />
+            <wsdl:output message="typens:catalogCategoryUpdateProductResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryRemoveProduct">
+            <wsdl:documentation>Remove product assignment from category</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryRemoveProductRequest" />
+            <wsdl:output message="typens:catalogCategoryRemoveProductResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAttributeCurrentStore">
+            <wsdl:documentation>Set/Get current store view</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryAttributeCurrentStoreRequest" />
+            <wsdl:output message="typens:catalogCategoryAttributeCurrentStoreResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAttributeList">
+            <wsdl:documentation>Retrieve category attributes</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryAttributeListRequest" />
+            <wsdl:output message="typens:catalogCategoryAttributeListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAttributeOptions">
+            <wsdl:documentation>Retrieve attribute options</wsdl:documentation>
+            <wsdl:input message="typens:catalogCategoryAttributeOptionsRequest" />
+            <wsdl:output message="typens:catalogCategoryAttributeOptionsResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCurrentStore">
+            <wsdl:documentation>Set/Get current store view</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCurrentStoreRequest" />
+            <wsdl:output message="typens:catalogProductCurrentStoreResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductList">
+            <wsdl:documentation>Retrieve products list by filters</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductListRequest" />
+            <wsdl:output message="typens:catalogProductListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductInfo">
+            <wsdl:documentation>Retrieve product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductInfoRequest" />
+            <wsdl:output message="typens:catalogProductInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCreate">
+            <wsdl:documentation>Create new product and return product id</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCreateRequest" />
+            <wsdl:output message="typens:catalogProductCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductUpdate">
+            <wsdl:documentation>Update product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductUpdateRequest" />
+            <wsdl:output message="typens:catalogProductUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductSetSpecialPrice">
+            <wsdl:documentation>Update product special price</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductSetSpecialPriceRequest" />
+            <wsdl:output message="typens:catalogProductSetSpecialPriceResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductGetSpecialPrice">
+            <wsdl:documentation>Get product special price data</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductGetSpecialPriceRequest" />
+            <wsdl:output message="typens:catalogProductGetSpecialPriceResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductDelete">
+            <wsdl:documentation>Delete product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductDeleteRequest" />
+            <wsdl:output message="typens:catalogProductDeleteResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeCurrentStore">
+            <wsdl:documentation>Set/Get current store view</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeCurrentStoreRequest" />
+            <wsdl:output message="typens:catalogProductAttributeCurrentStoreResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductListOfAdditionalAttributes">
+            <wsdl:documentation>Get list of additional attributes which are not in default create/update list</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductListOfAdditionalAttributesRequest" />
+            <wsdl:output message="typens:catalogProductListOfAdditionalAttributesResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeList">
+            <wsdl:documentation>Retrieve attribute list</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeListRequest" />
+            <wsdl:output message="typens:catalogProductAttributeListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeOptions">
+            <wsdl:documentation>Retrieve attribute options</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeOptionsRequest" />
+            <wsdl:output message="typens:catalogProductAttributeOptionsResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionAdd">
+            <wsdl:documentation>Add new custom option into product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionAddRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionAddResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionUpdate">
+            <wsdl:documentation>Update product custom option</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionUpdateRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionTypes">
+            <wsdl:documentation>Get list of available custom option types </wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionTypesRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionTypesResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionList">
+            <wsdl:documentation>Retrieve list of product custom options</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionListRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionInfo">
+            <wsdl:documentation>Get full information about custom option in product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionInfoRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionRemove">
+            <wsdl:documentation>Remove custom option</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionRemoveRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionRemoveResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueList">
+            <wsdl:documentation>Retrieve custom option values list</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionValueListRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionValueListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueAdd">
+            <wsdl:documentation>Add new custom option values</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionValueAddRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionValueAddResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueInfo">
+            <wsdl:documentation>Retrieve custom option value info</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionValueInfoRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionValueInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueUpdate">
+            <wsdl:documentation>Update custom option value</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionValueUpdateRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionValueUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueRemove">
+            <wsdl:documentation>Remove value from custom option</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductCustomOptionValueRemoveRequest" />
+            <wsdl:output message="typens:catalogProductCustomOptionValueRemoveResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetCreate">
+            <wsdl:documentation>Create product attribute set based on another set</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeSetCreateRequest" />
+            <wsdl:output message="typens:catalogProductAttributeSetCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetRemove">
+            <wsdl:documentation>Remove product attribute set</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeSetRemoveRequest" />
+            <wsdl:output message="typens:catalogProductAttributeSetRemoveResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetList">
+            <wsdl:documentation>Retrieve product attribute sets</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeSetListRequest" />
+            <wsdl:output message="typens:catalogProductAttributeSetListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetAttributeAdd">
+            <wsdl:documentation>Add attribute into attribute set</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeSetAttributeAddRequest" />
+            <wsdl:output message="typens:catalogProductAttributeSetAttributeAddResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetAttributeRemove">
+            <wsdl:documentation>Remove attribute from attribute set</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeSetAttributeRemoveRequest" />
+            <wsdl:output message="typens:catalogProductAttributeSetAttributeRemoveResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetGroupAdd">
+            <wsdl:documentation>Create group within existing attribute set</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeSetGroupAddRequest" />
+            <wsdl:output message="typens:catalogProductAttributeSetGroupAddResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetGroupRename">
+            <wsdl:documentation>Rename existing group</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeSetGroupRenameRequest" />
+            <wsdl:output message="typens:catalogProductAttributeSetGroupRenameResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetGroupRemove">
+            <wsdl:documentation>Remove group from attribute set</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeSetGroupRemoveRequest" />
+            <wsdl:output message="typens:catalogProductAttributeSetGroupRemoveResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductTypeList">
+            <wsdl:documentation>Retrieve product types</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductTypeListRequest" />
+            <wsdl:output message="typens:catalogProductTypeListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeTierPriceInfo">
+            <wsdl:documentation>Retrieve product tier prices</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeTierPriceInfoRequest" />
+            <wsdl:output message="typens:catalogProductAttributeTierPriceInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeTierPriceUpdate">
+            <wsdl:documentation>Update product tier prices</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeTierPriceUpdateRequest" />
+            <wsdl:output message="typens:catalogProductAttributeTierPriceUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaCurrentStore">
+            <wsdl:documentation>Set/Get current store view</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeMediaCurrentStoreRequest" />
+            <wsdl:output message="typens:catalogProductAttributeMediaCurrentStoreResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaList">
+            <wsdl:documentation>Retrieve product image list</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeMediaListRequest" />
+            <wsdl:output message="typens:catalogProductAttributeMediaListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaInfo">
+            <wsdl:documentation>Retrieve product image data</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeMediaInfoRequest" />
+            <wsdl:output message="typens:catalogProductAttributeMediaInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaTypes">
+            <wsdl:documentation>Retrieve product image types</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeMediaTypesRequest" />
+            <wsdl:output message="typens:catalogProductAttributeMediaTypesResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaCreate">
+            <wsdl:documentation>Upload new product image</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeMediaCreateRequest" />
+            <wsdl:output message="typens:catalogProductAttributeMediaCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaUpdate">
+            <wsdl:documentation>Update product image</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeMediaUpdateRequest" />
+            <wsdl:output message="typens:catalogProductAttributeMediaUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaRemove">
+            <wsdl:documentation>Remove product image</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeMediaRemoveRequest" />
+            <wsdl:output message="typens:catalogProductAttributeMediaRemoveResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkList">
+            <wsdl:documentation>Retrieve linked products</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductLinkListRequest" />
+            <wsdl:output message="typens:catalogProductLinkListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkAssign">
+            <wsdl:documentation>Assign product link</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductLinkAssignRequest" />
+            <wsdl:output message="typens:catalogProductLinkAssignResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkUpdate">
+            <wsdl:documentation>Update product link</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductLinkUpdateRequest" />
+            <wsdl:output message="typens:catalogProductLinkUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkRemove">
+            <wsdl:documentation>Remove product link</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductLinkRemoveRequest" />
+            <wsdl:output message="typens:catalogProductLinkRemoveResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkTypes">
+            <wsdl:documentation>Retrieve product link types</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductLinkTypesRequest" />
+            <wsdl:output message="typens:catalogProductLinkTypesResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkAttributes">
+            <wsdl:documentation>Retrieve product link type attributes</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductLinkAttributesRequest" />
+            <wsdl:output message="typens:catalogProductLinkAttributesResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeCreate">
+            <wsdl:documentation>Create new attribute</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeCreateRequest" />
+            <wsdl:output message="typens:catalogProductAttributeCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeRemove">
+            <wsdl:documentation>Delete attribute</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductAttributeRemoveRequest" />
+            <wsdl:output message="typens:catalogProductAttributeRemoveResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="catalogCategoryCurrentStore">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryTree">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryLevel">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryMove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryDelete">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAssignedProducts">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAssignProduct">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryUpdateProduct">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryRemoveProduct">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCurrentStore">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductSetSpecialPrice">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductGetSpecialPrice">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductDelete">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeCurrentStore">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductListOfAdditionalAttributes">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeOptions">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionAdd">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionTypes">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueAdd">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductCustomOptionValueRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetAttributeAdd">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetAttributeRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetGroupAdd">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetGroupRename">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeSetGroupRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductTypeList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeTierPriceInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeTierPriceUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAttributeCurrentStore">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAttributeList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogCategoryAttributeOptions">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaCurrentStore">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaTypes">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeMediaRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkAssign">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkTypes">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductLinkAttributes">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductAttributeRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="{{var wsdl.name}}Service">
+        <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/Catalog/view/adminhtml/js/grouped-product.js b/app/code/core/Mage/Catalog/view/adminhtml/js/grouped-product.js
new file mode 100644
index 00000000000..950855a5f0a
--- /dev/null
+++ b/app/code/core/Mage/Catalog/view/adminhtml/js/grouped-product.js
@@ -0,0 +1,182 @@
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Catalog
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/*jshint browser:true jquery:true*/
+(function($) {
+    $.widget('mage.groupedProduct', {
+        _create: function () {
+            this.$grid = this.element.find('#grouped_grid');
+            this.$popup = this.element.find('#grouped_grid_popup');
+
+            this._bindDialog();
+            this._bindEventHandlers();
+            if (!$.isArray(this.options.gridData) || this.options.gridData.length) {
+                this._initGridWithData(this.options.gridData);
+            }
+            this._displayGridRow(this.options.associatedProductIds);
+            this._updatePopupGrid();
+            this._updateHiddenField(this.options.associatedProductIds);
+            this._sortGridByPosition();
+        },
+
+        _bindDialog: function () {
+            var widget = this;
+            $('#grouped-product-popup').dialog({
+                title: 'Add Products to Group',
+                autoOpen: false,
+                minWidth: 980,
+                modal: true,
+                resizable: true,
+                buttons: [{
+                    id: 'grouped-product-dialog-cancel-button',
+                    text: 'Cancel',
+                    click: function () {
+                        widget._updatePopupGrid();
+                        $(this).dialog('close');
+                    }
+                }, {
+                    id: 'grouped-product-dialog-apply-button',
+                    text: 'Apply Changes',
+                    'class': 'add',
+                    click: function () {
+                        var ids = widget._getSelectedIds();
+                        widget._displayGridRow(ids);
+                        widget._updateHiddenField(ids);
+                        $(this).dialog('close');
+                    }
+                }]
+            });
+        },
+
+        _bindEventHandlers: function () {
+            var widget = this;
+            $('#grouped-add-products').on('click', function () {
+                $('#grouped-product-popup').dialog('open');
+                return false;
+            });
+            this.$grid.on('click', '.product-delete button', function (event) {
+                $(this).closest('tr').hide().addClass('ignore-validate');
+                widget._updatePopupGrid();
+                widget._updateHiddenField(widget._getSelectedIds());
+                widget._updateGridVisibility();
+            });
+            this.$grid.on('change keyup', 'input[type="text"]', function (event) {
+                widget._updateHiddenField(widget._getSelectedIds());
+            });
+            this.options.grid.rowClickCallback = function () {};
+            this.options.gridPopup.rowClickCallback = function (grid, event) {
+                event.stopPropagation();
+                if (!this.rows || !this.rows.length) {
+                    return;
+                }
+                $(event.target).parent().find('td.selected-products input[type="checkbox"]').click();
+                return false;
+            };
+        },
+
+        updateRowsPositions: function () {
+            $.each(this.$grid.find('input[name="position"]'), function (index) {
+                $(this).val(index);
+            });
+            this._updateHiddenField(this._getSelectedIds());
+        },
+
+        _updateHiddenField: function (ids) {
+            var gridData = {}, widget = this;
+            $.each(this.$grid.find('input[name="entity_id"]'), function () {
+                var $idContainer = $(this),
+                    inArray = $.inArray($idContainer.val(), ids) !== -1;
+                if (inArray) {
+                    var data = {};
+                    $.each(widget.options.fieldsToSave, function (k, v) {
+                        data[v] = $idContainer.closest('tr').find('input[name="' + v + '"]').val();
+                    });
+                    gridData[$idContainer.val()] = data;
+                }
+            });
+            widget.options.$hiddenInput.val(JSON.stringify(gridData));
+        },
+
+        _displayGridRow: function (ids) {
+            var displayedRows = 0;
+            $.each(this.$grid.find('input[name="entity_id"]'), function () {
+                var $idContainer = $(this),
+                    inArray = $.inArray($idContainer.val(), ids) !== -1;
+                $idContainer.closest('tr').toggle(inArray).toggleClass('ignore-validate', !inArray);
+                if (inArray) {
+                    displayedRows++;
+                }
+            });
+            this._updateGridVisibility(displayedRows);
+        },
+
+        _initGridWithData: function (gridData) {
+            $.each(this.$grid.find('input[name="entity_id"]'), function () {
+                var $idContainer = $(this),
+                    id = $idContainer.val();
+                if (!gridData[id]) {
+                    return true;
+                }
+                $.each(gridData[id], function (fieldName, data) {
+                    $idContainer.closest('tr').find('input[name="' + fieldName + '"]').val(data);
+                });
+            });
+        },
+
+        _getSelectedIds: function () {
+            var ids = [];
+            $.each(this.$popup.find('.selected-products input[type="checkbox"]:checked'),
+                function () {
+                    ids.push($(this).val());
+                }
+            );
+            return ids;
+        },
+
+        _updatePopupGrid: function () {
+            var $popup = this.$popup;
+            $.each(this.$grid.find('input[name="entity_id"]'), function () {
+                var id = $(this).val();
+                $popup.find('input[type=checkbox][value="' + id + '"]')
+                    .prop({checked: !$(this).closest('tr').hasClass('ignore-validate')});
+            });
+        },
+
+        _sortGridByPosition: function () {
+            var rows = this.$grid.find('tbody tr');
+            rows.sort(function (a, b) {
+                var valueA = $(a).find('input[name="position"]').val(),
+                    valueB = $(b).find('input[name="position"]').val();
+                return (valueA < valueB) ? -1 : (valueA > valueB) ? 1 : 0;
+            });
+            this.$grid.find('tbody').html(rows);
+        },
+
+        _updateGridVisibility: function (showGrid) {
+            showGrid = showGrid || this.element.find('#grouped_grid_table tbody tr:visible').length > 0;
+            this.element.find('.grid-wrapper').toggle(showGrid);
+            this.element.find('.no-products-message').toggle(!showGrid);
+        }
+    });
+})(jQuery);
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/_files/adminhtml/default/basic/theme.xml b/app/code/core/Mage/Catalog/view/adminhtml/product/grouped/container.phtml
similarity index 66%
rename from dev/tests/integration/testsuite/Mage/Core/Block/_files/adminhtml/default/basic/theme.xml
rename to app/code/core/Mage/Catalog/view/adminhtml/product/grouped/container.phtml
index 5707aed823d..63f6c4426ba 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/_files/adminhtml/default/basic/theme.xml
+++ b/app/code/core/Mage/Catalog/view/adminhtml/product/grouped/container.phtml
@@ -1,4 +1,4 @@
-<!--
+<?php
 /**
  * Magento
  *
@@ -18,21 +18,21 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Magento
- * @package     Design
- * @subpackage  integration_tests
+ * @category    design
+ * @package     default_default
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
--->
-<design>
-    <package code="default">
-        <title>Default</title>
-        <theme version="2.0.0.0" code="basic">
-            <title>Default</title>
-            <requirements>
-                <magento_version from="2.0.0.0-dev1" to="*"/>
-            </requirements>
-        </theme>
-    </package>
-</design>
+ ?>
+
+<?php /* @var $this Mage_Catalog_Block_Product_Grouped_AssociatedProducts  */ ?>
+<div class="entry-edit" id="<?php echo $this->getId() ?>">
+    <div class="entry-edit-head">
+        <h4 class="icon-head head-edit-form fieldset-legend">
+            <?php echo $this->getTabLabel() ?>
+        </h4>
+    </div>
+    <fieldset>
+        <?php echo $this->getChildHtml()?>
+    </fieldset>
+</div>
diff --git a/app/code/core/Mage/Catalog/view/adminhtml/product/grouped/grouped.phtml b/app/code/core/Mage/Catalog/view/adminhtml/product/grouped/grouped.phtml
new file mode 100644
index 00000000000..65b13e5e548
--- /dev/null
+++ b/app/code/core/Mage/Catalog/view/adminhtml/product/grouped/grouped.phtml
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    design
+ * @package     default_default
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<div id="grouped-product-container">
+    <div class="no-products-message" style="display:block">
+        <?php echo Mage::helper('Mage_Catalog_Helper_Data')->__('There are no grouped products.')?>
+    </div>
+    <div class="grid-wrapper" style="display:none">
+<?php
+    /** @var $this Mage_Core_Block_Template */
+    /** @var $_gridBlock Mage_Catalog_Block_Product_Grouped_AssociatedProducts_Grid */
+    $_gridBlock = $this->getChildBlock('catalog.product.group.grid.container')
+        ->getChildBlock('catalog.product.group.grid');
+    $_gridPopupBlock = $this->getChildBlock('catalog.product.group.grid.popup.container')
+        ->getChildBlock('catalog.product.group.grid.popup');
+    $_gridPopupBlock->setRowClickCallback('function(){}');
+    /** @var $_helper Mage_Core_Helper_Data */
+    $_helper = $this->helper('Mage_Core_Helper_Data');
+    echo $this->getChildBlock('catalog.product.group.grid.container')->getChildHtml('catalog.product.group.grid');
+?>
+    </div>
+    <input type="hidden" name="<?php echo $_gridBlock->getHiddenInputName();?>"/>
+    <div id="grouped-product-popup" style="display:none">
+        <?php echo $this->getChildBlock('catalog.product.group.grid.popup.container')->getChildHtml('catalog.product.group.grid.popup');?>
+    </div>
+</div>
+<button id="grouped-add-products">Add Products to Group</button>
+<script type="text/javascript">
+jQuery(function($) {
+    head.js("<?php echo $this->getViewFileUrl('Mage_Catalog::js/grouped-product.js') ?>", function () {
+        $('#grouped-product-container').mage('groupedProduct', {
+            grid: window.<?php echo $_gridBlock->getJsObjectName() ?>,
+            gridData: <?php echo $_gridBlock->getAssociatedProducts()?>,
+            gridPopup: window.<?php echo $_gridPopupBlock->getJsObjectName() ?>,
+            $hiddenInput: $('#grouped-product-container input[name="<?php echo $_gridBlock->getHiddenInputName()?>"]'),
+            associatedProductIds: <?php echo $_gridBlock->getAssociatedProductIds()?>,
+            fieldsToSave: <?php echo $_helper->jsonEncode($_gridBlock->getFieldsToSave())?>
+        });
+    });
+});
+</script>
diff --git a/app/code/core/Mage/Catalog/view/adminhtml/product/product.css b/app/code/core/Mage/Catalog/view/adminhtml/product/product.css
index 7e2c060b86f..80613497138 100644
--- a/app/code/core/Mage/Catalog/view/adminhtml/product/product.css
+++ b/app/code/core/Mage/Catalog/view/adminhtml/product/product.css
@@ -853,6 +853,7 @@
 
 .ui-icon-grip-dotted-vertical {
     background-position: 0 -224px;
+    cursor: n-resize;
 }
 
 .ui-icon-grip-dotted-horizontal {
@@ -1053,3 +1054,11 @@
     filter: none;
     text-shadow: none;
 }
+#grouped-product-container .no-products-message {
+    border: #dadfe0 1px solid;
+    background: #fff;
+    margin: 0 30px 10px;
+    padding: 20px 40px;
+    text-align: center;
+    vertical-align: middle;
+}
diff --git a/app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php b/app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
index 053a895321b..574a19efc85 100644
--- a/app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
+++ b/app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
@@ -162,20 +162,34 @@ class Mage_CatalogInventory_Block_Adminhtml_Form_Field_Stock extends Varien_Data
     {
         return "
             <script>
-            //<![CDATA[
                 jQuery(function($) {
-                    var qty = $('#$quantityFieldId'),
-                        isInStock = $('#$inStockFieldId'),
-                        manageStock = $('#inventory_manage_stock').removeClass('disabled').removeAttr('disabled'),
-                        useConfigManageStock = $('#inventory_use_config_manage_stock');
+                    var qty = $('#{$quantityFieldId}'),
+                        productType = $('#type_id').val(),
+                        stockAvailabilityField = $('#{$inStockFieldId}'),
+                        manageStockField = $('#inventory_manage_stock'),
+                        useConfigManageStockField = $('#inventory_use_config_manage_stock');
 
                     var disabler = function() {
-                        if ('' === qty.val()) {
-                            isInStock.attr('disabled', 'disabled');
-                            manageStock.val(0);
+                        var hasVariation = $('#config_super_product-checkbox').is(':checked');
+                        if ((productType == 'configurable' && hasVariation)
+                            || productType == 'grouped'
+                            || productType == 'bundle'//@TODO move this check to Mage_Bundle after refactoring as widget
+                            || hasVariation
+                        ) {
+                            return;
+                        }
+                        var manageStockValue = (qty.val() === '') ? 0 : 1;
+                        if (manageStockValue) {
+                            stockAvailabilityField.prop('disabled', false);
                         } else {
-                            isInStock.removeAttr('disabled');
-                            manageStock.val(1);
+                            stockAvailabilityField.prop('disabled', true).val(0);
+                        }
+                        if (manageStockField.val() != manageStockValue) {
+                            if (useConfigManageStockField.val() == 1) {
+                                useConfigManageStockField.removeAttr('checked').val(0);
+                            }
+                            manageStockField.toggleClass('disabled', false).prop('disabled', false);
+                            manageStockField.val(manageStockValue);
                         }
                     };
 
@@ -212,7 +226,6 @@ class Mage_CatalogInventory_Block_Adminhtml_Form_Field_Stock extends Varien_Data
                     });
                     disabler();
                 });
-            //]]>
             </script>
         ";
     }
diff --git a/app/code/core/Mage/CatalogInventory/Model/Stock/Item/Api.php b/app/code/core/Mage/CatalogInventory/Model/Stock/Item/Api.php
new file mode 100644
index 00000000000..b43852cb546
--- /dev/null
+++ b/app/code/core/Mage/CatalogInventory/Model/Stock/Item/Api.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.
+ *
+ * @category    Mage
+ * @package     Mage_CatalogInventory
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog inventory api
+ *
+ * @category   Mage
+ * @package    Mage_CatalogInventory
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_CatalogInventory_Model_Stock_Item_Api extends Mage_Catalog_Model_Api_Resource
+{
+    public function __construct()
+    {
+        $this->_storeIdSessionField = 'product_store_id';
+    }
+
+    public function items($productIds)
+    {
+        if (!is_array($productIds)) {
+            $productIds = array($productIds);
+        }
+
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+
+        foreach ($productIds as &$productId) {
+            if ($newId = $product->getIdBySku($productId)) {
+                $productId = $newId;
+            }
+        }
+
+        $collection = Mage::getModel('Mage_Catalog_Model_Product')
+            ->getCollection()
+            ->setFlag('require_stock_items', true)
+            ->addFieldToFilter('entity_id', array('in'=>$productIds));
+
+        $result = array();
+
+        foreach ($collection as $product) {
+            if ($product->getStockItem()) {
+                $result[] = array(
+                    'product_id'    => $product->getId(),
+                    'sku'           => $product->getSku(),
+                    'qty'           => $product->getStockItem()->getQty(),
+                    'is_in_stock'   => $product->getStockItem()->getIsInStock()
+                );
+            }
+        }
+
+        return $result;
+    }
+} // Class Mage_CatalogInventory_Model_Stock_Item_Api End
diff --git a/app/code/core/Mage/CatalogInventory/Model/Stock/Item/Api/V2.php b/app/code/core/Mage/CatalogInventory/Model/Stock/Item/Api/V2.php
new file mode 100644
index 00000000000..54bc68c1b32
--- /dev/null
+++ b/app/code/core/Mage/CatalogInventory/Model/Stock/Item/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_CatalogInventory
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Catalog inventory api V2
+ *
+ * @category   Mage
+ * @package    Mage_CatalogInventory
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_CatalogInventory_Model_Stock_Item_Api_V2 extends Mage_CatalogInventory_Model_Stock_Item_Api
+{
+    public function update($productId, $data)
+    {
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+
+        if ($newId = $product->getIdBySku($productId)) {
+            $productId = $newId;
+        }
+
+        $product->setStoreId($this->_getStoreId())
+            ->load($productId);
+
+        if (!$product->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        if (!$stockData = $product->getStockData()) {
+            $stockData = array();
+        }
+
+        if (isset($data->qty)) {
+            $stockData['qty'] = $data->qty;
+        }
+
+        if (isset($data->is_in_stock)) {
+            $stockData['is_in_stock'] = $data->is_in_stock;
+        }
+
+        if (isset($data->manage_stock)) {
+            $stockData['manage_stock'] = $data->manage_stock;
+        }
+
+        if (isset($data->use_config_manage_stock)) {
+            $stockData['use_config_manage_stock'] = $data->use_config_manage_stock;
+        }
+
+        if (isset($data->use_config_backorders)) {
+            $stockData['use_config_backorders'] = $data->use_config_backorders;
+        }
+
+        if (isset($data->backorders)) {
+            $stockData['backorders'] = $data->backorders;
+        }
+
+        $product->setStockData($stockData);
+
+        try {
+            $product->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_updated', $e->getMessage());
+        }
+
+        return true;
+    }
+}
diff --git a/app/code/core/Mage/CatalogInventory/etc/api.xml b/app/code/core/Mage/CatalogInventory/etc/api.xml
new file mode 100644
index 00000000000..282d8192d20
--- /dev/null
+++ b/app/code/core/Mage/CatalogInventory/etc/api.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_CatalogInventory
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <cataloginventory_stock_item translate="title" module="Mage_CatalogInventory">
+                <model>Mage_CatalogInventory_Model_Stock_Item_Api</model>
+                <title>Inventory API</title>
+                <acl>cataloginventory</acl>
+                <methods>
+                    <list translate="title" module="Mage_CatalogInventory">
+                        <title>Retrieve stock data by product ids</title>
+                        <method>items</method>
+                        <acl>cataloginventory/info</acl>
+                    </list>
+                    <update translate="title" module="Mage_CatalogInventory">
+                        <title>Update product stock data</title>
+                        <acl>cataloginventory/update</acl>
+                    </update>
+                </methods>
+                <faults module="Mage_CatalogInventory">
+                    <not_exists>
+                        <code>101</code>
+                        <message>Product does not exist.</message>
+                    </not_exists>
+                    <not_updated>
+                        <code>102</code>
+                        <message>Product inventory is not updated. Details are in error message.</message>
+                    </not_updated>
+                </faults>
+            </cataloginventory_stock_item>
+        </resources>
+        <resources_alias>
+            <product_stock>cataloginventory_stock_item</product_stock>
+        </resources_alias>
+        <v2>
+            <resources_function_prefix>
+                <product_stock>catalogInventoryStockItem</product_stock>
+            </resources_function_prefix>
+        </v2>
+        <acl>
+            <resources>
+                <cataloginventory translate="title" module="Mage_CatalogInventory">
+                    <title>Catalog Inventory</title>
+                    <sort_order>4</sort_order>
+                    <update translate="title" module="Mage_CatalogInventory">
+                        <title>Update</title>
+                    </update>
+                    <info translate="title" module="Mage_CatalogInventory">
+                        <title>Retrieve stock data</title>
+                    </info>
+                </cataloginventory>
+            </resources>
+        </acl>
+    </api>
+</config>
diff --git a/app/code/core/Mage/CatalogInventory/etc/wsdl.xml b/app/code/core/Mage/CatalogInventory/etc/wsdl.xml
new file mode 100644
index 00000000000..6291e9cc039
--- /dev/null
+++ b/app/code/core/Mage/CatalogInventory/etc/wsdl.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
+    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
+            <complexType name="catalogInventoryStockItemEntity">
+                <all>
+                    <element name="product_id" type="xsd:string" minOccurs="0" />
+                    <element name="sku" type="xsd:string" minOccurs="0" />
+                    <element name="qty" type="xsd:string" minOccurs="0" />
+                    <element name="is_in_stock" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="catalogInventoryStockItemEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogInventoryStockItemEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogInventoryStockItemUpdateEntity">
+                <all>
+                    <element name="qty" type="xsd:string" minOccurs="0" />
+                    <element name="is_in_stock" type="xsd:int" minOccurs="0" />
+                    <element name="manage_stock" type="xsd:int" minOccurs="0" />
+                    <element name="use_config_manage_stock" type="xsd:int" minOccurs="0" />
+                    <element name="min_qty" type="xsd:int" minOccurs="0" />
+                    <element name="use_config_min_qty" type="xsd:int" minOccurs="0" />
+                    <element name="min_sale_qty" type="xsd:int" minOccurs="0" />
+                    <element name="use_config_min_sale_qty" type="xsd:int" minOccurs="0" />
+                    <element name="max_sale_qty" type="xsd:int" minOccurs="0" />
+                    <element name="use_config_max_sale_qty" type="xsd:int" minOccurs="0" />
+                    <element name="is_qty_decimal" type="xsd:int" minOccurs="0" />
+                    <element name="backorders" type="xsd:int" minOccurs="0" />
+                    <element name="use_config_backorders" type="xsd:int" minOccurs="0" />
+                    <element name="notify_stock_qty" type="xsd:int" minOccurs="0" />
+                    <element name="use_config_notify_stock_qty" type="xsd:int" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductCreateEntity">
+                <all>
+                    <element name="stock_data" type="typens:catalogInventoryStockItemUpdateEntity" minOccurs="0" />
+                </all>
+            </complexType>
+        </schema>
+    </types>
+    <message name="catalogInventoryStockItemListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="products" type="typens:ArrayOfString" />
+    </message>
+    <message name="catalogInventoryStockItemListResponse">
+        <part name="result" type="typens:catalogInventoryStockItemEntityArray" />
+    </message>
+    <message name="catalogInventoryStockItemUpdateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="product" type="xsd:string" />
+        <part name="data" type="typens:catalogInventoryStockItemUpdateEntity" />
+    </message>
+    <message name="catalogInventoryStockItemUpdateResponse">
+        <part name="result" type="xsd:int" />
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="catalogInventoryStockItemList">
+            <documentation>Retrieve stock data by product ids</documentation>
+            <input message="typens:catalogInventoryStockItemListRequest" />
+            <output message="typens:catalogInventoryStockItemListResponse" />
+        </operation>
+        <operation name="catalogInventoryStockItemUpdate">
+            <documentation>Update product stock data</documentation>
+            <input message="typens:catalogInventoryStockItemUpdateRequest" />
+            <output message="typens:catalogInventoryStockItemUpdateResponse" />
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="catalogInventoryStockItemList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="catalogInventoryStockItemUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/CatalogInventory/etc/wsi.xml b/app/code/core/Mage/CatalogInventory/etc/wsi.xml
new file mode 100644
index 00000000000..6812d85cb05
--- /dev/null
+++ b/app/code/core/Mage/CatalogInventory/etc/wsi.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="catalogInventoryStockItemEntity">
+                <xsd:sequence>
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_in_stock" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogInventoryStockItemEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogInventoryStockItemEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogInventoryStockItemUpdateEntity">
+                <xsd:sequence>
+                    <xsd:element name="qty" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_in_stock" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="manage_stock" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="use_config_manage_stock" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="min_qty" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="use_config_min_qty" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="min_sale_qty" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="use_config_min_sale_qty" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="max_sale_qty" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="use_config_max_sale_qty" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="is_qty_decimal" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="backorders" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="use_config_backorders" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="notify_stock_qty" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="use_config_notify_stock_qty" type="xsd:int" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductCreateEntity">
+                <xsd:sequence>
+                    <xsd:element name="stock_data" type="typens:catalogInventoryStockItemUpdateEntity" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+
+
+            <xsd:element name="catalogInventoryStockItemListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productIds" type="typens:ArrayOfString" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogInventoryStockItemListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogInventoryStockItemEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogInventoryStockItemUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogInventoryStockItemUpdateEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogInventoryStockItemUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="catalogInventoryStockItemListRequest">
+        <wsdl:part name="parameters" element="typens:catalogInventoryStockItemListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogInventoryStockItemListResponse">
+        <wsdl:part name="parameters" element="typens:catalogInventoryStockItemListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogInventoryStockItemUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogInventoryStockItemUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogInventoryStockItemUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogInventoryStockItemUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="catalogInventoryStockItemList">
+            <wsdl:documentation>Retrieve stock data by product ids</wsdl:documentation>
+            <wsdl:input message="typens:catalogInventoryStockItemListRequest" />
+            <wsdl:output message="typens:catalogInventoryStockItemListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogInventoryStockItemUpdate">
+            <wsdl:documentation>Update product stock data</wsdl:documentation>
+            <wsdl:input message="typens:catalogInventoryStockItemUpdateRequest" />
+            <wsdl:output message="typens:catalogInventoryStockItemUpdateResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="catalogInventoryStockItemList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogInventoryStockItemUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="{{var wsdl.name}}Service">
+        <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/CatalogSearch/view/frontend/form.mini.phtml b/app/code/core/Mage/CatalogSearch/view/frontend/form.mini.phtml
index 19d2cc05b88..e5de26bf743 100644
--- a/app/code/core/Mage/CatalogSearch/view/frontend/form.mini.phtml
+++ b/app/code/core/Mage/CatalogSearch/view/frontend/form.mini.phtml
@@ -25,6 +25,7 @@
  */
 ?>
 <?php
+/** @var $this Mage_Core_Block_Template */
 /** @var $helper Mage_CatalogSearch_Helper_Data */
 $helper = $this->helper('Mage_CatalogSearch_Helper_Data');
 ?>
diff --git a/app/code/core/Mage/Checkout/Model/Api/Resource.php b/app/code/core/Mage/Checkout/Model/Api/Resource.php
new file mode 100644
index 00000000000..48c9b3784a3
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Api/Resource.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.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Checkout api resource
+ *
+ * @category   Mage
+ * @package    Mage_Checkout
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Checkout_Model_Api_Resource extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Attributes map array per entity type
+     *
+     * @var array
+     */
+    protected $_attributesMap = array(
+        'global' => array(),
+    );
+
+    /**
+     * Default ignored attribute codes per entity type
+     *
+     * @var array
+     */
+    protected $_ignoredAttributeCodes = array(
+        'global' => array('entity_id', 'attribute_set_id', 'entity_type_id')
+    );
+
+    /**
+     * Field name in session for saving store id
+     *
+     * @var string
+     */
+    protected $_storeIdSessionField = 'store_id';
+
+    /** @var Mage_Api_Helper_Data */
+    protected $_apiHelper;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param Mage_Api_Helper_Data $apiHelper
+     */
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        $this->_apiHelper = $apiHelper;
+    }
+
+    /**
+     * Check if quote already exist with provided quoteId for creating
+     *
+     * @param int $quoteId
+     * @return bool
+     */
+    protected function _isQuoteExist($quoteId)
+    {
+        if (empty($quoteId)) {
+            return false;
+        }
+
+        try {
+            $quote = $this->_getQuote($quoteId);
+        } catch (Mage_Api_Exception $e) {
+            return false;
+        }
+
+        if (!is_null($quote->getId())) {
+            $this->_fault('quote_already_exist');
+        }
+
+        return false;
+    }
+
+    /**
+     * Retrieves store id from store code, if no store id specified,
+     * it use set session or admin store
+     *
+     * @param string|int $store
+     * @return int
+     */
+    protected function _getStoreId($store = null)
+    {
+        if (is_null($store)) {
+            $store = ($this->_getSession()->hasData($this->_storeIdSessionField)
+                ? $this->_getSession()->getData($this->_storeIdSessionField) : 0);
+        }
+
+        try {
+            $storeId = Mage::app()->getStore($store)->getId();
+
+        } catch (Mage_Core_Model_Store_Exception $e) {
+            $this->_fault('store_not_exists');
+        }
+
+        return $storeId;
+    }
+
+    /**
+     * Retrieves quote by quote identifier and store code or by quote identifier
+     *
+     * @param int $quoteId
+     * @param string|int $store
+     * @return Mage_Sales_Model_Quote
+     */
+    protected function _getQuote($quoteId, $store = null)
+    {
+        /** @var $quote Mage_Sales_Model_Quote */
+        $quote = Mage::getModel('Mage_Sales_Model_Quote');
+
+        if (!(is_string($store) || is_integer($store))) {
+            $quote->loadByIdWithoutStore($quoteId);
+        } else {
+            $storeId = $this->_getStoreId($store);
+
+            $quote->setStoreId($storeId)
+                ->load($quoteId);
+        }
+        if (is_null($quote->getId())) {
+            $this->_fault('quote_not_exists');
+        }
+
+        return $quote;
+    }
+
+    /**
+     * Get store identifier by quote identifier
+     *
+     * @param int $quoteId
+     * @return int
+     */
+    protected function _getStoreIdFromQuote($quoteId)
+    {
+        /** @var $quote Mage_Sales_Model_Quote */
+        $quote = Mage::getModel('Mage_Sales_Model_Quote')
+            ->loadByIdWithoutStore($quoteId);
+
+        return $quote->getStoreId();
+    }
+
+    /**
+     * Update attributes for entity
+     *
+     * @param array $data
+     * @param Mage_Core_Model_Abstract $object
+     * @param string $type
+     * @param array|null $attributes
+     * @return Mage_Checkout_Model_Api_Resource
+     */
+    protected function _updateAttributes($data, $object, $type, array $attributes = null)
+    {
+        foreach ($data as $attribute => $value) {
+            if ($this->_apiHelper->isAttributeAllowed($attribute, $type, $this->_ignoredAttributeCodes, $attributes)) {
+                $object->setData($attribute, $value);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Retrieve entity attributes values
+     *
+     * @param Mage_Core_Model_Abstract $object
+     * @param string $type
+     * @param array $attributes
+     * @return Mage_Checkout_Model_Api_Resource
+     */
+    protected function _getAttributes($object, $type, array $attributes = null)
+    {
+        $result = array();
+        if (!is_object($object)) {
+            return $result;
+        }
+        foreach ($object->getData() as $attribute => $value) {
+            if (is_object($value)) {
+                continue;
+            }
+
+            if ($this->_apiHelper->isAttributeAllowed($attribute, $type, $this->_ignoredAttributeCodes, $attributes)) {
+                $result[$attribute] = $value;
+            }
+        }
+        if (isset($this->_attributesMap[$type])) {
+            foreach ($this->_attributesMap[$type] as $alias => $attributeCode) {
+                $result[$alias] = $object->getData($attributeCode);
+            }
+        }
+        foreach ($this->_attributesMap['global'] as $alias => $attributeCode) {
+            $result[$alias] = $object->getData($attributeCode);
+        }
+        return $result;
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Api/Resource/Customer.php b/app/code/core/Mage/Checkout/Model/Api/Resource/Customer.php
new file mode 100644
index 00000000000..34a314d3f6f
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Api/Resource/Customer.php
@@ -0,0 +1,213 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Checkout api resource for Customer
+ *
+ * @category   Mage
+ * @package    Mage_Checkout
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Checkout_Model_Api_Resource_Customer extends Mage_Checkout_Model_Api_Resource
+{
+    /**
+     * Customer address types
+     */
+    const ADDRESS_BILLING    = Mage_Sales_Model_Quote_Address::TYPE_BILLING;
+    const ADDRESS_SHIPPING   = Mage_Sales_Model_Quote_Address::TYPE_SHIPPING;
+
+    /**
+     * Customer checkout types
+     */
+     const MODE_CUSTOMER = Mage_Checkout_Model_Type_Onepage::METHOD_CUSTOMER;
+     const MODE_REGISTER = Mage_Checkout_Model_Type_Onepage::METHOD_REGISTER;
+     const MODE_GUEST    = Mage_Checkout_Model_Type_Onepage::METHOD_GUEST;
+
+
+    /**
+     *
+     */
+    protected function _getCustomer($customerId)
+    {
+        /** @var $customer Mage_Customer_Model_Customer */
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')
+            ->load($customerId);
+        if (!$customer->getId()) {
+            $this->_fault('customer_not_exists');
+        }
+
+        return $customer;
+    }
+
+    /**
+     * Get customer address by identifier
+     *
+     * @param   int $addressId
+     * @return  Mage_Customer_Model_Address
+     */
+    protected function _getCustomerAddress($addressId)
+    {
+        $address = Mage::getModel('Mage_Customer_Model_Address')->load((int)$addressId);
+        if (is_null($address->getId())) {
+            $this->_fault('invalid_address_id');
+        }
+
+        $address->explodeStreetAddress();
+        if ($address->getRegionId()) {
+            $address->setRegion($address->getRegionId());
+        }
+        return $address;
+    }
+
+    /**
+     * @param Mage_Sales_Model_Quote $quote
+     * @return bool
+     */
+    public function prepareCustomerForQuote(Mage_Sales_Model_Quote $quote)
+    {
+        $isNewCustomer = false;
+        switch ($quote->getCheckoutMethod()) {
+        case self::MODE_GUEST:
+            $this->_prepareGuestQuote($quote);
+            break;
+        case self::MODE_REGISTER:
+            $this->_prepareNewCustomerQuote($quote);
+            $isNewCustomer = true;
+            break;
+        default:
+            $this->_prepareCustomerQuote($quote);
+            break;
+        }
+
+        return $isNewCustomer;
+    }
+
+    /**
+     * Prepare quote for guest checkout order submit
+     *
+     * @param Mage_Sales_Model_Quote $quote
+     * @return Mage_Checkout_Model_Api_Resource_Customer
+     */
+    protected function _prepareGuestQuote(Mage_Sales_Model_Quote $quote)
+    {
+        $quote->setCustomerId(null)
+            ->setCustomerEmail($quote->getBillingAddress()->getEmail())
+            ->setCustomerIsGuest(true)
+            ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
+        return $this;
+    }
+
+    /**
+     * Prepare quote for customer registration and customer order submit
+     *
+     * @param Mage_Sales_Model_Quote $quote
+     * @return Mage_Checkout_Model_Api_Resource_Customer
+     */
+    protected function _prepareNewCustomerQuote(Mage_Sales_Model_Quote $quote)
+    {
+        $billing    = $quote->getBillingAddress();
+        $shipping   = $quote->isVirtual() ? null : $quote->getShippingAddress();
+
+        //$customer = Mage::getModel('Mage_Customer_Model_Customer');
+        $customer = $quote->getCustomer();
+        /* @var $customer Mage_Customer_Model_Customer */
+        $customerBilling = $billing->exportCustomerAddress();
+        $customer->addAddress($customerBilling);
+        $billing->setCustomerAddress($customerBilling);
+        $customerBilling->setIsDefaultBilling(true);
+        if ($shipping && !$shipping->getSameAsBilling()) {
+            $customerShipping = $shipping->exportCustomerAddress();
+            $customer->addAddress($customerShipping);
+            $shipping->setCustomerAddress($customerShipping);
+            $customerShipping->setIsDefaultShipping(true);
+        } else {
+            $customerBilling->setIsDefaultShipping(true);
+        }
+
+        Mage::helper('Mage_Core_Helper_Data')->copyFieldset('checkout_onepage_quote', 'to_customer', $quote, $customer);
+        $customer->setPassword($customer->decryptPassword($quote->getPasswordHash()));
+        $customer->setPasswordHash($customer->hashPassword($customer->getPassword()));
+        $quote->setCustomer($customer)
+            ->setCustomerId(true);
+
+        return $this;
+    }
+
+    /**
+     * Prepare quote for customer order submit
+     *
+     * @param Mage_Sales_Model_Quote $quote
+     * @return Mage_Checkout_Model_Api_Resource_Customer
+     */
+    protected function _prepareCustomerQuote(Mage_Sales_Model_Quote $quote)
+    {
+        $billing    = $quote->getBillingAddress();
+        $shipping   = $quote->isVirtual() ? null : $quote->getShippingAddress();
+
+        $customer = $quote->getCustomer();
+        if (!$billing->getCustomerId() || $billing->getSaveInAddressBook()) {
+            $customerBilling = $billing->exportCustomerAddress();
+            $customer->addAddress($customerBilling);
+            $billing->setCustomerAddress($customerBilling);
+        }
+        if ($shipping && ((!$shipping->getCustomerId() && !$shipping->getSameAsBilling())
+            || (!$shipping->getSameAsBilling() && $shipping->getSaveInAddressBook()))) {
+            $customerShipping = $shipping->exportCustomerAddress();
+            $customer->addAddress($customerShipping);
+            $shipping->setCustomerAddress($customerShipping);
+        }
+
+        if (isset($customerBilling) && !$customer->getDefaultBilling()) {
+            $customerBilling->setIsDefaultBilling(true);
+        }
+        if ($shipping && isset($customerShipping) && !$customer->getDefaultShipping()) {
+            $customerShipping->setIsDefaultShipping(true);
+        } else if (isset($customerBilling) && !$customer->getDefaultShipping()) {
+            $customerBilling->setIsDefaultShipping(true);
+        }
+        $quote->setCustomer($customer);
+
+        return $this;
+    }
+
+    /**
+     * Involve new customer to system
+     *
+     * @param Mage_Sales_Model_Quote $quote
+     * @return Mage_Checkout_Model_Api_Resource_Customer
+     */
+    public function involveNewCustomer(Mage_Sales_Model_Quote $quote)
+    {
+        $customer = $quote->getCustomer();
+        if ($customer->isConfirmationRequired()) {
+            $customer->sendNewAccountEmail('confirmation');
+        } else {
+            $customer->sendNewAccountEmail();
+        }
+
+        return $this;
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Api/Resource/Product.php b/app/code/core/Mage/Checkout/Model/Api/Resource/Product.php
new file mode 100644
index 00000000000..c46cc692935
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Api/Resource/Product.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * API Resource class for product
+ */
+class Mage_Checkout_Model_Api_Resource_Product extends Mage_Checkout_Model_Api_Resource
+{
+    /**
+     * Default ignored attribute codes
+     *
+     * @var array
+     */
+    protected $_ignoredAttributeCodes = array('entity_id', 'attribute_set_id', 'entity_type_id');
+
+    /**
+     * Return loaded product instance
+     *
+     * @param  int|string $productId (SKU or ID)
+     * @param  int|string $store
+     * @param  string $identifierType
+     * @return Mage_Catalog_Model_Product
+     */
+    protected function _getProduct($productId, $store = null, $identifierType = null)
+    {
+        $product = Mage::helper('Mage_Catalog_Helper_Product')->getProduct($productId,
+                        $this->_getStoreId($store),
+                        $identifierType
+        );
+        return $product;
+    }
+
+    /**
+     * Get request for product add to cart procedure
+     *
+     * @param   mixed $requestInfo
+     * @return  Varien_Object
+     */
+    protected function _getProductRequest($requestInfo)
+    {
+        if ($requestInfo instanceof Varien_Object) {
+            $request = $requestInfo;
+        } elseif (is_numeric($requestInfo)) {
+            $request = new Varien_Object();
+            $request->setQty($requestInfo);
+        } else {
+            $request = new Varien_Object($requestInfo);
+        }
+
+        if (!$request->hasQty()) {
+            $request->setQty(1);
+        }
+        return $request;
+    }
+
+    /**
+     * Get QuoteItem by Product and request info
+     *
+     * @param Mage_Sales_Model_Quote $quote
+     * @param Mage_Catalog_Model_Product $product
+     * @param Varien_Object $requestInfo
+     * @return Mage_Sales_Model_Quote_Item
+     * @throw Mage_Core_Exception
+     */
+    protected function _getQuoteItemByProduct(Mage_Sales_Model_Quote $quote,
+                            Mage_Catalog_Model_Product $product,
+                            Varien_Object $requestInfo)
+    {
+        $cartCandidates = $product->getTypeInstance()
+                        ->prepareForCartAdvanced($requestInfo,
+                                $product,
+                                Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_FULL
+        );
+
+        /**
+         * Error message
+         */
+        if (is_string($cartCandidates)) {
+            throw Mage::throwException($cartCandidates);
+        }
+
+        /**
+         * If prepare process return one object
+         */
+        if (!is_array($cartCandidates)) {
+            $cartCandidates = array($cartCandidates);
+        }
+
+        /** @var $item Mage_Sales_Model_Quote_Item */
+        $item = null;
+        foreach ($cartCandidates as $candidate) {
+            if ($candidate->getParentProductId()) {
+                continue;
+            }
+
+            $item = $quote->getItemByProduct($candidate);
+        }
+
+        if (is_null($item)) {
+            $item = Mage::getModel('Mage_Sales_Model_Quote_Item');
+        }
+
+        return $item;
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Api.php b/app/code/core/Mage/Checkout/Model/Cart/Api.php
new file mode 100644
index 00000000000..7eb79c58f64
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Api.php
@@ -0,0 +1,366 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Checkout_Model_Cart_Api extends Mage_Checkout_Model_Api_Resource
+{
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        parent::__construct($apiHelper);
+        $this->_storeIdSessionField = "cart_store_id";
+        $this->_attributesMap['quote'] = array('quote_id' => 'entity_id');
+        $this->_attributesMap['quote_customer'] = array('customer_id' => 'entity_id');
+        $this->_attributesMap['quote_address'] = array('address_id' => 'entity_id');
+        $this->_attributesMap['quote_payment'] = array('payment_id' => 'entity_id');
+    }
+
+    /**
+     * Prepare payment data for futher usage
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function _preparePaymentData($data)
+    {
+        if (!(is_array($data) && is_null($data[0]))) {
+            return array();
+        }
+
+        return $data;
+    }
+
+    /**
+     * Create new quote for shopping cart
+     *
+     * @param int|string $store
+     * @return int
+     */
+    public function create($store = null)
+    {
+        $storeId = $this->_getStoreId($store);
+
+        try {
+            /*@var $quote Mage_Sales_Model_Quote*/
+            $quote = Mage::getModel('Mage_Sales_Model_Quote');
+            $quote->setStoreId($storeId)
+                    ->setIsActive(false)
+                    ->setIsMultiShipping(false)
+                    ->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('create_quote_fault', $e->getMessage());
+        }
+        return (int) $quote->getId();
+    }
+
+    /**
+     * Retrieve full information about quote
+     *
+     * @param  $quoteId
+     * @param  $store
+     * @return array
+     */
+    public function info($quoteId, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+
+        if ($quote->getGiftMessageId() > 0) {
+            $quote->setGiftMessage(
+                Mage::getSingleton('Mage_GiftMessage_Model_Message')->load($quote->getGiftMessageId())->getMessage()
+            );
+        }
+
+        $result = $this->_getAttributes($quote, 'quote');
+        $result['shipping_address'] = $this->_getAttributes($quote->getShippingAddress(), 'quote_address');
+        $result['billing_address'] = $this->_getAttributes($quote->getBillingAddress(), 'quote_address');
+        $result['items'] = array();
+
+        foreach ($quote->getAllItems() as $item) {
+            if ($item->getGiftMessageId() > 0) {
+                $item->setGiftMessage(
+                    Mage::getSingleton('Mage_GiftMessage_Model_Message')->load($item->getGiftMessageId())->getMessage()
+                );
+            }
+
+            $result['items'][] = $this->_getAttributes($item, 'quote_item');
+        }
+
+        $result['payment'] = $this->_getAttributes($quote->getPayment(), 'quote_payment');
+
+        return $result;
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $store
+     * @return void
+     */
+    public function totals($quoteId, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+
+        $totals = $quote->getTotals();
+
+        $totalsResult = array();
+        foreach ($totals as $total) {
+            $totalsResult[] = array(
+                "title" => $total->getTitle(),
+                "amount" => $total->getValue()
+            );
+        }
+        return $totalsResult;
+    }
+
+    /**
+     * Check wether we can use this payment method with current quote
+     *
+     * @param Mage_Payment_Model_Method_Abstract $method
+     * @param Mage_Sales_Model_Quote $quote
+     * @return bool
+     */
+    protected function _canUsePaymentMethod($method, $quote)
+    {
+        if (!($method->isGateway() || $method->canUseInternal())) {
+            return false;
+        }
+
+        if (!$method->canUseForCountry($quote->getBillingAddress()->getCountry())) {
+            return false;
+        }
+
+        if (!$method->canUseForCurrency(Mage::app()->getStore($quote->getStoreId())->getBaseCurrencyCode())) {
+            return false;
+        }
+
+        /**
+         * Checking for min/max order total for assigned payment method
+         */
+        $total = $quote->getBaseGrandTotal();
+        $minTotal = $method->getConfigData('min_order_total');
+        $maxTotal = $method->getConfigData('max_order_total');
+
+        if ((!empty($minTotal) && ($total < $minTotal)) || (!empty($maxTotal) && ($total > $maxTotal))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Create an order from the shopping cart (quote)
+     *
+     * @param int $quoteId
+     * @param string|int $store
+     * @param array $agreements
+     * @return string
+     */
+    public function createOrder($quoteId, $store = null, $agreements = null)
+    {
+        $this->_checkAgreement($agreements);
+        $quote = $this->_getQuote($quoteId, $store);
+        $orderId = $this->_placeOrder($quote);
+        return $orderId;
+    }
+
+    /**
+     * Create an order from the shopping cart (quote) with ability to set payment method
+     *
+     * @param int $quoteId
+     * @param string|int $store
+     * @param array $agreements
+     * @param array $paymentData
+     * @return string
+     */
+    public function createOrderWithPayment($quoteId, $store = null, $agreements = null, $paymentData = null)
+    {
+        $this->_checkAgreement($agreements);
+        $quote = $this->_getQuote($quoteId, $store);
+        $this->_setPayment($quote, $store, $paymentData);
+        $orderId = $this->_placeOrder($quote);
+        return $orderId;
+    }
+
+    /**
+     * Convert quote to order and return order increment id
+     *
+     * @param Mage_Sales_Model_Quote $quote
+     * @return string
+     */
+    protected function _placeOrder($quote)
+    {
+        if ($quote->getIsMultiShipping()) {
+            $this->_fault('invalid_checkout_type');
+        }
+        if ($quote->getCheckoutMethod() == Mage_Checkout_Model_Api_Resource_Customer::MODE_GUEST
+            && !Mage::helper('Mage_Checkout_Helper_Data')->isAllowedGuestCheckout($quote, $quote->getStoreId())
+        ) {
+            $this->_fault('guest_checkout_is_not_enabled');
+        }
+
+        Mage::getConfig()->setCurrentAreaCode('adminhtml');
+        /** @var $customerResource Mage_Checkout_Model_Api_Resource_Customer */
+        $customerResource = Mage::getModel("Mage_Checkout_Model_Api_Resource_Customer");
+        $isNewCustomer = $customerResource->prepareCustomerForQuote($quote);
+
+        try {
+            $quote->collectTotals();
+            /** @var $service Mage_Sales_Model_Service_Quote */
+            $service = Mage::getModel('Mage_Sales_Model_Service_Quote', array('quote' => $quote));
+            $service->submitAll();
+
+            if ($isNewCustomer) {
+                try {
+                    $customerResource->involveNewCustomer($quote);
+                } catch (Exception $e) {
+                    Mage::logException($e);
+                }
+            }
+
+            $order = $service->getOrder();
+            if ($order) {
+                Mage::dispatchEvent(
+                    'checkout_type_onepage_save_order_after',
+                    array('order' => $order, 'quote' => $quote)
+                );
+
+                try {
+                    $order->sendNewOrderEmail();
+                } catch (Exception $e) {
+                    Mage::logException($e);
+                }
+            }
+
+            Mage::dispatchEvent('checkout_submit_all_after', array('order' => $order, 'quote' => $quote));
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('create_order_fault', $e->getMessage());
+        }
+
+        return $order->getIncrementId();
+    }
+
+    /**
+     * Set payment data
+     *
+     * @param Mage_Sales_Model_Quote $quote
+     * @param string|int $store
+     * @param array $paymentData
+     */
+    protected function _setPayment($quote, $store = null, $paymentData = null)
+    {
+        if ($paymentData !== null) {
+            $paymentData = $this->_preparePaymentData($paymentData);
+            if (empty($paymentData)) {
+                $this->_fault('payment_method_empty');
+            }
+
+            if ($quote->isVirtual()) {
+                // check if billing address is set
+                if (is_null($quote->getBillingAddress()->getId())) {
+                    $this->_fault('billing_address_is_not_set');
+                }
+                $quote->getBillingAddress()
+                    ->setPaymentMethod(isset($paymentData['method']) ? $paymentData['method'] : null);
+            } else {
+                // check if shipping address is set
+                if (is_null($quote->getShippingAddress()->getId()) ) {
+                    $this->_fault('shipping_address_is_not_set');
+                }
+                $quote->getShippingAddress()
+                    ->setPaymentMethod(isset($paymentData['method']) ? $paymentData['method'] : null);
+            }
+
+            if (!$quote->isVirtual() && $quote->getShippingAddress()) {
+                $quote->getShippingAddress()->setCollectShippingRates(true);
+            }
+
+            $total = $quote->getBaseSubtotal();
+            $methods = Mage::helper('Mage_Payment_Helper_Data')->getStoreMethods($store, $quote);
+            foreach ($methods as $key => $method) {
+                if ($method->getCode() == $paymentData['method']) {
+                    /** @var $method Mage_Payment_Model_Method_Abstract */
+                    if (!($this->_canUsePaymentMethod($method, $quote) && ($total != 0 || $method->getCode() == 'free'
+                        || ($quote->hasRecurringItems() && $method->canManageRecurringProfiles())))
+                    ) {
+                        $this->_fault('method_not_allowed');
+                    }
+                }
+            }
+            try {
+                $quote->getPayment()->importData($paymentData);
+                $quote->setTotalsCollectedFlag(false)->collectTotals();
+            } catch (Mage_Core_Exception $e) {
+                $this->_fault('payment_method_is_not_set', $e->getMessage());
+            }
+        }
+    }
+
+    /**
+     * Check required billing agreements
+     *
+     * @param array $agreements
+     */
+    protected function _checkAgreement($agreements = null)
+    {
+        $requiredAgreements = Mage::helper('Mage_Checkout_Helper_Data')->getRequiredAgreementIds();
+        if (!empty($requiredAgreements)) {
+            $diff = array_diff($agreements, $requiredAgreements);
+            if (!empty($diff)) {
+                $this->_fault('required_agreements_are_not_all');
+            }
+        }
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $store
+     * @return array
+     */
+    public function licenseAgreement($quoteId, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+        $storeId = $quote->getStoreId();
+
+        $agreements = array();
+        if (Mage::getStoreConfigFlag('checkout/options/enable_agreements')) {
+            $agreementsCollection = Mage::getModel('Mage_Checkout_Model_Agreement')->getCollection()
+                    ->addStoreFilter($storeId)
+                    ->addFieldToFilter('is_active', 1);
+
+            foreach ($agreementsCollection as $_a) {
+                /** @var $_a  Mage_Checkout_Model_Agreement */
+                $agreements[] = $this->_getAttributes($_a, "quote_agreement");
+            }
+        }
+
+        return $agreements;
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Api/V2.php b/app/code/core/Mage/Checkout/Model/Cart/Api/V2.php
new file mode 100644
index 00000000000..0b964922b2c
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Api/V2.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart model
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Checkout_Model_Cart_Api_V2 extends Mage_Checkout_Model_Cart_Api
+{
+    /**
+     * Prepare payment data for further usage
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function _preparePaymentData($data)
+    {
+        $data = get_object_vars($data);
+        return parent::_preparePaymentData($data);
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Coupon/Api.php b/app/code/core/Mage/Checkout/Model/Cart/Coupon/Api.php
new file mode 100644
index 00000000000..32d7ad1981c
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Coupon/Api.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.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Checkout_Model_Cart_Coupon_Api extends Mage_Checkout_Model_Api_Resource
+{
+    /**
+     * @param  $quoteId
+     * @param  $couponCode
+     * @param  $store
+     * @return bool
+     */
+    public function add($quoteId, $couponCode, $store = null)
+    {
+        return $this->_applyCoupon($quoteId, $couponCode, $store = null);
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $store
+     * @return bool
+     */
+    public function remove($quoteId, $store = null)
+    {
+        $couponCode = '';
+        return $this->_applyCoupon($quoteId, $couponCode, $store);
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $couponCode
+     * @param  $store
+     * @return bool
+     */
+    protected function _applyCoupon($quoteId, $couponCode, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+
+        if (!$quote->getItemsCount()) {
+            $this->_fault('quote_is_empty');
+        }
+
+        $oldCouponCode = $quote->getCouponCode();
+        if (!strlen($couponCode) && !strlen($oldCouponCode)) {
+            return false;
+        }
+
+        try {
+            $quote->getShippingAddress()->setCollectShippingRates(true);
+            $quote->setCouponCode(strlen($couponCode) ? $couponCode : '')
+                ->collectTotals()
+                ->save();
+        } catch (Exception $e) {
+            $this->_fault("cannot_apply_coupon_code", $e->getMessage());
+        }
+
+        if ($couponCode) {
+            if (!$couponCode == $quote->getCouponCode()) {
+                $this->_fault('coupon_code_is_not_valid');
+            }
+        }
+
+        return true;
+    }
+
+
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Coupon/Api/V2.php b/app/code/core/Mage/Checkout/Model/Cart/Coupon/Api/V2.php
new file mode 100644
index 00000000000..2867f6ec043
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Coupon/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Checkout_Model_Cart_Coupon_Api_V2 extends Mage_Checkout_Model_Cart_Coupon_Api
+{
+
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Customer/Api.php b/app/code/core/Mage/Checkout/Model/Cart/Customer/Api.php
new file mode 100644
index 00000000000..e5248395e02
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Customer/Api.php
@@ -0,0 +1,232 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api for customer data
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Checkout_Model_Cart_Customer_Api extends Mage_Checkout_Model_Api_Resource_Customer
+{
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        parent::__construct($apiHelper);
+        $this->_storeIdSessionField = "cart_store_id";
+
+        $this->_attributesMap['quote'] = array('quote_id' => 'entity_id');
+        $this->_attributesMap['quote_customer'] = array('customer_id' => 'entity_id');
+        $this->_attributesMap['quote_address'] = array('address_id' => 'entity_id');
+    }
+
+    /**
+     * Set customer for shopping cart
+     *
+     * @param int $quoteId
+     * @param array|object $customerData
+     * @param int | string $store
+     * @return int
+     */
+    public function set($quoteId, $customerData, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+
+        $customerData = $this->_prepareCustomerData($customerData);
+        if (!isset($customerData['mode'])) {
+            $this->_fault('customer_mode_is_unknown');
+        }
+
+        switch ($customerData['mode']) {
+            case self::MODE_CUSTOMER:
+                /** @var Mage_Customer_Model_Customer $customer */
+                $customer = $this->_getCustomer($customerData['entity_id']);
+                $customer->setMode(self::MODE_CUSTOMER);
+                break;
+            case self::MODE_REGISTER:
+            case self::MODE_GUEST:
+                /** @var Mage_Customer_Model_Customer $customer */
+                $customer = Mage::getModel('Mage_Customer_Model_Customer')->setData($customerData);
+
+                if ($customer->getMode() == self::MODE_GUEST) {
+                    $password = $customer->generatePassword();
+                    $customer->setPassword($password)
+                        ->setConfirmation($password);
+                }
+
+                $isCustomerValid = $customer->validate();
+                if ($isCustomerValid !== true && is_array($isCustomerValid)) {
+                    $this->_fault('customer_data_invalid', implode(PHP_EOL, $isCustomerValid));
+                }
+                break;
+        }
+
+        try {
+            $quote->setCustomer($customer)
+                ->setCheckoutMethod($customer->getMode())
+                ->setPasswordHash($customer->encryptPassword($customer->getPassword()))
+                ->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('customer_not_set', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * @param int $quoteId
+     * @param array of array|object $customerAddressData
+     * @param int|string $store
+     * @return int
+     */
+    public function setAddresses($quoteId, $customerAddressData, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+
+        $customerAddressData = $this->_prepareCustomerAddressData($customerAddressData);
+        if (is_null($customerAddressData)) {
+            $this->_fault('customer_address_data_empty');
+        }
+
+        foreach ($customerAddressData as $addressItem) {
+//            switch($addressItem['mode']) {
+//            case self::ADDRESS_BILLING:
+                /** @var $address Mage_Sales_Model_Quote_Address */
+                $address = Mage::getModel('Mage_Sales_Model_Quote_Address');
+//                break;
+//            case self::ADDRESS_SHIPPING:
+//                /** @var $address Mage_Sales_Model_Quote_Address */
+//                $address = Mage::getModel('Mage_Sales_Model_Quote_Address');
+//                break;
+//            }
+            $addressMode = $addressItem['mode'];
+            unset($addressItem['mode']);
+
+            if (!empty($addressItem['entity_id'])) {
+                $customerAddress = $this->_getCustomerAddress($addressItem['entity_id']);
+                if ($customerAddress->getCustomerId() != $quote->getCustomerId()) {
+                    $this->_fault('address_not_belong_customer');
+                }
+                $address->importCustomerAddress($customerAddress);
+
+            } else {
+                $address->setData($addressItem);
+            }
+
+            $address->implodeStreetAddress();
+
+            if (($validateRes = $address->validate())!==true) {
+                $this->_fault('customer_address_invalid', implode(PHP_EOL, $validateRes));
+            }
+
+            switch ($addressMode) {
+                case self::ADDRESS_BILLING:
+                    $address->setEmail($quote->getCustomer()->getEmail());
+
+                    if (!$quote->isVirtual()) {
+                        $useCase = isset($addressItem['use_for_shipping']) ? (int)$addressItem['use_for_shipping'] : 0;
+                        switch ($useCase) {
+                            case 0:
+                                $shippingAddress = $quote->getShippingAddress();
+                                $shippingAddress->setSameAsBilling(0);
+                                break;
+                            case 1:
+                                $billingAddress = clone $address;
+                                $billingAddress->unsAddressId()->unsAddressType();
+
+                                $shippingAddress = $quote->getShippingAddress();
+                                $shippingMethod = $shippingAddress->getShippingMethod();
+                                $shippingAddress->addData($billingAddress->getData())
+                                    ->setSameAsBilling(1)
+                                    ->setShippingMethod($shippingMethod)
+                                    ->setCollectShippingRates(true);
+                                break;
+                        }
+                    }
+                    $quote->setBillingAddress($address);
+                    break;
+
+                case self::ADDRESS_SHIPPING:
+                    $address->setCollectShippingRates(true)
+                        ->setSameAsBilling(0);
+                    $quote->setShippingAddress($address);
+                    break;
+            }
+
+        }
+
+        try {
+            $quote->collectTotals()
+                ->save();
+        } catch (Exception $e) {
+            $this->_fault('address_is_not_set', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Prepare customer entered data for implementing
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function _prepareCustomerData($data)
+    {
+        foreach ($this->_attributesMap['quote_customer'] as $attributeAlias => $attributeCode) {
+            if (isset($data[$attributeAlias])) {
+                $data[$attributeCode] = $data[$attributeAlias];
+                unset($data[$attributeAlias]);
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * Prepare customer entered data for implementing
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function _prepareCustomerAddressData($data)
+    {
+        if (!is_array($data) || !is_array($data[0])) {
+            return null;
+        }
+
+        $dataAddresses = array();
+        foreach ($data as $addressItem) {
+            foreach ($this->_attributesMap['quote_address'] as $attributeAlias => $attributeCode) {
+                if (isset($addressItem[$attributeAlias])) {
+                    $addressItem[$attributeCode] = $addressItem[$attributeAlias];
+                    unset($addressItem[$attributeAlias]);
+                }
+            }
+            $dataAddresses[] = $addressItem;
+        }
+        return $dataAddresses;
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Customer/Api/V2.php b/app/code/core/Mage/Checkout/Model/Cart/Customer/Api/V2.php
new file mode 100644
index 00000000000..1069273cd3c
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Customer/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shoping cart api for customer data 
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Checkout_Model_Cart_Customer_Api_V2 extends Mage_Checkout_Model_Cart_Customer_Api
+{
+    /**
+     * Prepare customer entered data for implementing
+     *
+     * @param  object $data
+     * @return array
+     */
+    protected function _prepareCustomerData($data)
+    {
+        if (null !== ($_data = get_object_vars($data))) {
+            return parent::_prepareCustomerData($_data);
+        }
+        return array();
+    }
+
+    /**
+     * Prepare customer entered data for implementing
+     *
+     * @param  object $data
+     * @return array
+     */
+    protected function _prepareCustomerAddressData($data)
+    {
+        if (is_array($data)) {
+            $dataAddresses = array();
+            foreach($data as $addressItem) {
+                if (null !== ($_addressItem = get_object_vars($addressItem))) {
+                    $dataAddresses[] = $_addressItem;
+                }
+            }
+            return parent::_prepareCustomerAddressData($dataAddresses);
+        }
+        
+        return null;
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Payment/Api.php b/app/code/core/Mage/Checkout/Model/Cart/Payment/Api.php
new file mode 100644
index 00000000000..b26d0164dd6
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Payment/Api.php
@@ -0,0 +1,200 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Checkout_Model_Cart_Payment_Api extends Mage_Checkout_Model_Api_Resource
+{
+
+    /**
+     * Returns payment data or empty array in case it is not valid
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function _preparePaymentData($data)
+    {
+        if (!is_array($data)) {
+            return array();
+        }
+
+        return $data;
+    }
+
+    /**
+     * @param  $method
+     * @param  $quote
+     * @return bool
+     */
+    protected function _canUsePaymentMethod($method, $quote)
+    {
+        if ( !($method->isGateway() || $method->canUseInternal()) ) {
+            return false;
+        }
+
+        if (!$method->canUseForCountry($quote->getBillingAddress()->getCountry())) {
+            return false;
+        }
+
+        if (!$method->canUseForCurrency(Mage::app()->getStore($quote->getStoreId())->getBaseCurrencyCode())) {
+            return false;
+        }
+
+        /**
+         * Checking for min/max order total for assigned payment method
+         */
+        $total = $quote->getBaseGrandTotal();
+        $minTotal = $method->getConfigData('min_order_total');
+        $maxTotal = $method->getConfigData('max_order_total');
+
+        if ((!empty($minTotal) && ($total < $minTotal)) || (!empty($maxTotal) && ($total > $maxTotal))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    protected function _getPaymentMethodAvailableCcTypes($method)
+    {
+        $ccTypes = Mage::getSingleton('Mage_Payment_Model_Config')->getCcTypes();
+        $methodCcTypes = explode(',',$method->getConfigData('cctypes'));
+        foreach ($ccTypes as $code=>$title) {
+            if (!in_array($code, $methodCcTypes)) {
+                unset($ccTypes[$code]);
+            }
+        }
+        if (empty($ccTypes)) {
+            return null;
+        }
+
+        return $ccTypes;
+    }
+
+    /**
+     * Retrieve available payment methods for a quote
+     *
+     * @param int $quoteId
+     * @param int $store
+     * @return array
+     */
+    public function getPaymentMethodsList($quoteId, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+        $store = $quote->getStoreId();
+
+        $total = $quote->getBaseSubtotal();
+
+        $methodsResult = array();
+        $methods = Mage::helper('Mage_Payment_Helper_Data')->getStoreMethods($store, $quote);
+
+        foreach ($methods as $method) {
+            /** @var $method Mage_Payment_Model_Method_Abstract */
+            if ($this->_canUsePaymentMethod($method, $quote)) {
+                $isRecurring = $quote->hasRecurringItems() && $method->canManageRecurringProfiles();
+
+                if ($total != 0 || $method->getCode() == 'free' || $isRecurring) {
+                    $methodsResult[] = array(
+                        'code' => $method->getCode(),
+                        'title' => $method->getTitle(),
+                        'cc_types' => $this->_getPaymentMethodAvailableCcTypes($method),
+                    );
+                }
+            }
+        }
+
+        return $methodsResult;
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $paymentData
+     * @param  $store
+     * @return bool
+     */
+    public function setPaymentMethod($quoteId, $paymentData, $store=null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+        $store = $quote->getStoreId();
+
+        $paymentData = $this->_preparePaymentData($paymentData);
+
+        if (empty($paymentData)) {
+            $this->_fault("payment_method_empty");
+        }
+
+        if ($quote->isVirtual()) {
+            // check if billing address is set
+            if (is_null($quote->getBillingAddress()->getId()) ) {
+                $this->_fault('billing_address_is_not_set');
+            }
+            $quote->getBillingAddress()->setPaymentMethod(isset($paymentData['method']) ? $paymentData['method'] : null);
+        } else {
+            // check if shipping address is set
+            if (is_null($quote->getShippingAddress()->getId()) ) {
+                $this->_fault('shipping_address_is_not_set');
+            }
+            $quote->getShippingAddress()->setPaymentMethod(isset($paymentData['method']) ? $paymentData['method'] : null);
+        }
+
+        if (!$quote->isVirtual() && $quote->getShippingAddress()) {
+            $quote->getShippingAddress()->setCollectShippingRates(true);
+        }
+
+        $total = $quote->getBaseSubtotal();
+        $methods = Mage::helper('Mage_Payment_Helper_Data')->getStoreMethods($store, $quote);
+
+        foreach ($methods as $method) {
+            /** @var $method Mage_Payment_Model_Method_Abstract */
+            if ($method->getCode() == $paymentData['method']) {
+                $isRecurring = $quote->hasRecurringItems() && $method->canManageRecurringProfiles();
+                $isAllowedMethod = $total != 0 || $method->getCode() == 'free' || $isRecurring;
+                if (!$this->_canUsePaymentMethod($method, $quote) || !$isAllowedMethod) {
+                    $this->_fault("method_not_allowed");
+                }
+            }
+        }
+
+        try {
+            $payment = $quote->getPayment();
+            $payment->importData($paymentData);
+
+
+            $quote->setTotalsCollectedFlag(false)
+                    ->collectTotals()
+                    ->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('payment_method_is_not_set', $e->getMessage());
+        }
+        return true;
+    }
+
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Payment/Api/V2.php b/app/code/core/Mage/Checkout/Model/Cart/Payment/Api/V2.php
new file mode 100644
index 00000000000..b3be46c0cbc
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Payment/Api/V2.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+ class Mage_Checkout_Model_Cart_Payment_Api_V2 extends Mage_Checkout_Model_Cart_Payment_Api
+{
+     protected function _preparePaymentData($data)
+     {
+        if (null !== ($_data = get_object_vars($data))) {
+            return parent::_preparePaymentData($_data);
+        }
+
+        return array();
+     }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Product/Api.php b/app/code/core/Mage/Checkout/Model/Cart/Product/Api.php
new file mode 100644
index 00000000000..077c8c69e18
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Product/Api.php
@@ -0,0 +1,330 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api for product
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Checkout_Model_Cart_Product_Api extends Mage_Checkout_Model_Api_Resource_Product
+{
+    /**
+     * Base preparation of product data
+     *
+     * @param mixed $data
+     * @return null|array
+     */
+    protected function _prepareProductsData($data)
+    {
+        return is_array($data) ? $data : null;
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $productsData
+     * @param  $store
+     * @return bool
+     */
+    public function add($quoteId, $productsData, $store=null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+        if (empty($store)) {
+            $store = $quote->getStoreId();
+        }
+
+        $productsData = $this->_prepareProductsData($productsData);
+        if (empty($productsData)) {
+            $this->_fault('invalid_product_data');
+        }
+
+        $errors = array();
+        foreach ($productsData as $productItem) {
+            if (isset($productItem['product_id'])) {
+                $productByItem = $this->_getProduct($productItem['product_id'], $store, "id");
+            } else if (isset($productItem['sku'])) {
+                $productByItem = $this->_getProduct($productItem['sku'], $store, "sku");
+            } else {
+                $errors[] = Mage::helper('Mage_Checkout_Helper_Data')->__("One item of products do not have identifier or sku");
+                continue;
+            }
+
+            $productRequest = $this->_getProductRequest($productItem);
+            try {
+                $result = $quote->addProduct($productByItem, $productRequest);
+                if (is_string($result)) {
+                    Mage::throwException($result);
+                }
+            } catch (Mage_Core_Exception $e) {
+                $errors[] = $e->getMessage();
+            }
+        }
+
+        if (!empty($errors)) {
+            $this->_fault("add_product_fault", implode(PHP_EOL, $errors));
+        }
+
+        try {
+            $quote->collectTotals()->save();
+        } catch(Exception $e) {
+            $this->_fault("add_product_quote_save_fault", $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $productsData
+     * @param  $store
+     * @return bool
+     */
+    public function update($quoteId, $productsData, $store=null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+        if (empty($store)) {
+            $store = $quote->getStoreId();
+        }
+
+        $productsData = $this->_prepareProductsData($productsData);
+        if (empty($productsData)) {
+            $this->_fault('invalid_product_data');
+        }
+
+        $errors = array();
+        foreach ($productsData as $productItem) {
+            if (isset($productItem['product_id'])) {
+                $productByItem = $this->_getProduct($productItem['product_id'], $store, "id");
+            } else if (isset($productItem['sku'])) {
+                $productByItem = $this->_getProduct($productItem['sku'], $store, "sku");
+            } else {
+                $errors[] = Mage::helper('Mage_Checkout_Helper_Data')->__("One item of products do not have identifier or sku");
+                continue;
+            }
+
+            /** @var $quoteItem Mage_Sales_Model_Quote_Item */
+            $quoteItem = $this->_getQuoteItemByProduct($quote, $productByItem,
+                $this->_getProductRequest($productItem));
+            if (is_null($quoteItem->getId())) {
+                $errors[] = Mage::helper('Mage_Checkout_Helper_Data')->__("One item of products is not belong any of quote item");
+                continue;
+            }
+
+            if ($productItem['qty'] > 0) {
+                $quoteItem->setQty($productItem['qty']);
+            }
+        }
+
+        if (!empty($errors)) {
+            $this->_fault("update_product_fault", implode(PHP_EOL, $errors));
+        }
+
+        try {
+            $quote->save();
+        } catch(Exception $e) {
+            $this->_fault("update_product_quote_save_fault", $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $productsData
+     * @param  $store
+     * @return bool
+     */
+    public function remove($quoteId, $productsData, $store=null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+        if (empty($store)) {
+            $store = $quote->getStoreId();
+        }
+
+        $productsData = $this->_prepareProductsData($productsData);
+        if (empty($productsData)) {
+            $this->_fault('invalid_product_data');
+        }
+
+        $errors = array();
+        foreach ($productsData as $productItem) {
+            if (isset($productItem['product_id'])) {
+                $productByItem = $this->_getProduct($productItem['product_id'], $store, "id");
+            } else if (isset($productItem['sku'])) {
+                $productByItem = $this->_getProduct($productItem['sku'], $store, "sku");
+            } else {
+                $errors[] = Mage::helper('Mage_Checkout_Helper_Data')->__("One item of products do not have identifier or sku");
+                continue;
+            }
+
+            try {
+                /** @var $quoteItem Mage_Sales_Model_Quote_Item */
+                $quoteItem = $this->_getQuoteItemByProduct($quote, $productByItem,
+                    $this->_getProductRequest($productItem));
+                if (is_null($quoteItem->getId())) {
+                    $errors[] = Mage::helper('Mage_Checkout_Helper_Data')->__("One item of products is not belong any of quote item");
+                    continue;
+                }
+                $quote->removeItem($quoteItem->getId());
+            } catch (Mage_Core_Exception $e) {
+                $errors[] = $e->getMessage();
+            }
+        }
+
+        if (!empty($errors)) {
+            $this->_fault("remove_product_fault", implode(PHP_EOL, $errors));
+        }
+
+        try {
+            $quote->save();
+        } catch(Exception $e) {
+            $this->_fault("remove_product_quote_save_fault", $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $store
+     * @return array
+     */
+    public function items($quoteId, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+        if (empty($store)) {
+            $store = $quote->getStoreId();
+        }
+
+        if (!$quote->getItemsCount()) {
+            return array();
+        }
+
+        $productsResult = array();
+        foreach ($quote->getAllItems() as $item) {
+            /** @var $item Mage_Sales_Model_Quote_Item */
+            $product = $item->getProduct();
+            $productsResult[] = array( // Basic product data
+                'product_id'   => $product->getId(),
+                'sku'          => $product->getSku(),
+                'name'         => $product->getName(),
+                'set'          => $product->getAttributeSetId(),
+                'type'         => $product->getTypeId(),
+                'category_ids' => $product->getCategoryIds(),
+                'website_ids'  => $product->getWebsiteIds()
+            );
+        }
+
+        return $productsResult;
+    }
+
+    /**
+     * @param  $quoteId
+     * @param  $productsData
+     * @param  $store
+     * @return bool
+     */
+    public function moveToCustomerQuote($quoteId, $productsData, $store=null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+
+        if (empty($store)) {
+            $store = $quote->getStoreId();
+        }
+
+        $customer = $quote->getCustomer();
+        if (is_null($customer->getId())) {
+            $this->_fault('customer_not_set_for_quote');
+        }
+
+        /** @var $customerQuote Mage_Sales_Model_Quote */
+        $customerQuote = Mage::getModel('Mage_Sales_Model_Quote')
+            ->setStoreId($store)
+            ->loadByCustomer($customer);
+
+        if (is_null($customerQuote->getId())) {
+            $this->_fault('customer_quote_not_exist');
+        }
+
+        if ($customerQuote->getId() == $quote->getId()) {
+            $this->_fault('quotes_are_similar');
+        }
+
+        $productsData = $this->_prepareProductsData($productsData);
+        if (empty($productsData)) {
+            $this->_fault('invalid_product_data');
+        }
+
+        $errors = array();
+        foreach($productsData as $key => $productItem){
+            if (isset($productItem['product_id'])) {
+                $productByItem = $this->_getProduct($productItem['product_id'], $store, "id");
+            } else if (isset($productItem['sku'])) {
+                $productByItem = $this->_getProduct($productItem['sku'], $store, "sku");
+            } else {
+                $errors[] = Mage::helper('Mage_Checkout_Helper_Data')->__("One item of products do not have identifier or sku");
+                continue;
+            }
+
+            try {
+                /** @var $quoteItem Mage_Sales_Model_Quote_Item */
+                $quoteItem = $this->_getQuoteItemByProduct($quote, $productByItem,
+                    $this->_getProductRequest($productItem));
+                if($quoteItem && $quoteItem->getId()){
+                    $newQuoteItem = clone $quoteItem;
+                    $newQuoteItem->setId(null);
+                    $customerQuote->addItem($newQuoteItem);
+                    $quote->removeItem($quoteItem->getId());
+                    unset($productsData[$key]);
+                } else {
+                     $errors[] = Mage::helper('Mage_Checkout_Helper_Data')->__("One item of products is not belong any of quote item");
+                }
+            } catch (Mage_Core_Exception $e) {
+                $errors[] = $e->getMessage();
+            }
+        }
+
+        if (count($productsData) || !empty($errors)) {
+            $this->_fault('unable_to_move_all_products', implode(PHP_EOL, $errors));
+        }
+
+        try {
+            $customerQuote
+                ->collectTotals()
+                ->save();
+
+            $quote
+                ->collectTotals()
+                ->save();
+        } catch (Exception $e) {
+             $this->_fault("product_move_quote_save_fault", $e->getMessage());
+        }
+
+        return true;
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Product/Api/V2.php b/app/code/core/Mage/Checkout/Model/Cart/Product/Api/V2.php
new file mode 100644
index 00000000000..2994c9f5238
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Product/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api for product
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Checkout_Model_Cart_Product_Api_V2 extends Mage_Checkout_Model_Cart_Product_Api
+{
+
+    /**
+     * Return an Array of Object attributes.
+     *
+     * @param Mixed $data
+     * @return Array
+     */
+    protected function _prepareProductsData($data){
+        if (is_object($data)) {
+            $arr = get_object_vars($data);
+            foreach ($arr as $key => $value) {
+                $assocArr = array();
+                if (is_array($value)) {
+                    foreach ($value as $v) {
+                        if (is_object($v) && count(get_object_vars($v))==2
+                            && isset($v->key) && isset($v->value)) {
+                            $assocArr[$v->key] = $v->value;
+                        }
+                    }
+                }
+                if (!empty($assocArr)) {
+                    $arr[$key] = $assocArr;
+                }
+            }
+            $arr = $this->_prepareProductsData($arr);
+            return parent::_prepareProductsData($arr);
+        }
+        if (is_array($data)) {
+            foreach ($data as $key => $value) {
+                if (is_object($value) || is_array($value)) {
+                    $data[$key] = $this->_prepareProductsData($value);
+                } else {
+                    $data[$key] = $value;
+                }
+            }
+            return parent::_prepareProductsData($data);
+        }
+        return $data;
+    }
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Shipping/Api.php b/app/code/core/Mage/Checkout/Model/Cart/Shipping/Api.php
new file mode 100644
index 00000000000..cf31b878945
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Shipping/Api.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.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Checkout_Model_Cart_Shipping_Api extends Mage_Checkout_Model_Api_Resource
+{
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        parent::__construct($apiHelper);
+        $this->_ignoredAttributeCodes['quote_shipping_rate'] = array('address_id', 'created_at', 'updated_at', 'rate_id', 'carrier_sort_order');
+    }
+
+    /**
+     * Set an Shipping Method for Shopping Cart
+     *
+     * @param  $quoteId
+     * @param  $shippingMethod
+     * @param  $store
+     * @return bool
+     */
+    public function setShippingMethod($quoteId, $shippingMethod, $store = null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+
+        $quoteShippingAddress = $quote->getShippingAddress();
+        if(is_null($quoteShippingAddress->getId()) ) {
+            $this->_fault("shipping_address_is_not_set");
+        }
+
+        $rate = $quote->getShippingAddress()->collectShippingRates()->getShippingRateByCode($shippingMethod);
+        if (!$rate) {
+            $this->_fault('shipping_method_is_not_available');
+        }
+
+        try {
+            $quote->getShippingAddress()->setShippingMethod($shippingMethod);
+            $quote->collectTotals()->save();
+        } catch(Mage_Core_Exception $e) {
+            $this->_fault('shipping_method_is_not_set', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Get list of available shipping methods
+     *
+     * @param  $quoteId
+     * @param  $store
+     * @return array
+     */
+    public function getShippingMethodsList($quoteId, $store=null)
+    {
+        $quote = $this->_getQuote($quoteId, $store);
+
+        $quoteShippingAddress = $quote->getShippingAddress();
+        if (is_null($quoteShippingAddress->getId())) {
+            $this->_fault("shipping_address_is_not_set");
+        }
+
+        try {
+            $quoteShippingAddress->collectShippingRates()->save();
+            $groupedRates = $quoteShippingAddress->getGroupedAllShippingRates();
+
+            $ratesResult = array();
+            foreach ($groupedRates as $carrierCode => $rates ) {
+                $carrierName = $carrierCode;
+                if (!is_null(Mage::getStoreConfig('carriers/'.$carrierCode.'/title'))) {
+                    $carrierName = Mage::getStoreConfig('carriers/'.$carrierCode.'/title');
+                }
+
+                foreach ($rates as $rate) {
+                    $rateItem = $this->_getAttributes($rate, "quote_shipping_rate");
+                    $rateItem['carrierName'] = $carrierName;
+                    $ratesResult[] = $rateItem;
+                    unset($rateItem);
+                }
+            }
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('shipping_methods_list_could_not_be_retrived', $e->getMessage());
+        }
+
+        return $ratesResult;
+    }
+
+
+}
diff --git a/app/code/core/Mage/Checkout/Model/Cart/Shipping/Api/V2.php b/app/code/core/Mage/Checkout/Model/Cart/Shipping/Api/V2.php
new file mode 100644
index 00000000000..5d7058852f6
--- /dev/null
+++ b/app/code/core/Mage/Checkout/Model/Cart/Shipping/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Shopping cart api
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Checkout_Model_Cart_Shipping_Api_V2 extends Mage_Checkout_Model_Cart_Shipping_Api
+{
+
+}
diff --git a/app/code/core/Mage/Checkout/etc/api.xml b/app/code/core/Mage/Checkout/etc/api.xml
new file mode 100644
index 00000000000..d3e73dab15a
--- /dev/null
+++ b/app/code/core/Mage/Checkout/etc/api.xml
@@ -0,0 +1,536 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Checkout
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <cart translate="title" module="Mage_Checkout">
+                <model>Mage_Checkout_Model_Cart_Api</model>
+                <title>Shopping Cart</title>
+                <acl>cart</acl>
+                <methods>
+                    <create translate="title" module="Mage_Checkout">
+                        <title>Create shopping cart</title>
+                        <method>create</method>
+                        <acl>cart/create</acl>
+                    </create>
+                    <order translate="title" module="Mage_Checkout">
+                        <title>Create an order from shopping cart</title>
+                        <method>createOrder</method>
+                        <acl>cart/order</acl>
+                    </order>
+                    <orderWithPayment translate="title" module="Mage_Checkout">
+                        <title>Create an order from shopping cart with payment method</title>
+                        <method>createOrderWithPayment</method>
+                        <acl>cart/order</acl>
+                    </orderWithPayment>
+                    <info translate="title" module="Mage_Checkout">
+                        <title>Retrieve information about shopping cart</title>
+                        <method>info</method>
+                        <acl>cart/info</acl>
+                    </info>
+                    <totals translate="title" module="Mage_Checkout">
+                        <title>Get total prices for shopping cart</title>
+                        <method>totals</method>
+                        <acl>cart/totals</acl>
+                    </totals>
+                    <license translate="title" module="Mage_Checkout">
+                        <title>Get terms and conditions</title>
+                        <method>licenseAgreement</method>
+                        <acl>cart/license</acl>
+                    </license>
+                </methods>
+                <faults module="Mage_Checkout">
+                    <store_not_exists>
+                        <code>1001</code>
+                        <message>Cannot perform operation because store does not exist.</message>
+                    </store_not_exists>
+                    <quote_not_exists>
+                        <code>1002</code>
+                        <message>Cannot perform operation because quote does not exist.</message>
+                    </quote_not_exists>
+                    <quote_create_fault>
+                        <code>1003</code>
+                        <message>Cannot create a quote. </message>
+                    </quote_create_fault>
+                    <quote_already_exists>
+                        <code>1004</code>
+                        <message>Cannot create a quote because quote with such ID already exists.</message>
+                    </quote_already_exists>
+                    <required_agreements_are_not_all>
+                        <code>1005</code>
+                        <message>Not all required agreements are set.</message>
+                    </required_agreements_are_not_all>
+                    <invalid_checkout_type>
+                        <code>1006</code>
+                        <message>The checkout type is not valid. Select single checkout type.</message>
+                    </invalid_checkout_type>
+                    <guest_checkout_is_not_enabled>
+                        <code>1007</code>
+                        <message>Checkout is not available for guest.</message>
+                    </guest_checkout_is_not_enabled>
+                    <create_order_fault>
+                        <code>1008</code>
+                        <message>Cannot create an order. </message>
+                    </create_order_fault>
+                    <payment_method_empty>
+                        <code>1071</code>
+                        <message>Payment method data is empty.</message>
+                    </payment_method_empty>
+                    <billing_address_is_not_set>
+                        <code>1072</code>
+                        <message>Customer billing address is not set and is required for payment method data.</message>
+                    </billing_address_is_not_set>
+                    <shipping_address_is_not_set>
+                        <code>1073</code>
+                        <message>Customer shipping address is not set and is required for payment method data.</message>
+                    </shipping_address_is_not_set>
+                    <method_not_allowed>
+                        <code>1074</code>
+                        <message>Payment method is not allowed.</message>
+                    </method_not_allowed>
+                    <payment_method_is_not_set>
+                        <code>1075</code>
+                        <message>Payment method is not set.</message>
+                    </payment_method_is_not_set>
+                </faults>
+            </cart>
+            <cart_product translate="title" module="Mage_Checkout">
+                <model>Mage_Checkout_Model_Cart_Product_Api</model>
+                <title>Cart Product API</title>
+                <acl>cart/product</acl>
+                <methods>
+                    <add translate="title" module="Mage_Checkout">
+                        <title>Add product to shopping cart</title>
+                        <method>add</method>
+                        <acl>cart/product/add</acl>
+                    </add>
+                    <update translate="title" module="Mage_Checkout">
+                        <title>Update product quantities in shopping cart</title>
+                        <method>update</method>
+                        <acl>cart/product/update</acl>
+                    </update>
+                    <remove translate="title" module="Mage_Checkout">
+                        <title>Remove product from shopping cart</title>
+                        <method>remove</method>
+                        <acl>cart/product/remove</acl>
+                    </remove>
+                    <list translate="title" module="Mage_Checkout">
+                        <title>Get list of products in shopping cart</title>
+                        <method>items</method>
+                        <acl>cart/product/list</acl>
+                    </list>
+                    <moveToCustomerQuote>
+                        <title>Move product(s) to customer quote</title>
+                        <method>moveToCustomerQuote</method>
+                        <acl>cart/product/moveToCustomerQuote</acl>
+                    </moveToCustomerQuote>
+                </methods>
+                <faults module="Mage_Checkout">
+                    <store_not_exists>
+                        <code>1001</code>
+                        <message>Cannot perform operation because store does not exist.</message>
+                    </store_not_exists>
+                    <quote_not_exists>
+                        <code>1002</code>
+                        <message>Cannot perform operation because quote does not exist.</message>
+                    </quote_not_exists>
+                    <invalid_product_data>
+                        <code>1021</code>
+                        <message>Product data is not valid.</message>
+                    </invalid_product_data>
+                    <add_product_fault>
+                        <code>1022</code>
+                        <message>Product(s) could not be added. </message>
+                    </add_product_fault>
+                    <add_product_quote_save_fault>
+                        <code>1023</code>
+                        <message>Quote could not be saved during adding product(s) operation.</message>
+                    </add_product_quote_save_fault>
+                    <update_product_fault>
+                        <code>1024</code>
+                        <message>Product(s) could not be updated. </message>
+                    </update_product_fault>
+                    <update_product_quote_save_fault>
+                        <code>1025</code>
+                        <message>Quote could not be saved during updating product(s) operation.</message>
+                    </update_product_quote_save_fault>
+                    <remove_product_fault>
+                        <code>1026</code>
+                        <message>Product(s) could not be removed. </message>
+                    </remove_product_fault>
+                    <remove_product_quote_save_fault>
+                        <code>1027</code>
+                        <message>Quote could not be saved during removing product(s) operation.</message>
+                    </remove_product_quote_save_fault>
+                    <customer_not_set_for_quote>
+                        <code>1028</code>
+                        <message>Customer is not set for quote.</message>
+                    </customer_not_set_for_quote>
+                    <customer_quote_not_exist>
+                        <code>1029</code>
+                        <message>Customer quote does not exist.</message>
+                    </customer_quote_not_exist>
+                    <quotes_are_similar>
+                        <code>1030</code>
+                        <message>Quotes are identical.</message>
+                    </quotes_are_similar>
+                    <unable_to_move_all_products>
+                        <code>1031</code>
+                        <message>Product(s) could not be moved. </message>
+                    </unable_to_move_all_products>
+                    <product_move_quote_save_fault>
+                        <code>1032</code>
+                        <message>One of quotes could not be saved during moving product(s) operation.</message>
+                    </product_move_quote_save_fault>
+                </faults>
+            </cart_product>
+            <cart_customer translate="title" module="Mage_Checkout">
+                <model>Mage_Checkout_Model_Cart_Customer_Api</model>
+                <title>Customer Information</title>
+                <acl>cart/customer</acl>
+                <methods>
+                    <set translate="title" module="Mage_Checkout">
+                        <title>Set customer for shopping cart</title>
+                        <method>set</method>
+                        <acl>cart/customer/set</acl>
+                    </set>
+                    <addresses translate="title" module="Mage_Checkout">
+                        <title>Set customer's addresses in shopping cart</title>
+                        <method>setAddresses</method>
+                        <acl>cart/customer/addresses</acl>
+                    </addresses>
+                </methods>
+                <faults module="Mage_Checkout">
+                    <store_not_exists>
+                        <code>1001</code>
+                        <message>Cannot perform operation because store does not exist.</message>
+                    </store_not_exists>
+                    <quote_not_exists>
+                        <code>1002</code>
+                        <message>Cannot perform operation because quote does not exist.</message>
+                    </quote_not_exists>
+                    <customer_not_set>
+                        <code>1041</code>
+                        <message>Customer is not set. </message>
+                    </customer_not_set>
+                    <customer_not_exists>
+                        <code>1042</code>
+                        <message>The customer ID is not valid or customer does not exist.</message>
+                    </customer_not_exists>
+                    <customer_not_created>
+                        <code>1043</code>
+                        <message>Customer could not be created. </message>
+                    </customer_not_created>
+                    <customer_data_invalid>
+                        <code>1044</code>
+                        <message>Customer data is not valid. </message>
+                    </customer_data_invalid>
+                    <customer_mode_is_unknown>
+                        <code>1045</code>
+                        <message>Customer mode is unknown</message>
+                    </customer_mode_is_unknown>
+                    <customer_address_data_empty>
+                        <code>1051</code>
+                        <message>Customer address data is empty.</message>
+                    </customer_address_data_empty>
+                    <customer_address_invalid>
+                        <code>1052</code>
+                        <message>Customer address data is not valid.</message>
+                    </customer_address_invalid>
+                    <invalid_address_id>
+                        <code>1053</code>
+                        <message>The customer address ID is not valid</message>
+                    </invalid_address_id>
+                    <address_is_not_set>
+                        <code>1054</code>
+                        <message>Customer address is not set.</message>
+                    </address_is_not_set>
+                    <address_not_belong_customer>
+                        <code>1055</code>
+                        <message>Customer address ID does not belong to customer which is set in quote.</message>
+                    </address_not_belong_customer>
+                </faults>
+            </cart_customer>
+            <cart_shipping translate="title" module="Mage_Checkout">
+                <model>Mage_Checkout_Model_Cart_Shipping_Api</model>
+                <title>Shipping information</title>
+                <acl>cart/shipping</acl>
+                <methods>
+                    <method translate="title" module="Mage_Checkout">
+                        <title>Set shipping method</title>
+                        <method>setShippingMethod</method>
+                        <acl>cart/shipping/method</acl>
+                    </method>
+                    <list translate="title" module="Mage_Checkout">
+                        <title>Get list of available shipping methods</title>
+                        <method>getShippingMethodsList</method>
+                        <acl>cart/shipping/list</acl>
+                    </list>
+                </methods>
+                <faults module="Mage_Checkout">
+                    <store_not_exists>
+                        <code>1001</code>
+                        <message>Cannot perform operation because store does not exist.</message>
+                    </store_not_exists>
+                    <quote_not_exists>
+                        <code>1002</code>
+                        <message>Cannot perform operation because quote does not exist.</message>
+                    </quote_not_exists>
+                    <shipping_address_is_not_set>
+                        <code>1061</code>
+                        <message>Cannot perform operation because customer shipping address is not set.</message>
+                    </shipping_address_is_not_set>
+                    <shipping_method_is_not_available>
+                        <code>1062</code>
+                        <message>Shipping method is not available.</message>
+                    </shipping_method_is_not_available>
+                    <shipping_method_is_not_set>
+                        <code>1063</code>
+                        <message>Cannot set shipping method. </message>
+                    </shipping_method_is_not_set>
+                    <shipping_methods_list_could_not_be_retrived>
+                        <code>1064</code>
+                        <message>Cannot receive the list of shipping methods. </message>
+                    </shipping_methods_list_could_not_be_retrived>
+                </faults>
+            </cart_shipping>
+            <cart_payment translate="title" module="Mage_Checkout">
+                <model>Mage_Checkout_Model_Cart_Payment_Api</model>
+                <title>Payment method information</title>
+                <acl>cart/payment</acl>
+                <methods>
+                    <method translate="title" module="Mage_Checkout">
+                        <title>Set payment method</title>
+                        <method>setPaymentMethod</method>
+                        <acl>cart/payment/method</acl>
+                    </method>
+                    <list translate="title" module="Mage_Checkout">
+                        <title>Get list of available payment methods</title>
+                        <method>getPaymentMethodsList</method>
+                        <acl>cart/payment/list</acl>
+                    </list>
+                </methods>
+                <faults module="Mage_Checkout">
+                    <store_not_exists>
+                        <code>1001</code>
+                        <message>Cannot perform operation because store does not exist.</message>
+                    </store_not_exists>
+                    <quote_not_exists>
+                        <code>1002</code>
+                        <message>Cannot perform operation because quote does not exist.</message>
+                    </quote_not_exists>
+                    <payment_method_empty>
+                        <code>1071</code>
+                        <message>Payment method data is empty.</message>
+                    </payment_method_empty>
+                    <billing_address_is_not_set>
+                        <code>1072</code>
+                        <message>Customer billing address is not set. It is required for payment method data.</message>
+                    </billing_address_is_not_set>
+                    <shipping_address_is_not_set>
+                        <code>1073</code>
+                        <message>Customer shipping address is not set. It is required for payment method data.</message>
+                    </shipping_address_is_not_set>
+                    <method_not_allowed>
+                        <code>1074</code>
+                        <message>Payment method is not allowed.</message>
+                    </method_not_allowed>
+                    <payment_method_is_not_set>
+                        <code>1075</code>
+                        <message>Payment method is not set. </message>
+                    </payment_method_is_not_set>
+                </faults>
+            </cart_payment>
+            <cart_coupon translate="title" module="Mage_Checkout">
+                <model>Mage_Checkout_Model_Cart_Coupon_Api</model>
+                <title>Shopping cart ability to set coupon code</title>
+                <acl>cart/coupon</acl>
+                <methods>
+                    <add translate="title" module="Mage_Checkout">
+                        <title>Add coupon code for shopping cart</title>
+                        <method>add</method>
+                        <acl>cart/coupon/add</acl>
+                    </add>
+                    <remove translate="title" module="Mage_Checkout">
+                        <title>Remove coupon code from shopping cart</title>
+                        <method>remove</method>
+                        <acl>cart/coupon/remove</acl>
+                    </remove>
+                </methods>
+                <faults module="Mage_Checkout">
+                    <store_not_exists>
+                        <code>1001</code>
+                        <message>Cannot perform operation because store does not exist.</message>
+                    </store_not_exists>
+                    <quote_not_exists>
+                        <code>1002</code>
+                        <message>Cannot perform operation because quote does not exist.</message>
+                    </quote_not_exists>
+                    <quote_is_empty>
+                        <code>1081</code>
+                        <message>Coupon could not be applied because quote is empty.</message>
+                    </quote_is_empty>
+                    <cannot_apply_coupon_code>
+                        <code>1082</code>
+                        <message>Coupon could not be applied.</message>
+                    </cannot_apply_coupon_code>
+                    <coupon_code_is_not_valid>
+                        <code>1083</code>
+                        <message>Coupon is not valid.</message>
+                    </coupon_code_is_not_valid>
+                </faults>
+            </cart_coupon>
+        </resources>
+        <resources_alias>
+            <cart_customer_address>cart_customer</cart_customer_address>
+        </resources_alias>
+        <rest>
+            <mapping>
+                <cart_product>
+                    <post>
+                        <method>add</method>
+                    </post>
+                    <delete>
+                        <method>remove</method>
+                    </delete>
+                </cart_product>
+                <cart_shipping>
+                    <post>
+                        <method>method</method>
+                    </post>
+                </cart_shipping>
+                <cart_payment>
+                    <post>
+                        <method>method</method>
+                    </post>
+                </cart_payment>
+                <cart_customer>
+                    <post>
+                        <method>set</method>
+                    </post>
+                </cart_customer>
+                <cart_customer_address>
+                    <post>
+                        <method>addresses</method>
+                    </post>
+                </cart_customer_address>
+                <cart_payment>
+                    <post>
+                        <method>method</method>
+                    </post>
+                </cart_payment>
+            </mapping>
+        </rest>
+        <acl>
+            <resources>
+                <cart translate="title" module="Mage_Checkout">
+                    <title>Shopping Cart</title>
+                    <create translate="title" module="Mage_Checkout">
+                        <title>Create shopping cart</title>
+                    </create>
+                    <order translate="title" module="Mage_Checkout">
+                        <title>Create an order from shopping cart</title>
+                    </order>
+                    <info translate="title" module="Mage_Checkout">
+                        <title>Retrieve information about shopping cart</title>
+                    </info>
+                    <totals translate="title" module="Mage_Checkout">
+                        <title>Get total prices for shopping cart</title>
+                    </totals>
+                    <license translate="title" module="Mage_Checkout">
+                        <title>Get terms and conditions</title>
+                    </license>
+                    <product translate="title" module="Mage_Checkout">
+                        <title>Products</title>
+                        <add translate="title" module="Mage_Checkout">
+                            <title>Add product(s) to shopping cart</title>
+                        </add>
+                        <update translate="title" module="Mage_Checkout">
+                            <title>Update product(s) quantities in shopping cart</title>
+                        </update>
+                        <remove translate="title" module="Mage_Checkout">
+                            <title>Remove product(s) from shopping cart</title>
+                        </remove>
+                        <list translate="title" module="Mage_Checkout">
+                            <title>Get list of products in shopping cart</title>
+                        </list>
+                        <moveToCustomerQuote>
+                            <title>Move product(s) to customer quote</title>
+                        </moveToCustomerQuote>
+                    </product>
+                    <customer translate="title" module="Mage_Checkout">
+                        <title>Customer's information</title>
+                        <set translate="title" module="Mage_Checkout">
+                           <title>Set customer for shopping cart</title>
+                        </set>
+                        <addresses translate="title" module="Mage_Checkout">
+                            <title>Set customer's addresses in shopping cart</title>
+                        </addresses>
+                    </customer>
+                    <shipping translate="title" module="Mage_Checkout">
+                        <title>Shipping methods in shopping cart</title>
+                        <method translate="title" module="Mage_Checkout">
+                            <title>Set shipping method</title>
+                        </method>
+                        <list translate="title" module="Mage_Checkout">
+                            <title>Get list of available shipping methods</title>
+                        </list>
+                    </shipping>
+                    <payment translate="title" module="Mage_Checkout">
+                        <title>Payment methods in shopping cart</title>
+                        <method translate="title" module="Mage_Checkout">
+                            <title>Set payment method</title>
+                        </method>
+                        <list translate="title" module="Mage_Checkout">
+                            <title>Get list of available payment methods</title>
+                        </list>
+                    </payment>
+                    <coupon>
+                        <title>Shopping cart ability to set coupon code</title>
+                        <add>
+                            <title>Add coupon code for shopping cart</title>
+                        </add>
+                        <remove>
+                             <title>Remove coupon code from shopping cart</title>
+                        </remove>
+                    </coupon>
+                </cart>
+            </resources>
+        </acl>
+        <v2>
+            <resources_function_prefix>
+                <cart>shoppingCart</cart>
+                <cart_product>shoppingCartProduct</cart_product>
+                <cart_customer>shoppingCartCustomer</cart_customer>
+                <cart_shipping>shoppingCartShipping</cart_shipping>
+                <cart_payment>shoppingCartPayment</cart_payment>
+                <cart_coupon>shoppingCartCoupon</cart_coupon>
+            </resources_function_prefix>
+        </v2>
+    </api>
+</config>
diff --git a/app/code/core/Mage/Checkout/etc/wsdl.xml b/app/code/core/Mage/Checkout/etc/wsdl.xml
new file mode 100644
index 00000000000..7102732f4ef
--- /dev/null
+++ b/app/code/core/Mage/Checkout/etc/wsdl.xml
@@ -0,0 +1,805 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             xmlns="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <complexType name="shoppingCartAddressEntity">
+                <all>
+                    <element name="address_id" type="xsd:string" minOccurs="0"/>
+                    <element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_id" type="xsd:string" minOccurs="0"/>
+                    <element name="save_in_address_book" type="xsd:int" minOccurs="0"/>
+                    <element name="customer_address_id" type="xsd:string" minOccurs="0"/>
+                    <element name="address_type" type="xsd:string" minOccurs="0"/>
+                    <element name="email" type="xsd:string" minOccurs="0"/>
+                    <element name="prefix" type="xsd:string" minOccurs="0"/>
+                    <element name="firstname" type="xsd:string" minOccurs="0"/>
+                    <element name="middlename" type="xsd:string" minOccurs="0"/>
+                    <element name="lastname" type="xsd:string" minOccurs="0"/>
+                    <element name="suffix" type="xsd:string" minOccurs="0"/>
+                    <element name="company" type="xsd:string" minOccurs="0"/>
+                    <element name="street" type="xsd:string" minOccurs="0"/>
+                    <element name="city" type="xsd:string" minOccurs="0"/>
+                    <element name="region" type="xsd:string" minOccurs="0"/>
+                    <element name="region_id" type="xsd:string" minOccurs="0"/>
+                    <element name="postcode" type="xsd:string" minOccurs="0"/>
+                    <element name="country_id" type="xsd:string" minOccurs="0"/>
+                    <element name="telephone" type="xsd:string" minOccurs="0"/>
+                    <element name="fax" type="xsd:string" minOccurs="0"/>
+                    <element name="same_as_billing" type="xsd:int" minOccurs="0"/>
+                    <element name="free_shipping" type="xsd:int" minOccurs="0"/>
+                    <element name="shipping_method" type="xsd:string" minOccurs="0"/>
+                    <element name="shipping_description" type="xsd:string" minOccurs="0"/>
+                    <element name="weight" type="xsd:double" minOccurs="0"/>
+                    <element name="fax" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartItemEntity">
+                <all>
+                    <element name="item_id" type="xsd:string" minOccurs="0"/>
+                    <element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <element name="product_id" type="xsd:string" minOccurs="0"/>
+                    <element name="store_id" type="xsd:string" minOccurs="0"/>
+                    <element name="parent_item_id" type="xsd:string" minOccurs="0"/>
+                    <element name="is_virtual" type="xsd:int" minOccurs="0"/>
+                    <element name="sku" type="xsd:string" minOccurs="0"/>
+                    <element name="name" type="xsd:string" minOccurs="0"/>
+                    <element name="description" type="xsd:string" minOccurs="0"/>
+                    <element name="applied_rule_ids" type="xsd:string" minOccurs="0"/>
+                    <element name="additional_data" type="xsd:string" minOccurs="0"/>
+                    <element name="free_shipping" type="xsd:string" minOccurs="0"/>
+                    <element name="is_qty_decimal" type="xsd:string" minOccurs="0"/>
+                    <element name="no_discount" type="xsd:string" minOccurs="0"/>
+                    <element name="weight" type="xsd:double" minOccurs="0"/>
+                    <element name="qty" type="xsd:double" minOccurs="0"/>
+                    <element name="price" type="xsd:double" minOccurs="0"/>
+                    <element name="base_price" type="xsd:double" minOccurs="0"/>
+                    <element name="custom_price" type="xsd:double" minOccurs="0"/>
+                    <element name="discount_percent" type="xsd:double" minOccurs="0"/>
+                    <element name="discount_amount" type="xsd:double" minOccurs="0"/>
+                    <element name="base_discount_amount" type="xsd:double" minOccurs="0"/>
+                    <element name="tax_percent" type="xsd:double" minOccurs="0"/>
+                    <element name="tax_amount" type="xsd:double" minOccurs="0"/>
+                    <element name="base_tax_amount" type="xsd:double" minOccurs="0"/>
+                    <element name="row_total" type="xsd:double" minOccurs="0"/>
+                    <element name="base_row_total" type="xsd:double" minOccurs="0"/>
+                    <element name="row_total_with_discount" type="xsd:double" minOccurs="0"/>
+                    <element name="row_weight" type="xsd:double" minOccurs="0"/>
+                    <element name="product_type" type="xsd:string" minOccurs="0"/>
+                    <element name="base_tax_before_discount" type="xsd:double" minOccurs="0"/>
+                    <element name="tax_before_discount" type="xsd:double" minOccurs="0"/>
+                    <element name="original_custom_price" type="xsd:double" minOccurs="0"/>
+                    <element name="base_cost" type="xsd:double" minOccurs="0"/>
+                    <element name="price_incl_tax" type="xsd:double" minOccurs="0"/>
+                    <element name="base_price_incl_tax" type="xsd:double" minOccurs="0"/>
+                    <element name="row_total_incl_tax" type="xsd:double" minOccurs="0"/>
+                    <element name="base_row_total_incl_tax" type="xsd:double" minOccurs="0"/>
+                    <element name="gift_message_id" type="xsd:string" minOccurs="0"/>
+                    <element name="gift_message" type="xsd:string" minOccurs="0"/>
+                    <element name="gift_message_available" type="xsd:string" minOccurs="0"/>
+                    <element name="weee_tax_applied" type="xsd:double" minOccurs="0"/>
+                    <element name="weee_tax_applied_amount" type="xsd:double" minOccurs="0"/>
+                    <element name="weee_tax_applied_row_amount" type="xsd:double" minOccurs="0"/>
+                    <element name="base_weee_tax_applied_amount" type="xsd:double" minOccurs="0"/>
+                    <element name="base_weee_tax_applied_row_amnt" type="xsd:double" minOccurs="0"/>
+                    <element name="weee_tax_disposition" type="xsd:double" minOccurs="0"/>
+                    <element name="weee_tax_row_disposition" type="xsd:double" minOccurs="0"/>
+                    <element name="base_weee_tax_disposition" type="xsd:double" minOccurs="0"/>
+                    <element name="base_weee_tax_row_disposition" type="xsd:double" minOccurs="0"/>
+                    <element name="tax_class_id" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartItemEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:shoppingCartItemEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="shoppingCartPaymentEntity">
+                <all>
+                    <element name="payment_id" type="xsd:string" minOccurs="0"/>
+                    <element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <element name="method" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_type" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_number_enc" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_last4" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_cid_enc" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_owner" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_exp_month" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_exp_year" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_ss_owner" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_ss_start_month" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_ss_start_year" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_ss_issue" type="xsd:string" minOccurs="0"/>
+                    <element name="po_number" type="xsd:string" minOccurs="0"/>
+                    <element name="additional_data" type="xsd:string" minOccurs="0"/>
+                    <element name="additional_information" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartInfoEntity">
+                <all>
+                    <element name="store_id" type="xsd:string" minOccurs="0"/>
+                    <element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <element name="converted_at" type="xsd:string" minOccurs="0"/>
+                    <element name="quote_id" type="xsd:int" minOccurs="0"/>
+                    <element name="is_active" type="xsd:int" minOccurs="0"/>
+                    <element name="is_virtual" type="xsd:int" minOccurs="0"/>
+                    <element name="is_multi_shipping" type="xsd:int" minOccurs="0"/>
+                    <element name="items_count" type="xsd:double" minOccurs="0"/>
+                    <element name="items_qty" type="xsd:double" minOccurs="0"/>
+                    <element name="orig_order_id" type="xsd:string" minOccurs="0"/>
+                    <element name="store_to_base_rate" type="xsd:string" minOccurs="0"/>
+                    <element name="store_to_quote_rate" type="xsd:string" minOccurs="0"/>
+                    <element name="base_currency_code" type="xsd:string" minOccurs="0"/>
+                    <element name="store_currency_code" type="xsd:string" minOccurs="0"/>
+                    <element name="quote_currency_code" type="xsd:string" minOccurs="0"/>
+                    <element name="grand_total" type="xsd:string" minOccurs="0"/>
+                    <element name="base_grand_total" type="xsd:string" minOccurs="0"/>
+                    <element name="checkout_method" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_id" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_tax_class_id" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_group_id" type="xsd:int" minOccurs="0"/>
+                    <element name="customer_email" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_prefix" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_firstname" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_middlename" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_lastname" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_suffix" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_note" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_note_notify" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_is_guest" type="xsd:string" minOccurs="0"/>
+                    <element name="applied_rule_ids" type="xsd:string" minOccurs="0"/>
+                    <element name="reserved_order_id" type="xsd:string" minOccurs="0"/>
+                    <element name="password_hash" type="xsd:string" minOccurs="0"/>
+                    <element name="coupon_code" type="xsd:string" minOccurs="0"/>
+                    <element name="global_currency_code" type="xsd:string" minOccurs="0"/>
+                    <element name="base_to_global_rate" type="xsd:double" minOccurs="0"/>
+                    <element name="base_to_quote_rate" type="xsd:double" minOccurs="0"/>
+                    <element name="customer_taxvat" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_gender" type="xsd:string" minOccurs="0"/>
+                    <element name="subtotal" type="xsd:double" minOccurs="0"/>
+                    <element name="base_subtotal" type="xsd:double" minOccurs="0"/>
+                    <element name="subtotal_with_discount" type="xsd:double" minOccurs="0"/>
+                    <element name="base_subtotal_with_discount" type="xsd:double" minOccurs="0"/>
+                    <element name="ext_shipping_info" type="xsd:string" minOccurs="0"/>
+                    <element name="gift_message_id" type="xsd:string" minOccurs="0"/>
+                    <element name="gift_message" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_balance_amount_used" type="xsd:double" minOccurs="0"/>
+                    <element name="base_customer_bal_amount_used" type="xsd:double" minOccurs="0"/>
+                    <element name="use_customer_balance" type="xsd:string" minOccurs="0"/>
+                    <element name="gift_cards_amount" type="xsd:string" minOccurs="0"/>
+                    <element name="base_gift_cards_amount" type="xsd:string" minOccurs="0"/>
+                    <element name="gift_cards_amount_used" type="xsd:string" minOccurs="0"/>
+                    <element name="use_reward_points" type="xsd:string" minOccurs="0"/>
+                    <element name="reward_points_balance" type="xsd:string" minOccurs="0"/>
+                    <element name="base_reward_currency_amount" type="xsd:string" minOccurs="0"/>
+                    <element name="reward_currency_amount" type="xsd:string" minOccurs="0"/>
+                    <element name="shipping_address" type="typens:shoppingCartAddressEntity" minOccurs="0"/>
+                    <element name="billing_address" type="typens:shoppingCartAddressEntity" minOccurs="0"/>
+                    <element name="items" type="typens:shoppingCartItemEntityArray" minOccurs="0"/>
+                    <element name="payment" type="typens:shoppingCartPaymentEntity" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartTotalsEntity">
+                <all>
+                    <element name="title" type="xsd:string" minOccurs="0"/>
+                    <element name="amount" type="xsd:double" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartTotalsEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:shoppingCartTotalsEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="shoppingCartLicenseEntity">
+                <all>
+                    <element name="agreement_id" type="xsd:string" minOccurs="0"/>
+                    <element name="name" type="xsd:string" minOccurs="0"/>
+                    <element name="content" type="xsd:string" minOccurs="0"/>
+                    <element name="is_active" type="xsd:int" minOccurs="0"/>
+                    <element name="is_html" type="xsd:int" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartLicenseEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:shoppingCartLicenseEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+
+            <complexType name="shoppingCartProductEntity">
+                <all>
+                    <element name="product_id" type="xsd:string" minOccurs="0"/>
+                    <element name="sku" type="xsd:string" minOccurs="0"/>
+                    <element name="qty" type="xsd:double" minOccurs="0"/>
+                    <element name="options" type="typens:associativeArray" minOccurs="0"/>
+                    <element name="bundle_option" type="typens:associativeArray" minOccurs="0"/>
+                    <element name="bundle_option_qty" type="typens:associativeArray" minOccurs="0"/>
+                    <element name="links" type="typens:ArrayOfString" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartProductEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:shoppingCartProductEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="shoppingCartProductResponseEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="shoppingCartCustomerEntity">
+                <all>
+                    <element name="mode" type="xsd:string" minOccurs="0"/>
+                    <element name="customer_id" type="xsd:int" minOccurs="0"/>
+                    <element name="email" type="xsd:string" minOccurs="0"/>
+                    <element name="firstname" type="xsd:string" minOccurs="0"/>
+                    <element name="lastname" type="xsd:string" minOccurs="0"/>
+                    <element name="password" type="xsd:string" minOccurs="0"/>
+                    <element name="confirmation" type="xsd:string" minOccurs="0"/>
+                    <element name="website_id" type="xsd:int" minOccurs="0"/>
+                    <element name="store_id" type="xsd:int" minOccurs="0"/>
+                    <element name="group_id" type="xsd:int" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartCustomerAddressEntity">
+                <all>
+                    <element name="mode" type="xsd:string" minOccurs="0"/>
+                    <element name="address_id" type="xsd:string" minOccurs="0"/>
+                    <element name="firstname" type="xsd:string" minOccurs="0"/>
+                    <element name="lastname" type="xsd:string" minOccurs="0"/>
+                    <element name="company" type="xsd:string" minOccurs="0"/>
+                    <element name="street" type="xsd:string" minOccurs="0"/>
+                    <element name="city" type="xsd:string" minOccurs="0"/>
+                    <element name="region" type="xsd:string" minOccurs="0"/>
+                    <element name="region_id" type="xsd:string" minOccurs="0"/>
+                    <element name="postcode" type="xsd:string" minOccurs="0"/>
+                    <element name="country_id" type="xsd:string" minOccurs="0"/>
+                    <element name="telephone" type="xsd:string" minOccurs="0"/>
+                    <element name="fax" type="xsd:string" minOccurs="0"/>
+                    <element name="is_default_billing" type="xsd:int" minOccurs="0"/>
+                    <element name="is_default_shipping" type="xsd:int" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartCustomerAddressEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:shoppingCartCustomerAddressEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="shoppingCartShippingMethodEntity">
+                <all>
+                    <element name="code" type="xsd:string" minOccurs="0"/>
+                    <element name="carrier" type="xsd:string" minOccurs="0"/>
+                    <element name="carrier_title" type="xsd:string" minOccurs="0"/>
+                    <element name="method" type="xsd:string" minOccurs="0"/>
+                    <element name="method_title" type="xsd:string" minOccurs="0"/>
+                    <element name="method_description" type="xsd:string" minOccurs="0"/>
+                    <element name="price" type="xsd:double" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartShippingMethodEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:shoppingCartShippingMethodEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+
+            <complexType name="shoppingCartPaymentMethodEntity">
+                <all>
+                    <element name="po_number" type="xsd:string" minOccurs="0"/>
+                    <element name="method" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_cid" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_owner" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_number" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_type" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_exp_year" type="xsd:string" minOccurs="0"/>
+                    <element name="cc_exp_month" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartPaymentMethodResponseEntity">
+                <all>
+                    <element name="code" type="xsd:string"/>
+                    <element name="title" type="xsd:string"/>
+                    <element name="cc_types" type="typens:associativeArray"/>
+                </all>
+            </complexType>
+            <complexType name="shoppingCartPaymentMethodResponseEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:shoppingCartPaymentMethodResponseEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+        </schema>
+    </types>
+    <message name="shoppingCartCreateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartCreateResponse">
+        <part name="quoteId" type="xsd:int"/>
+    </message>
+    <message name="shoppingCartOrderRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+        <part name="licenses" type="typens:ArrayOfString"/>
+    </message>
+    <message name="shoppingCartOrderResponse">
+        <part name="result" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartOrderWithPaymentRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+        <part name="licenses" type="typens:ArrayOfString"/>
+        <part name="paymentData" type="typens:shoppingCartPaymentMethodEntity"/>
+    </message>
+    <message name="shoppingCartOrderWithPaymentResponse">
+        <part name="result" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartInfoRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartInfoResponse">
+        <part name="result" type="typens:shoppingCartInfoEntity"/>
+    </message>
+    <message name="shoppingCartTotalsRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartTotalsResponse">
+        <part name="result" type="typens:shoppingCartTotalsEntityArray"/>
+    </message>
+    <message name="shoppingCartLicenseRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartLicenseResponse">
+        <part name="result" type="typens:shoppingCartLicenseEntityArray"/>
+    </message>
+    <message name="shoppingCartProductAddRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="products" type="typens:shoppingCartProductEntityArray"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartProductAddResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartProductUpdateRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="products" type="typens:shoppingCartProductEntityArray"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartProductUpdateResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartProductRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="products" type="typens:shoppingCartProductEntityArray"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartProductRemoveResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartProductListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartProductListResponse">
+        <part name="result" type="typens:shoppingCartProductResponseEntityArray"/>
+    </message>
+    <message name="shoppingCartProductMoveToCustomerQuoteRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="products" type="typens:shoppingCartProductEntityArray"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartProductMoveToCustomerQuoteResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartCustomerSetRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="customer" type="typens:shoppingCartCustomerEntity"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartCustomerSetResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartCustomerAddressesRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="customer" type="typens:shoppingCartCustomerAddressEntityArray"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartCustomerAddressesResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartShippingMethodRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="method" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartShippingMethodResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartShippingListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartShippingListResponse">
+        <part name="result" type="typens:shoppingCartShippingMethodEntityArray"/>
+    </message>
+    <message name="shoppingCartPaymentMethodRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="paymentData" type="typens:shoppingCartPaymentMethodEntity"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartPaymentMethodResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartPaymentListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartPaymentListResponse">
+        <part name="result" type="typens:shoppingCartPaymentMethodResponseEntityArray"/>
+    </message>
+    <message name="shoppingCartCouponAddRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="couponCode" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartCouponAddResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <message name="shoppingCartCouponRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="quoteId" type="xsd:int"/>
+        <part name="store" type="xsd:string"/>
+    </message>
+    <message name="shoppingCartCouponRemoveResponse">
+        <part name="result" type="xsd:boolean"/>
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="shoppingCartCreate">
+            <documentation>Create shopping cart</documentation>
+            <input message="typens:shoppingCartCreateRequest"/>
+            <output message="typens:shoppingCartCreateResponse"/>
+        </operation>
+        <operation name="shoppingCartInfo">
+            <documentation>Retrieve information about shopping cart</documentation>
+            <input message="typens:shoppingCartInfoRequest"/>
+            <output message="typens:shoppingCartInfoResponse"/>
+        </operation>
+        <operation name="shoppingCartOrder">
+            <documentation>Create an order from shopping cart</documentation>
+            <input message="typens:shoppingCartOrderRequest"/>
+            <output message="typens:shoppingCartOrderResponse"/>
+        </operation>
+        <operation name="shoppingCartOrderWithPayment">
+            <documentation>Create an order from shopping cart with payment method</documentation>
+            <input message="typens:shoppingCartOrderWithPaymentRequest"/>
+            <output message="typens:shoppingCartOrderWithPaymentResponse"/>
+        </operation>
+        <operation name="shoppingCartTotals">
+            <documentation>Get total prices for shopping cart</documentation>
+            <input message="typens:shoppingCartTotalsRequest"/>
+            <output message="typens:shoppingCartTotalsResponse"/>
+        </operation>
+        <operation name="shoppingCartLicense">
+            <documentation>Get terms and conditions</documentation>
+            <input message="typens:shoppingCartLicenseRequest"/>
+            <output message="typens:shoppingCartLicenseResponse"/>
+        </operation>
+        <operation name="shoppingCartProductAdd">
+            <documentation>Add product(s) to shopping cart</documentation>
+            <input message="typens:shoppingCartProductAddRequest"/>
+            <output message="typens:shoppingCartProductAddResponse"/>
+        </operation>
+        <operation name="shoppingCartProductUpdate">
+            <documentation>Update product(s) quantities in shopping cart</documentation>
+            <input message="typens:shoppingCartProductUpdateRequest"/>
+            <output message="typens:shoppingCartProductUpdateResponse"/>
+        </operation>
+        <operation name="shoppingCartProductRemove">
+            <documentation>Remove product(s) from shopping cart</documentation>
+            <input message="typens:shoppingCartProductRemoveRequest"/>
+            <output message="typens:shoppingCartProductRemoveResponse"/>
+        </operation>
+        <operation name="shoppingCartProductList">
+            <documentation>Get list of products in shopping cart</documentation>
+            <input message="typens:shoppingCartProductListRequest"/>
+            <output message="typens:shoppingCartProductListResponse"/>
+        </operation>
+        <operation name="shoppingCartProductMoveToCustomerQuote">
+            <documentation>Move product(s) to customer quote</documentation>
+            <input message="typens:shoppingCartProductMoveToCustomerQuoteRequest"/>
+            <output message="typens:shoppingCartProductMoveToCustomerQuoteResponse"/>
+        </operation>
+        <operation name="shoppingCartCustomerSet">
+            <documentation>Set customer for shopping cart</documentation>
+            <input message="typens:shoppingCartCustomerSetRequest"/>
+            <output message="typens:shoppingCartCustomerSetResponse"/>
+        </operation>
+        <operation name="shoppingCartCustomerAddresses">
+            <documentation>Set customer's addresses in shopping cart</documentation>
+            <input message="typens:shoppingCartCustomerAddressesRequest"/>
+            <output message="typens:shoppingCartCustomerAddressesResponse"/>
+        </operation>
+        <operation name="shoppingCartShippingMethod">
+            <documentation>Set shipping method</documentation>
+            <input message="typens:shoppingCartShippingMethodRequest"/>
+            <output message="typens:shoppingCartShippingMethodResponse"/>
+        </operation>
+        <operation name="shoppingCartShippingList">
+            <documentation>Get list of available shipping methods</documentation>
+            <input message="typens:shoppingCartShippingListRequest"/>
+            <output message="typens:shoppingCartShippingListResponse"/>
+        </operation>
+        <operation name="shoppingCartPaymentMethod">
+            <documentation>Set payment method</documentation>
+            <input message="typens:shoppingCartPaymentMethodRequest"/>
+            <output message="typens:shoppingCartPaymentMethodResponse"/>
+        </operation>
+        <operation name="shoppingCartPaymentList">
+            <documentation>Get list of available payment methods</documentation>
+            <input message="typens:shoppingCartPaymentListRequest"/>
+            <output message="typens:shoppingCartPaymentListResponse"/>
+        </operation>
+        <operation name="shoppingCartCouponAdd">
+            <documentation>Add coupon code for shopping cart</documentation>
+            <input message="typens:shoppingCartCouponAddRequest"/>
+            <output message="typens:shoppingCartCouponAddResponse"/>
+        </operation>
+        <operation name="shoppingCartCouponRemove">
+            <documentation>Remove coupon code from shopping cart</documentation>
+            <input message="typens:shoppingCartCouponRemoveRequest"/>
+            <output message="typens:shoppingCartCouponRemoveResponse"/>
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <operation name="shoppingCartCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartTotals">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartOrder">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartOrderWithPayment">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartLicense">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartProductAdd">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartProductUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartProductRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartProductList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartProductMoveToCustomerQuote">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartCustomerSet">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartCustomerAddresses">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartShippingMethod">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartShippingList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartPaymentMethod">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartPaymentList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartCouponAdd">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="shoppingCartCouponRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+    </binding>
+</definitions>
diff --git a/app/code/core/Mage/Checkout/etc/wsi.xml b/app/code/core/Mage/Checkout/etc/wsi.xml
new file mode 100644
index 00000000000..71c218acd90
--- /dev/null
+++ b/app/code/core/Mage/Checkout/etc/wsi.xml
@@ -0,0 +1,1018 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="shoppingCartAddressEntity">
+                <xsd:sequence>
+                    <xsd:element name="address_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="save_in_address_book" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="customer_address_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="address_type" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="email" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="prefix" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="middlename" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="suffix" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="company" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="street" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="city" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="region" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="region_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="postcode" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="country_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="telephone" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="fax" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="same_as_billing" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="free_shipping" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="shipping_method" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="shipping_description" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="weight" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="fax" type="xsd:string" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartItemEntity">
+                <xsd:sequence>
+                    <xsd:element name="item_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="store_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="parent_item_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="is_virtual" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="name" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="description" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="applied_rule_ids" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="additional_data" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="free_shipping" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="is_qty_decimal" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="no_discount" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="weight" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="qty" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="price" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_price" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="custom_price" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="discount_percent" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="discount_amount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_discount_amount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="tax_percent" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="tax_amount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_tax_amount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="row_total" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_row_total" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="row_total_with_discount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="row_weight" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="product_type" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="base_tax_before_discount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="tax_before_discount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="original_custom_price" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_cost" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="price_incl_tax" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_price_incl_tax" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="row_total_incl_tax" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_row_total_incl_tax" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="gift_message_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="gift_message" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="gift_message_available" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="weee_tax_applied" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="weee_tax_applied_amount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="weee_tax_applied_row_amount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_weee_tax_applied_amount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_weee_tax_applied_row_amnt" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="weee_tax_disposition" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="weee_tax_row_disposition" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_weee_tax_disposition" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_weee_tax_row_disposition" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="tax_class_id" type="xsd:string" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartItemEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:shoppingCartItemEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartPaymentEntity">
+                <xsd:sequence>
+                    <xsd:element name="payment_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="method" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_type" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_number_enc" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_last4" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_cid_enc" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_owner" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_exp_month" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_exp_year" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_ss_owner" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_ss_start_month" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_ss_start_year" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_ss_issue" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="po_number" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="additional_data" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="additional_information" type="xsd:string" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartInfoEntity">
+                <xsd:sequence>
+                    <xsd:element name="store_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="converted_at" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="quote_id" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="is_active" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="is_virtual" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="is_multi_shipping" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="items_count" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="items_qty" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="orig_order_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="store_to_base_rate" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="store_to_quote_rate" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="base_currency_code" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="store_currency_code" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="quote_currency_code" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="grand_total" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="base_grand_total" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="checkout_method" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_tax_class_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_group_id" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="customer_email" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_prefix" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_firstname" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_middlename" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_lastname" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_suffix" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_note" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_note_notify" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_is_guest" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="applied_rule_ids" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="reserved_order_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="password_hash" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="coupon_code" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="global_currency_code" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="base_to_global_rate" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_to_quote_rate" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="customer_taxvat" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_gender" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="subtotal" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_subtotal" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="subtotal_with_discount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_subtotal_with_discount" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="ext_shipping_info" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="gift_message_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="gift_message" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_balance_amount_used" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="base_customer_bal_amount_used" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="use_customer_balance" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="gift_cards_amount" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="base_gift_cards_amount" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="gift_cards_amount_used" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="use_reward_points" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="reward_points_balance" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="base_reward_currency_amount" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="reward_currency_amount" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="shipping_address" type="typens:shoppingCartAddressEntity" minOccurs="0"/>
+                    <xsd:element name="billing_address" type="typens:shoppingCartAddressEntity" minOccurs="0"/>
+                    <xsd:element name="items" type="typens:shoppingCartItemEntityArray" minOccurs="0"/>
+                    <xsd:element name="payment" type="typens:shoppingCartPaymentEntity" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartTotalsEntity">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="amount" type="xsd:double" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartTotalsEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:shoppingCartTotalsEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartLicenseEntity">
+                <xsd:sequence>
+                    <xsd:element name="agreement_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="name" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="content" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="is_active" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="is_html" type="xsd:int" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartLicenseEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:shoppingCartLicenseEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartProductEntity">
+                <xsd:sequence>
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="qty" type="xsd:double" minOccurs="0"/>
+                    <xsd:element name="options" type="typens:associativeArray" minOccurs="0"/>
+                    <xsd:element name="bundle_option" type="typens:associativeArray" minOccurs="0"/>
+                    <xsd:element name="bundle_option_qty" type="typens:associativeArray" minOccurs="0"/>
+                    <xsd:element name="links" type="typens:ArrayOfString" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartProductEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:shoppingCartProductEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartProductResponseEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartCustomerEntity">
+                <xsd:sequence>
+                    <xsd:element name="mode" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="customer_id" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="email" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="password" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="confirmation" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="website_id" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="store_id" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="group_id" type="xsd:int" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartCustomerAddressEntity">
+                <xsd:sequence>
+                    <xsd:element name="mode" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="address_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="company" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="street" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="city" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="region" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="region_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="postcode" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="country_id" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="telephone" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="fax" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="is_default_billing" type="xsd:int" minOccurs="0"/>
+                    <xsd:element name="is_default_shipping" type="xsd:int" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartCustomerAddressEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:shoppingCartCustomerAddressEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartShippingMethodEntity">
+                <xsd:sequence>
+                    <xsd:element name="code" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="carrier" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="carrier_title" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="method" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="method_title" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="method_description" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="price" type="xsd:double" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartShippingMethodEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:shoppingCartShippingMethodEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartPaymentMethodEntity">
+                <xsd:sequence>
+                    <xsd:element name="po_number" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="method" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_cid" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_owner" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_number" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_type" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_exp_year" type="xsd:string" minOccurs="0"/>
+                    <xsd:element name="cc_exp_month" type="xsd:string" minOccurs="0"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartPaymentMethodResponseEntity">
+                <xsd:sequence>
+                    <xsd:element name="code" type="xsd:string"/>
+                    <xsd:element name="title" type="xsd:string"/>
+                    <xsd:element name="cc_types" type="typens:associativeArray"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="shoppingCartPaymentMethodResponseEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:shoppingCartPaymentMethodResponseEntity"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:element name="shoppingCartCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartOrderRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="agreements" type="typens:ArrayOfString" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartOrderResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartOrderWithPaymentRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="licenses" type="typens:ArrayOfString" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="paymentData" type="typens:shoppingCartPaymentMethodEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartOrderWithPaymentResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:shoppingCartInfoEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartTotalsRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartTotalsResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:shoppingCartTotalsEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartLicenseRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartLicenseResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:shoppingCartLicenseEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductAddRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productsData" type="typens:shoppingCartProductEntityArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductAddResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productsData" type="typens:shoppingCartProductEntityArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productsData" type="typens:shoppingCartProductEntityArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:shoppingCartProductResponseEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductMoveToCustomerQuoteRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productsData" type="typens:shoppingCartProductEntityArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartProductMoveToCustomerQuoteResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCustomerSetRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerData" type="typens:shoppingCartCustomerEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCustomerSetResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCustomerAddressesRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerAddressData" type="typens:shoppingCartCustomerAddressEntityArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCustomerAddressesResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartShippingMethodRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="shippingMethod" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartShippingMethodResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartShippingListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartShippingListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:shoppingCartShippingMethodEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartPaymentMethodRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="paymentData" type="typens:shoppingCartPaymentMethodEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartPaymentMethodResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartPaymentListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartPaymentListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:shoppingCartPaymentMethodResponseEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCouponAddRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="couponCode" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCouponAddResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCouponRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="shoppingCartCouponRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="shoppingCartCreateRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCreateResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartOrderRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartOrderRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartOrderResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartOrderResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartOrderWithPaymentRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartOrderWithPaymentRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartOrderWithPaymentResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartOrderWithPaymentResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartInfoRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartInfoResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartTotalsRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartTotalsRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartTotalsResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartTotalsResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartLicenseRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartLicenseRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartLicenseResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartLicenseResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductAddRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductAddRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductAddResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductAddResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductUpdateRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductUpdateResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductRemoveRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductRemoveResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductListRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductListResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductMoveToCustomerQuoteRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductMoveToCustomerQuoteRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartProductMoveToCustomerQuoteResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartProductMoveToCustomerQuoteResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCustomerSetRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartCustomerSetRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCustomerSetResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartCustomerSetResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCustomerAddressesRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartCustomerAddressesRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCustomerAddressesResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartCustomerAddressesResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartShippingMethodRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartShippingMethodRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartShippingMethodResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartShippingMethodResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartShippingListRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartShippingListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartShippingListResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartShippingListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartPaymentMethodRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartPaymentMethodRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartPaymentMethodResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartPaymentMethodResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartPaymentListRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartPaymentListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartPaymentListResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartPaymentListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCouponAddRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartCouponAddRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCouponAddResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartCouponAddResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCouponRemoveRequest">
+        <wsdl:part name="parameters" element="typens:shoppingCartCouponRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="shoppingCartCouponRemoveResponse">
+        <wsdl:part name="parameters" element="typens:shoppingCartCouponRemoveResponseParam" />
+    </wsdl:message>
+
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="shoppingCartCreate">
+            <wsdl:documentation>Create shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartCreateRequest"/>
+            <wsdl:output message="typens:shoppingCartCreateResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartInfo">
+            <wsdl:documentation>Retrieve information about shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartInfoRequest"/>
+            <wsdl:output message="typens:shoppingCartInfoResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartOrder">
+            <wsdl:documentation>Create an order from shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartOrderRequest"/>
+            <wsdl:output message="typens:shoppingCartOrderResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartOrderWithPayment">
+            <wsdl:documentation>Create an order from shopping cart with payment method</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartOrderWithPaymentRequest"/>
+            <wsdl:output message="typens:shoppingCartOrderWithPaymentResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartTotals">
+            <wsdl:documentation>Get total prices for shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartTotalsRequest"/>
+            <wsdl:output message="typens:shoppingCartTotalsResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartLicense">
+            <wsdl:documentation>Get terms and conditions</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartLicenseRequest"/>
+            <wsdl:output message="typens:shoppingCartLicenseResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductAdd">
+            <wsdl:documentation>Add product(s) to shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartProductAddRequest"/>
+            <wsdl:output message="typens:shoppingCartProductAddResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductUpdate">
+            <wsdl:documentation>Update product(s) quantities in shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartProductUpdateRequest"/>
+            <wsdl:output message="typens:shoppingCartProductUpdateResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductRemove">
+            <wsdl:documentation>Remove product(s) from shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartProductRemoveRequest"/>
+            <wsdl:output message="typens:shoppingCartProductRemoveResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductList">
+            <wsdl:documentation>Get list of products in shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartProductListRequest"/>
+            <wsdl:output message="typens:shoppingCartProductListResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductMoveToCustomerQuote">
+            <wsdl:documentation>Move product(s) to customer quote</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartProductMoveToCustomerQuoteRequest"/>
+            <wsdl:output message="typens:shoppingCartProductMoveToCustomerQuoteResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartCustomerSet">
+            <wsdl:documentation>Set customer for shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartCustomerSetRequest"/>
+            <wsdl:output message="typens:shoppingCartCustomerSetResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartCustomerAddresses">
+            <wsdl:documentation>Set customer's addresses in shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartCustomerAddressesRequest"/>
+            <wsdl:output message="typens:shoppingCartCustomerAddressesResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartShippingMethod">
+            <wsdl:documentation>Set shipping method</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartShippingMethodRequest"/>
+            <wsdl:output message="typens:shoppingCartShippingMethodResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartShippingList">
+            <wsdl:documentation>Get list of available shipping methods</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartShippingListRequest"/>
+            <wsdl:output message="typens:shoppingCartShippingListResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartPaymentMethod">
+            <wsdl:documentation>Set payment method</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartPaymentMethodRequest"/>
+            <wsdl:output message="typens:shoppingCartPaymentMethodResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartPaymentList">
+            <wsdl:documentation>Get list of available payment methods</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartPaymentListRequest"/>
+            <wsdl:output message="typens:shoppingCartPaymentListResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartCouponAdd">
+            <wsdl:documentation>Add coupon code for shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartCouponAddRequest"/>
+            <wsdl:output message="typens:shoppingCartCouponAddResponse"/>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartCouponRemove">
+            <wsdl:documentation>Remove coupon code from shopping cart</wsdl:documentation>
+            <wsdl:input message="typens:shoppingCartCouponRemoveRequest"/>
+            <wsdl:output message="typens:shoppingCartCouponRemoveResponse"/>
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <wsdl:operation name="shoppingCartCreate">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartInfo">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartTotals">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartOrder">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartOrderWithPayment">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartLicense">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductAdd">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductUpdate">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductRemove">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductList">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartProductMoveToCustomerQuote">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartCustomerSet">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartCustomerAddresses">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartShippingMethod">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartShippingList">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartPaymentMethod">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartPaymentList">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartCouponAdd">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="shoppingCartCouponRemove">
+            <soap:operation soapAction=""/>
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/Cms/Helper/Wysiwyg/Images.php b/app/code/core/Mage/Cms/Helper/Wysiwyg/Images.php
index d9b871fbe09..a282b00c54a 100644
--- a/app/code/core/Mage/Cms/Helper/Wysiwyg/Images.php
+++ b/app/code/core/Mage/Cms/Helper/Wysiwyg/Images.php
@@ -86,7 +86,7 @@ class Mage_Cms_Helper_Wysiwyg_Images extends Mage_Core_Helper_Abstract
      */
     public function getStorageRoot()
     {
-        return Mage::getConfig()->getOptions()->getMediaDir() . DS . Mage_Cms_Model_Wysiwyg_Config::IMAGE_DIRECTORY
+        return Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA) . DS . Mage_Cms_Model_Wysiwyg_Config::IMAGE_DIRECTORY
             . DS;
     }
 
@@ -247,7 +247,7 @@ class Mage_Cms_Helper_Wysiwyg_Images extends Mage_Core_Helper_Abstract
     public function getCurrentUrl()
     {
         if (!$this->_currentUrl) {
-            $path = str_replace(Mage::getConfig()->getOptions()->getMediaDir(), '', $this->getCurrentPath());
+            $path = str_replace(Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA), '', $this->getCurrentPath());
             $path = trim($path, DS);
             $this->_currentUrl = Mage::app()->getStore($this->_storeId)->getBaseUrl('media') .
                                  $this->convertPathToUrl($path) . '/';
diff --git a/app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php
index abcd1c2839e..f9915a25832 100644
--- a/app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php
+++ b/app/code/core/Mage/Cms/Model/Wysiwyg/Images/Storage.php
@@ -430,7 +430,7 @@ class Mage_Cms_Model_Wysiwyg_Images_Storage extends Varien_Object
      */
     public function getThumbsPath($filePath = false)
     {
-        $mediaRootDir = Mage::getConfig()->getOptions()->getMediaDir();
+        $mediaRootDir = Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA);
         $thumbnailDir = $this->getThumbnailRoot();
 
         if ($filePath && strpos($filePath, $mediaRootDir) === 0) {
diff --git a/app/code/core/Mage/Connect/Block/Adminhtml/Extension/Custom/Edit/Tab/Local.php b/app/code/core/Mage/Connect/Block/Adminhtml/Extension/Custom/Edit/Tab/Local.php
index 69afaf06fbf..e7f6898aa72 100644
--- a/app/code/core/Mage/Connect/Block/Adminhtml/Extension/Custom/Edit/Tab/Local.php
+++ b/app/code/core/Mage/Connect/Block/Adminhtml/Extension/Custom/Edit/Tab/Local.php
@@ -32,7 +32,7 @@
  * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Mage_Connect_Block_Adminhtml_Extension_Custom_Edit_Tab_Local
-    extends Mage_Adminhtml_Block_Abstract
+    extends Mage_Core_Block_Template
     implements Mage_Adminhtml_Block_Widget_Tab_Interface
 {
     /**
diff --git a/app/code/core/Mage/Connect/Model/Extension.php b/app/code/core/Mage/Connect/Model/Extension.php
index 88b5769ac0e..33bd0947326 100644
--- a/app/code/core/Mage/Connect/Model/Extension.php
+++ b/app/code/core/Mage/Connect/Model/Extension.php
@@ -293,8 +293,10 @@ class Mage_Connect_Model_Extension extends Varien_Object
     public function createPackage()
     {
         $path = Mage::helper('Mage_Connect_Helper_Data')->getLocalPackagesPath();
-        if (!Mage::getConfig()->createDirIfNotExists($path)) {
-            return false;
+        if (!is_dir($path)) {
+            if (!mkdir($path)) {
+                return false;
+            }
         }
         if (!$this->getPackageXml()) {
             $this->generatePackageXml();
@@ -311,8 +313,10 @@ class Mage_Connect_Model_Extension extends Varien_Object
     public function createPackageV1x()
     {
         $path = Mage::helper('Mage_Connect_Helper_Data')->getLocalPackagesPathV1x();
-        if (!Mage::getConfig()->createDirIfNotExists($path)) {
-            return false;
+        if (!is_dir($path)) {
+            if (!mkdir($path)) {
+                return false;
+            }
         }
         if (!$this->getPackageXml()) {
             $this->generatePackageXml();
diff --git a/app/code/core/Mage/Core/Block/Template.php b/app/code/core/Mage/Core/Block/Template.php
index 3d16eea7303..c68abf10665 100644
--- a/app/code/core/Mage/Core/Block/Template.php
+++ b/app/code/core/Mage/Core/Block/Template.php
@@ -38,13 +38,6 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
     const XML_PATH_DEBUG_TEMPLATE_HINTS_BLOCKS  = 'dev/debug/template_hints_blocks';
     const XML_PATH_TEMPLATE_ALLOW_SYMLINK       = 'dev/template/allow_symlink';
 
-    /**
-     * View scripts directory
-     *
-     * @var string
-     */
-    protected $_viewDir = '';
-
     /**
      * Assigned variables for view
      *
@@ -67,11 +60,14 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
     protected static $_showTemplateHintsBlocks;
 
     /**
-     * Path to template file in theme.
-     *
-     * @var string
+     * @var Mage_Core_Model_Dir
      */
-    protected $_template;
+    protected $_dirs;
+
+    /**
+     * @var Mage_Core_Model_Logger
+     */
+    protected $_logger;
 
     /**
      * @var Magento_Filesystem
@@ -79,6 +75,14 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
     protected $_filesystem;
 
     /**
+     * Path to template file in theme.
+     *
+     * @var string
+     */
+    protected $_template;
+
+    /**
+     * Constructor
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -90,6 +94,8 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param array $data
      *
@@ -107,24 +113,16 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         array $data = array()
     ) {
-        parent::__construct(
-            $request,
-            $layout,
-            $eventManager,
-            $urlBuilder,
-            $translator,
-            $cache,
-            $designPackage,
-            $session,
-            $storeConfig,
-            $frontController,
-            $helperFactory,
-            $data
-        );
+        $this->_dirs = $dirs;
+        $this->_logger = $logger;
         $this->_filesystem = $filesystem;
+        parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
+            $session, $storeConfig, $frontController, $helperFactory, $data);
     }
 
     /**
@@ -179,7 +177,7 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
         if ($area) {
             $params['area'] = $area;
         }
-        $templateName = Mage::getDesign()->getFilename($this->getTemplate(), $params);
+        $templateName = $this->_designPackage->getFilename($this->getTemplate(), $params);
         return $templateName;
     }
 
@@ -215,24 +213,6 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
         return $this;
     }
 
-    /**
-     * Set template location directory
-     *
-     * @param string $dir
-     * @return Mage_Core_Block_Template
-     */
-    public function setScriptPath($dir)
-    {
-        if (Magento_Filesystem::isPathInDirectory($dir, Mage::getBaseDir('design'))
-            || $this->_getAllowSymlinks()
-        ) {
-            $this->_viewDir = $dir;
-        } else {
-            Mage::log('Not valid script path:' . $dir, Zend_Log::CRIT, null, true);
-        }
-        return $this;
-    }
-
     /**
      * Check if direct output is allowed for block
      *
@@ -266,7 +246,7 @@ class Mage_Core_Block_Template extends Mage_Core_Block_Abstract
      */
     public function fetchView($fileName)
     {
-        $viewShortPath = str_replace(Mage::getBaseDir(), '', $fileName);
+        $viewShortPath = str_replace($this->_dirs->getDir(Mage_Core_Model_Dir::ROOT), '', $fileName);
         Magento_Profiler::start('TEMPLATE:' . $fileName, array('group' => 'TEMPLATE', 'file_name' => $viewShortPath));
 
         // EXTR_SKIP protects from overriding
@@ -295,13 +275,13 @@ HTML;
         }
 
         try {
-            if ((Magento_Filesystem::isPathInDirectory($fileName, Mage::getBaseDir('app'))
-                || Magento_Filesystem::isPathInDirectory($fileName, $this->_viewDir)
+            if ((Magento_Filesystem::isPathInDirectory($fileName, $this->_dirs->getDir(Mage_Core_Model_Dir::APP))
+                || Magento_Filesystem::isPathInDirectory($fileName, $this->_dirs->getDir(Mage_Core_Model_Dir::THEMES))
                 || $this->_getAllowSymlinks()) && $this->_filesystem->isFile($fileName)
             ) {
                 include $fileName;
             } else {
-                Mage::log("Invalid template file: '{$fileName}'", Zend_Log::CRIT, null, true);
+                $this->_logger->log("Invalid template file: '{$fileName}'", Zend_Log::CRIT);
             }
 
         } catch (Exception $e) {
@@ -325,29 +305,16 @@ HTML;
     }
 
     /**
-     * Render block
+     * Render block HTML
      *
      * @return string
      */
-    public function renderView()
+    protected function _toHtml()
     {
         if (!$this->getTemplate()) {
             return '';
         }
-        $this->setScriptPath(Mage::getBaseDir('design'));
-        $html = $this->fetchView($this->getTemplateFile());
-        return $html;
-    }
-
-    /**
-     * Render block HTML
-     *
-     * @return string
-     */
-    protected function _toHtml()
-    {
-        $html = $this->renderView();
-        return $html;
+        return $this->fetchView($this->getTemplateFile());
     }
 
     /**
diff --git a/app/code/core/Mage/Core/Controller/Varien/Router/Base.php b/app/code/core/Mage/Core/Controller/Varien/Router/Base.php
index f14298d53d5..cc761c071b5 100644
--- a/app/code/core/Mage/Core/Controller/Varien/Router/Base.php
+++ b/app/code/core/Mage/Core/Controller/Varien/Router/Base.php
@@ -56,7 +56,7 @@ class Mage_Core_Controller_Varien_Router_Base extends Mage_Core_Controller_Varie
     protected $_baseController;
 
     /**
-     * @var Magento_ObjectManager
+     * @var Mage_Core_Model_App
      */
     protected $_app;
 
@@ -90,11 +90,11 @@ class Mage_Core_Controller_Varien_Router_Base extends Mage_Core_Controller_Varie
     public function collectRoutes($configArea, $useRouterName)
     {
         $routers = array();
-        $routersConfigNode = Mage::getConfig()->getNode($configArea.'/routers');
+        $routersConfigNode = Mage::getConfig()->getNode($configArea . '/routers');
         if ($routersConfigNode) {
             $routers = $routersConfigNode->children();
         }
-        foreach ($routers as $routerName=>$routerConfig) {
+        foreach ($routers as $routerName => $routerConfig) {
             $use = (string)$routerConfig->use;
             if ($use == $useRouterName) {
                 $modules = array((string)$routerConfig->args->module);
@@ -178,7 +178,7 @@ class Mage_Core_Controller_Varien_Router_Base extends Mage_Core_Controller_Varie
             return null;
         }
 
-        $this->_app->loadDiConfiguration($this->_areaCode);
+        $this->_app->getConfig()->loadDiConfiguration($this->_areaCode);
 
         return $this->_matchController($request, $params);
     }
@@ -212,7 +212,7 @@ class Mage_Core_Controller_Varien_Router_Base extends Mage_Core_Controller_Varie
         }
 
         for ($i = 0, $l = sizeof($params); $i < $l; $i += 2) {
-            $output['variables'][$params[$i]] = isset($params[$i+1]) ? urldecode($params[$i+1]) : '';
+            $output['variables'][$params[$i]] = isset($params[$i+1]) ? urldecode($params[$i + 1]) : '';
         }
         return $output;
     }
@@ -386,7 +386,7 @@ class Mage_Core_Controller_Varien_Router_Base extends Mage_Core_Controller_Varie
             $action = $this->_matchActionName($request, $params['actionName']);
 
             //checking if this place should be secure
-            $this->_checkShouldBeSecure($request, '/'.$moduleFrontName.'/'.$controller.'/'.$action);
+            $this->_checkShouldBeSecure($request, '/' . $moduleFrontName . '/' . $controller . '/' . $action);
 
             $controllerClassName = $this->_validateControllerClassName($moduleName, $controller);
             if (false == $controllerClassName) {
@@ -558,7 +558,7 @@ class Mage_Core_Controller_Varien_Router_Base extends Mage_Core_Controller_Varie
         if (count($parts)) {
             $file .= DS . implode(DS, $parts);
         }
-        $file .= DS.uc_words($controller, DS).'Controller.php';
+        $file .= DS . uc_words($controller, DS) . 'Controller.php';
         return $file;
     }
 
@@ -576,7 +576,7 @@ class Mage_Core_Controller_Varien_Router_Base extends Mage_Core_Controller_Varie
 
     public function getControllerClassName($realModule, $controller)
     {
-        $class = $realModule.'_'.uc_words($controller).'Controller';
+        $class = $realModule . '_' . uc_words($controller) . 'Controller';
         return $class;
     }
 
@@ -641,11 +641,12 @@ class Mage_Core_Controller_Varien_Router_Base extends Mage_Core_Controller_Varie
 
     protected function _getCurrentSecureUrl($request)
     {
-        if ($alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS)) {
-            return Mage::getBaseUrl('link', true).ltrim($alias, '/');
+        $alias = $request->getAlias(Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS);
+        if ($alias) {
+            return Mage::getBaseUrl('link', true) . ltrim($alias, '/');
         }
 
-        return Mage::getBaseUrl('link', true).ltrim($request->getPathInfo(), '/');
+        return Mage::getBaseUrl('link', true) . ltrim($request->getPathInfo(), '/');
     }
 
     /**
diff --git a/app/code/core/Mage/Core/Helper/Data.php b/app/code/core/Mage/Core/Helper/Data.php
index f32493c6e69..523d5a50972 100644
--- a/app/code/core/Mage/Core/Helper/Data.php
+++ b/app/code/core/Mage/Core/Helper/Data.php
@@ -89,11 +89,10 @@ class Mage_Core_Helper_Data extends Mage_Core_Helper_Abstract
     {
         if ($this->_encryptor === null) {
             $encryptionModel = (string)Mage::getConfig()->getNode(self::XML_PATH_ENCRYPTION_MODEL);
-            if ($encryptionModel) {
-                $this->_encryptor = new $encryptionModel;
-            } else {
-                $this->_encryptor = Mage::getModel('Mage_Core_Model_Encryption');
+            if (empty($encryptionModel)) {
+                $encryptionModel = 'Mage_Core_Model_Encryption';
             }
+            $this->_encryptor = Mage::getModel($encryptionModel);
 
             $this->_encryptor->setHelper($this);
         }
diff --git a/app/code/core/Mage/Core/Model/App.php b/app/code/core/Mage/Core/Model/App.php
index eabc2776843..aa38dca9352 100644
--- a/app/code/core/Mage/Core/Model/App.php
+++ b/app/code/core/Mage/Core/Model/App.php
@@ -35,6 +35,34 @@
  */
 class Mage_Core_Model_App
 {
+    /**
+     * Scope code initialization option
+     */
+    const INIT_OPTION_SCOPE_CODE = 'MAGE_RUN_CODE';
+
+    /**
+     * Scope type initialization option
+     */
+    const INIT_OPTION_SCOPE_TYPE = 'MAGE_RUN_TYPE';
+
+    /**
+     * Custom directory paths initialization option
+     */
+    const INIT_OPTION_URIS = 'app_uris';
+
+    /**
+     * Custom directory absolute paths initialization option
+     */
+    const INIT_OPTION_DIRS = 'app_dirs';
+
+    /**#@+
+     * Available scope types
+     */
+    const SCOPE_TYPE_STORE   = 'store';
+    const SCOPE_TYPE_GROUP   = 'group';
+    const SCOPE_TYPE_WEBSITE = 'website';
+    /**#@-*/
+
     const XML_PATH_INSTALL_DATE = 'global/install/date';
 
     const XML_PATH_SKIP_PROCESS_MODULES_UPDATES = 'global/skip_process_modules_updates';
@@ -74,10 +102,6 @@ class Mage_Core_Model_App
      */
     const ADMIN_STORE_ID = 0;
 
-    /**
-     * Dependency injection configuration node name
-     */
-    const CONFIGURATION_DI_NODE = 'di';
 
     /**
      * Application loaded areas array
@@ -121,6 +145,13 @@ class Mage_Core_Model_App
      */
     protected $_design;
 
+    /**
+     * Initialization parameters
+     *
+     * @var array
+     */
+    protected $_initParams = null;
+
     /**
      * Application configuration object
      *
@@ -210,7 +241,6 @@ class Mage_Core_Model_App
      */
     protected $_response;
 
-
     /**
      * Events cache
      *
@@ -268,32 +298,32 @@ class Mage_Core_Model_App
     /**
      * Initialize application without request processing
      *
-     * @param  string|array $code
-     * @param  string $type
-     * @param  string|array $options
+     * @param  array $params
      * @return Mage_Core_Model_App
      */
-    public function init($code, $type = null, $options = array())
+    public function init(array $params)
     {
         $this->_initEnvironment();
-        if (is_string($options)) {
-            $options = array('etc_dir'=>$options);
-        }
+        $this->_initParams = $params;
+        $this->_initFilesystem();
+        $logger = $this->_initLogger();
 
         Magento_Profiler::start('init_config');
-        $this->_config = Mage::getConfig();
-        $this->_config->setOptions($options);
+        /** @var $config Mage_Core_Model_Config */
+        $config = $this->_objectManager->create('Mage_Core_Model_Config');
+        $this->_config = $config;
         $this->_initBaseConfig();
-        $logger = $this->_initLogger();
         $this->_initCache();
-        $this->_config->init($options);
+        $this->_config->init();
         $this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
-        $this->loadDiConfiguration();
         Magento_Profiler::stop('init_config');
 
-        if (Mage::isInstalled($options)) {
-            $this->_initCurrentStore($code, $type);
-            $logger->initForStore($this->_store);
+        if (Mage::isInstalled()) {
+            $this->_initCurrentStore(
+                $this->getInitParam(self::INIT_OPTION_SCOPE_CODE),
+                $this->getInitParam(self::INIT_OPTION_SCOPE_TYPE) ?: self::SCOPE_TYPE_STORE
+            );
+            $logger->initForStore($this->_store, $this->_config);
             $this->_initRequest();
         }
         return $this;
@@ -302,19 +332,21 @@ class Mage_Core_Model_App
     /**
      * Common logic for all run types
      *
-     * @param  string|array $options
+     * @param  array $params
      * @return Mage_Core_Model_App
      */
-    public function baseInit($options)
+    public function baseInit(array $params)
     {
         $this->_initEnvironment();
+        $this->_initParams = $params;
+        $this->_initFilesystem();
+        $this->_initLogger();
 
-        $this->_config = Mage::getConfig();
-        $this->_config->setOptions($options);
-
+        /** @var $config Mage_Core_Model_Config */
+        $config = $this->_objectManager->get('Mage_Core_Model_Config');
+        $this->_config = $config;
         $this->_initBaseConfig();
-        $cacheInitOptions = is_array($options) && array_key_exists('cache', $options) ? $options['cache'] : array();
-        $this->_initCache($cacheInitOptions);
+        $this->_initCache($this->getInitParam(Mage_Core_Model_Cache::APP_INIT_PARAM) ?: array());
 
         return $this;
     }
@@ -324,43 +356,37 @@ class Mage_Core_Model_App
      *
      * @see Mage_Core_Model_App->run()
      *
-     * @param  string|array $scopeCode
-     * @param  string $scopeType
-     * @param  string|array $options
+     * @param  array $params
      * @param  string|array $modules
      * @return Mage_Core_Model_App
      */
-    public function initSpecified($scopeCode, $scopeType = null, $options = array(), $modules = array())
+    public function initSpecified(array $params, $modules = array())
     {
-        $this->baseInit($options);
+        $this->baseInit($params);
 
         if (!empty($modules)) {
             $this->_config->addAllowedModules($modules);
         }
         $this->_initModules();
-        $this->_initCurrentStore($scopeCode, $scopeType);
+        $this->_initCurrentStore(
+            $this->getInitParam(self::INIT_OPTION_SCOPE_CODE),
+            $this->getInitParam(self::INIT_OPTION_SCOPE_TYPE) ?: self::SCOPE_TYPE_STORE
+        );
 
         return $this;
     }
 
     /**
      * Run application. Run process responsible for request processing and sending response.
-     * List of supported parameters:
-     *  scope_code - code of default scope (website/store_group/store code)
-     *  scope_type - type of default scope (website/group/store)
-     *  options    - configuration options
      *
-     * @param  array $params application run parameters
+     * @param array $params
      * @return Mage_Core_Model_App
      */
-    public function run($params)
+    public function run(array $params)
     {
-        $options = isset($params['options']) ? $params['options'] : array();
-
         Magento_Profiler::start('init');
 
-        $this->baseInit($options);
-        Mage::register('application_params', $params);
+        $this->baseInit($params);
 
         Magento_Profiler::stop('init');
 
@@ -368,16 +394,18 @@ class Mage_Core_Model_App
             $this->getResponse()->sendResponse();
         } else {
             Magento_Profiler::start('init');
-            $logger = $this->_initLogger();
+
             $this->_initModules();
             $this->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
-            $this->loadDiConfiguration();
 
             if ($this->_config->isLocalConfigLoaded()) {
-                $scopeCode = isset($params['scope_code']) ? $params['scope_code'] : '';
-                $scopeType = isset($params['scope_type']) ? $params['scope_type'] : 'store';
-                $this->_initCurrentStore($scopeCode, $scopeType);
-                $logger->initForStore($this->_store);
+                $this->_initCurrentStore(
+                    $this->getInitParam(self::INIT_OPTION_SCOPE_CODE),
+                    $this->getInitParam(self::INIT_OPTION_SCOPE_TYPE) ?: self::SCOPE_TYPE_STORE
+                );
+                /** @var $logger Mage_Core_Model_Logger */
+                $logger = $this->_objectManager->get('Mage_Core_Model_Logger');
+                $logger->initForStore($this->_store, $this->_config);
                 $this->_initRequest();
                 Mage_Core_Model_Resource_Setup::applyAllDataUpdates();
             }
@@ -389,6 +417,19 @@ class Mage_Core_Model_App
         return $this;
     }
 
+    /**
+     * Get initialization parameter
+     *
+     * Returns false if key does not exist in array or the value is null
+     *
+     * @param string $key
+     * @return mixed|bool
+     */
+    public function getInitParam($key)
+    {
+        return isset($this->_initParams[$key]) ? $this->_initParams[$key] : false;
+    }
+
     /**
      * Whether the application has been installed or not
      *
@@ -423,6 +464,23 @@ class Mage_Core_Model_App
         return $this;
     }
 
+    /**
+     * Create necessary directories in the file system
+     */
+    protected function _initFileSystem()
+    {
+        $customDirs = $this->getInitParam(self::INIT_OPTION_URIS) ?: array();
+        $customPaths = $this->getInitParam(self::INIT_OPTION_DIRS) ?: array();
+        $dirs = new Mage_Core_Model_Dir(BP, $customDirs, $customPaths);
+        $this->_objectManager->addSharedInstance($dirs, 'Mage_Core_Model_Dir');
+        foreach (Mage_Core_Model_Dir::getWritableDirCodes() as $code) {
+            $path = $dirs->getDir($code);
+            if ($path && !is_dir($path)) {
+                mkdir($path);
+            }
+        }
+    }
+
     /**
      * Initialize base system configuration (local.xml and config.xml files).
      * Base configuration provide ability initialize DB connection and cache backend
@@ -488,7 +546,7 @@ class Mage_Core_Model_App
     protected function _initLogger()
     {
         /** @var $logger Mage_Core_Model_Logger */
-        $logger = $this->_objectManager->get('Mage_Core_Model_Logger');
+        $logger = $this->_objectManager->create('Mage_Core_Model_Logger');
         $logger->addStreamLog(Mage_Core_Model_Logger::LOGGER_SYSTEM)
             ->addStreamLog(Mage_Core_Model_Logger::LOGGER_EXCEPTION);
         return $logger;
@@ -540,16 +598,16 @@ class Mage_Core_Model_App
 
         if (empty($scopeCode) && !is_null($this->_website)) {
             $scopeCode = $this->_website->getCode();
-            $scopeType = 'website';
+            $scopeType = self::SCOPE_TYPE_WEBSITE;
         }
         switch ($scopeType) {
-            case Mage_Core_Model_App_Options::APP_RUN_TYPE_STORE:
+            case self::SCOPE_TYPE_STORE:
                 $this->_currentStore = $scopeCode;
                 break;
-            case Mage_Core_Model_App_Options::APP_RUN_TYPE_GROUP:
+            case self::SCOPE_TYPE_GROUP:
                 $this->_currentStore = $this->_getStoreByGroup($scopeCode);
                 break;
-            case Mage_Core_Model_App_Options::APP_RUN_TYPE_WEBSITE:
+            case self::SCOPE_TYPE_WEBSITE:
                 $this->_currentStore = $this->_getStoreByWebsite($scopeCode);
                 break;
             default:
@@ -1109,7 +1167,7 @@ class Mage_Core_Model_App
     public function getGroup($id = null)
     {
         if (is_null($id)) {
-            $id = $this->getStore()->getGroup()->getId();
+            $id = $this->getStore()->getGroupId();
         } elseif ($id instanceof Mage_Core_Model_Store_Group) {
             return $id;
         }
@@ -1612,18 +1670,4 @@ class Mage_Core_Model_App
     {
         return Mage::getIsDeveloperMode();
     }
-
-    /**
-     * Load di configuration for given area
-     *
-     * @param string $areaCode
-     */
-    public function loadDiConfiguration($areaCode = Mage_Core_Model_App_Area::AREA_GLOBAL)
-    {
-        $configurationNode = $this->_config->getNode($areaCode . '/' . self::CONFIGURATION_DI_NODE);
-        if ($configurationNode) {
-            $configuration = $configurationNode->asArray();
-            $this->_objectManager->setConfiguration($configuration);
-        }
-    }
 }
diff --git a/app/code/core/Mage/Core/Model/App/Emulation.php b/app/code/core/Mage/Core/Model/App/Emulation.php
index b1dd0f4178f..438c732d9ee 100644
--- a/app/code/core/Mage/Core/Model/App/Emulation.php
+++ b/app/code/core/Mage/Core/Model/App/Emulation.php
@@ -130,7 +130,7 @@ class Mage_Core_Model_App_Emulation extends Varien_Object
             'store' => Mage::app()->getStore()
         );
 
-        $storeTheme = $design->getConfigurationDesignTheme($area, array('useId' => true, 'store' => $storeId));
+        $storeTheme = $design->getConfigurationDesignTheme($area, array('store' => $storeId));
         $design->setDesignTheme($storeTheme, $area);
 
         if ($area == Mage_Core_Model_App_Area::AREA_FRONTEND) {
diff --git a/app/code/core/Mage/Core/Model/App/Options.php b/app/code/core/Mage/Core/Model/App/Options.php
deleted file mode 100644
index 960dc267a36..00000000000
--- a/app/code/core/Mage/Core/Model/App/Options.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.
- *
- * @category    Mage
- * @package     Mage_Core
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-class Mage_Core_Model_App_Options
-{
-    /**@+
-     * Application option names
-     */
-    const OPTION_APP_RUN_CODE            = 'MAGE_RUN_CODE';
-    const OPTION_APP_RUN_TYPE            = 'MAGE_RUN_TYPE';
-    const OPTION_LOCAL_CONFIG_EXTRA_FILE = 'MAGE_LOCAL_CONFIG';
-    /**@-*/
-
-    /**@+
-     * Supported application run types
-     */
-    const APP_RUN_TYPE_STORE    = 'store';
-    const APP_RUN_TYPE_GROUP    = 'group';
-    const APP_RUN_TYPE_WEBSITE  = 'website';
-    /**@-*/
-
-    /**
-     * Shorthand for the list of supported application run types
-     *
-     * @var array
-     */
-    protected $_supportedRunTypes = array(
-        self::APP_RUN_TYPE_STORE, self::APP_RUN_TYPE_GROUP, self::APP_RUN_TYPE_WEBSITE
-    );
-
-    /**
-     * Store or website code
-     *
-     * @var string
-     */
-    protected $_runCode = '';
-
-    /**
-     * Run store or run website
-     *
-     * @var string
-     */
-    protected $_runType = self::APP_RUN_TYPE_STORE;
-
-    /**
-     * Application run options
-     *
-     * @var array
-     */
-    protected $_runOptions = array();
-
-    /**
-     * Constructor
-     *
-     * @param array $options Source of option values
-     * @throws InvalidArgumentException
-     */
-    public function __construct(array $options)
-    {
-        if (isset($options[self::OPTION_APP_RUN_CODE])) {
-            $this->_runCode = $options[self::OPTION_APP_RUN_CODE];
-        }
-
-        if (isset($options[self::OPTION_APP_RUN_TYPE])) {
-            $this->_runType = $options[self::OPTION_APP_RUN_TYPE];
-            if (!in_array($this->_runType, $this->_supportedRunTypes)) {
-                throw new InvalidArgumentException(sprintf(
-                    'Application run type "%s" is not recognized, supported values: "%s".',
-                    $this->_runType,
-                    implode('", "', $this->_supportedRunTypes)
-                ));
-            }
-        }
-
-        if (!empty($options[self::OPTION_LOCAL_CONFIG_EXTRA_FILE])) {
-            $localConfigFile = $options[self::OPTION_LOCAL_CONFIG_EXTRA_FILE];
-            $this->_runOptions[Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_FILE] = $localConfigFile;
-        }
-    }
-
-    /**
-     * Retrieve application run code
-     *
-     * @return string
-     */
-    public function getRunCode()
-    {
-        return $this->_runCode;
-    }
-
-    /**
-     * Retrieve application run type
-     *
-     * @return string
-     */
-    public function getRunType()
-    {
-        return $this->_runType;
-    }
-
-    /**
-     * Retrieve application run options
-     *
-     * @return array
-     */
-    public function getRunOptions()
-    {
-        return $this->_runOptions;
-    }
-}
diff --git a/app/code/core/Mage/Core/Model/Cache.php b/app/code/core/Mage/Core/Model/Cache.php
index 9104d3f6302..217f503840b 100644
--- a/app/code/core/Mage/Core/Model/Cache.php
+++ b/app/code/core/Mage/Core/Model/Cache.php
@@ -37,9 +37,9 @@ class Mage_Core_Model_Cache
     const XML_PATH_TYPES    = 'global/cache/types';
 
     /**
-     * @var Mage_Core_Model_Config
+     * Inject custom cache settings in application initialization
      */
-    protected $_config;
+    const APP_INIT_PARAM = 'cache';
 
     /**
      * @var Mage_Core_Helper_Abstract
@@ -107,17 +107,25 @@ class Mage_Core_Model_Cache
      */
     protected $_allowedCacheOptions = null;
 
+    /**
+     * @var Magento_ObjectManager
+     */
+    protected $_objectManager;
+
     /**
      * Class constructor. Initialize cache instance based on options
      *
+     * @param Mage_Core_Model_App $app
+     * @param Mage_Core_Model_Dir $dirs
      * @param array $options
      */
-    public function __construct(array $options = array())
+    public function __construct(Magento_ObjectManager $objectManager, array $options = array())
     {
-        $this->_config = isset($options['config']) ? $options['config'] : Mage::getConfig();
+        $this->_objectManager = $objectManager;
         $this->_helper = isset($options['helper']) ? $options['helper'] : Mage::helper('Mage_Core_Helper_Data');
 
-        $this->_defaultBackendOptions['cache_dir'] = $this->_config->getOptions()->getDir('cache');
+        $dirs = $objectManager->get('Mage_Core_Model_Dir');
+        $this->_defaultBackendOptions['cache_dir'] = $dirs->getDir(Mage_Core_Model_Dir::CACHE);
         /**
          * Initialize id prefix
          */
@@ -126,7 +134,7 @@ class Mage_Core_Model_Cache
             $this->_idPrefix = $options['prefix'];
         }
         if (empty($this->_idPrefix)) {
-            $this->_idPrefix = substr(md5($this->_config->getOptions()->getEtcDir()), 0, 3).'_';
+            $this->_idPrefix = substr(md5($dirs->getDir(Mage_Core_Model_Dir::CONFIG)), 0, 3) . '_';
         }
 
         $backend = $this->_getBackendOptions($options);
@@ -563,7 +571,7 @@ class Mage_Core_Model_Cache
             $this->_allowedCacheOptions = unserialize($options);
         }
 
-        if ($this->_config->getOptions()->getData('global_ban_use_cache')) {
+        if ($this->_objectManager->get('Mage_Core_Model_App')->getInitParam('global_ban_use_cache')) {
             foreach ($this->_allowedCacheOptions as $key => $val) {
                 $this->_allowedCacheOptions[$key] = false;
             }
@@ -641,7 +649,7 @@ class Mage_Core_Model_Cache
     public function getTagsByType($type)
     {
         $path = self::XML_PATH_TYPES.'/'.$type.'/tags';
-        $tagsConfig = $this->_config->getNode($path);
+        $tagsConfig = $this->_objectManager->get('Mage_Core_Model_Config')->getNode($path);
         if ($tagsConfig) {
             $tags = (string) $tagsConfig;
             $tags = explode(',', $tags);
@@ -659,7 +667,7 @@ class Mage_Core_Model_Cache
     public function getTypes()
     {
         $types = array();
-        $config = $this->_config->getNode(self::XML_PATH_TYPES);
+        $config = $this->_objectManager->get('Mage_Core_Model_Config')->getNode(self::XML_PATH_TYPES);
         if ($config) {
             foreach ($config->children() as $type=>$node) {
                 $types[$type] = new Varien_Object(array(
diff --git a/app/code/core/Mage/Core/Model/Config.php b/app/code/core/Mage/Core/Model/Config.php
index 9ca5a3418cb..788c0ced759 100644
--- a/app/code/core/Mage/Core/Model/Config.php
+++ b/app/code/core/Mage/Core/Model/Config.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Core configuration class
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -20,12 +18,15 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
+ * @category    Mage
+ * @package     Mage_Core
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-
 /**
+ * Core configuration class
+ *
  * @SuppressWarnings(PHPMD.TooManyFields)
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
@@ -33,6 +34,11 @@
  */
 class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
 {
+    /**
+     * Dependency injection configuration node name
+     */
+    const CONFIGURATION_DI_NODE = 'di';
+
     /**
      * Configuration cache tag
      */
@@ -48,12 +54,15 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      */
     const SCOPE_WEBSITES = 'websites';
 
-    /**@+
-     * Option key names
+    /**
+     * Read additional file during initialization
+     */
+    const INIT_OPTION_EXTRA_FILE = 'MAGE_CONFIG_FILE';
+
+    /**
+     * Read additional data (XML-string) during initialization
      */
-    const OPTION_LOCAL_CONFIG_EXTRA_FILE = 'local_config';
-    const OPTION_LOCAL_CONFIG_EXTRA_DATA = 'local_config_extra_data';
-    /**@-*/
+    const INIT_OPTION_EXTRA_DATA = 'MAGE_CONFIG_DATA';
 
     /**
      * Local configuration file
@@ -102,13 +111,6 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      */
     protected $_cacheLoadedSections = array();
 
-    /**
-     * Configuration options
-     *
-     * @var Mage_Core_Model_Config_Options
-     */
-    protected $_options;
-
     /**
      * Storage for generated class names
      *
@@ -130,20 +132,6 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      */
     protected $_secureUrlCache = array();
 
-    /**
-     * System environment server variables
-     *
-     * @var array
-     */
-    protected $_distroServerVars;
-
-    /**
-     * Array which is using for replace placeholders of server variables
-     *
-     * @var array
-     */
-    protected $_substServerVars;
-
     /**
      * Resource model
      * Used for operations with DB
@@ -268,11 +256,6 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
     {
         $this->_objectManager = $objectManager;
         $this->setCacheId('config_global');
-        $options = $sourceData;
-        if (!is_array($options)) {
-            $options = array($options);
-        }
-        $this->_options = $this->_objectManager->create('Mage_Core_Model_Config_Options', array('data' => $options));
         $this->_prototype = $this->_objectManager->create('Mage_Core_Model_Config_Base');
         $this->_prototype->loadString('<config/>');
         $this->_cacheChecksum = null;
@@ -305,41 +288,15 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
         return $this->_configDataModel;
     }
 
-    /**
-     * Get configuration options object
-     *
-     * @return Mage_Core_Model_Config_Options
-     */
-    public function getOptions()
-    {
-        return $this->_options;
-    }
-
-    /**
-     * Set configuration options
-     *
-     * @param array $options
-     * @return Mage_Core_Model_Config
-     */
-    public function setOptions($options)
-    {
-        if (is_array($options)) {
-            $this->getOptions()->addData($options);
-        }
-        return $this;
-    }
-
     /**
      * Initialization of core configuration
      *
-     * @param array $options
      * @return Mage_Core_Model_Config
      */
-    public function init($options = array())
+    public function init()
     {
         $this->setCacheChecksum(null);
         $this->_cacheLoadedSections = array();
-        $this->setOptions($options);
         $this->loadBase();
 
         $cacheLoad = $this->loadModulesCache();
@@ -360,7 +317,9 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      */
     public function loadBase()
     {
-        $etcDir = $this->getOptions()->getEtcDir();
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = $this->_objectManager->get('Mage_Core_Model_Dir');
+        $etcDir = $dirs->getDir(Mage_Core_Model_Dir::CONFIG);
         if (!$this->getNode()) {
             $this->loadString('<config/>');
         }
@@ -386,7 +345,11 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      */
     protected function _loadLocalConfig()
     {
-        $etcDir = $this->getOptions()->getEtcDir();
+        /** @var $app Mage_Core_Model_App */
+        $app = $this->_objectManager->get('Mage_Core_Model_App');
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = $this->_objectManager->get('Mage_Core_Model_Dir');
+        $etcDir = $dirs->getDir(Mage_Core_Model_Dir::CONFIG);
         $localConfigParts = array();
 
         $localConfigFile = $etcDir . DIRECTORY_SEPARATOR . self::LOCAL_CONFIG_FILE;
@@ -397,7 +360,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
             $localConfigParts[] = $localConfig;
 
             // 2. app/etc/<dir>/<file>.xml
-            $localConfigExtraFile = $this->getOptions()->getData(self::OPTION_LOCAL_CONFIG_EXTRA_FILE);
+            $localConfigExtraFile = $app->getInitParam(self::INIT_OPTION_EXTRA_FILE);
             if (preg_match('/^[a-z\d_-]+\/[a-z\d_-]+\.xml$/', $localConfigExtraFile)) {
                 $localConfigExtraFile = $etcDir . DIRECTORY_SEPARATOR . $localConfigExtraFile;
                 $localConfig = clone $this->_prototype;
@@ -407,7 +370,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
         }
 
         // 3. extra local configuration string
-        $localConfigExtraData = $this->getOptions()->getData(self::OPTION_LOCAL_CONFIG_EXTRA_DATA);
+        $localConfigExtraData = $app->getInitParam(self::INIT_OPTION_EXTRA_DATA);
         if ($localConfigExtraData) {
             $localConfig = clone $this->_prototype;
             $localConfig->loadString($localConfigExtraData);
@@ -451,7 +414,9 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      */
     public function loadLocales()
     {
-        $localeDir = $this->getOptions()->getLocaleDir();
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = $this->_objectManager->get('Mage_Core_Model_Dir');
+        $localeDir = $dirs->getDir(Mage_Core_Model_Dir::LOCALE);
         $files = glob($localeDir . DS . '*' . DS . 'config.xml');
 
         if (is_array($files) && !empty($files)) {
@@ -478,6 +443,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
                 Magento_Profiler::stop('init_modules_config_cache');
                 if ($loaded) {
                     $this->_useCache = true;
+                    $this->loadDiConfiguration();
                     return true;
                 }
             }
@@ -505,11 +471,26 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
         $this->_loadLocalConfig();
 
         $this->applyExtends();
+        $this->loadDiConfiguration();
         Magento_Profiler::stop('load_modules');
         Magento_Profiler::stop('config');
         return $this;
     }
 
+    /**
+     * Load di configuration for given area
+     *
+     * @param string $areaCode
+     */
+    public function loadDiConfiguration($areaCode = Mage_Core_Model_App_Area::AREA_GLOBAL)
+    {
+        $configurationNode = $this->getNode($areaCode . '/' . self::CONFIGURATION_DI_NODE);
+        if ($configurationNode) {
+            $configuration = $configurationNode->asArray();
+            $this->_objectManager->setConfiguration($configuration);
+        }
+    }
+
     /**
      * Check if local configuration (DB connection, etc) is loaded
      *
@@ -541,14 +522,13 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
     /**
      * Reinitialize configuration
      *
-     * @param   array $options
-     * @return  Mage_Core_Model_Config
+     * @return Mage_Core_Model_Config
      */
-    public function reinit($options = array())
+    public function reinit()
     {
         $this->_allowCacheForInit = false;
         $this->_useCache = false;
-        return $this->init($options);
+        return $this->init();
     }
 
     /**
@@ -588,7 +568,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      * @param   array $tags cache tags
      * @return  Mage_Core_Model_Config
      */
-    public function saveCache($tags=array())
+    public function saveCache($tags = array())
     {
         if (!Mage::app()->useCache('config')) {
             return $this;
@@ -664,7 +644,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
          */
         if (!$xmlString) {
             $this->_useCache = false;
-            $this->reinit($this->_options);
+            $this->reinit();
             return false;
         } else {
             $xml = simplexml_load_string($xmlString, $this->_elementClass);
@@ -876,7 +856,9 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      */
     protected function _getDeclaredModuleFiles()
     {
-        $codeDir = $this->getOptions()->getCodeDir();
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = $this->_objectManager->get('Mage_Core_Model_Dir');
+        $codeDir = $dirs->getDir(Mage_Core_Model_Dir::MODULES);
         $moduleFiles = glob($codeDir . DS . '*' . DS . '*' . DS . '*' . DS . 'etc' . DS . 'config.xml');
 
         if (!$moduleFiles) {
@@ -900,7 +882,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
             }
         }
 
-        $etcDir = $this->getOptions()->getEtcDir();
+        $etcDir = $dirs->getDir(Mage_Core_Model_Dir::CONFIG);
         $additionalFiles = glob($etcDir . DS . 'modules' . DS . '*.xml');
 
         foreach ($additionalFiles as $v) {
@@ -1112,15 +1094,6 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
         }
         return $result;
     }
-    /**
-     * Retrieve temporary directory path
-     *
-     * @return string
-     */
-    public function getTempVarDir()
-    {
-        return $this->getOptions()->getVarDir();
-    }
 
     /**
      * Get default server variables values
@@ -1128,57 +1101,23 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      * @return array
      */
-    public function getDistroServerVars()
+    public function getDistroBaseUrl()
     {
-        if (!$this->_distroServerVars) {
+        if (isset($_SERVER['SCRIPT_NAME']) && isset($_SERVER['HTTP_HOST'])) {
+            $secure = (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off'))
+                || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443');
+            $scheme = ($secure ? 'https' : 'http') . '://' ;
 
-            if (isset($_SERVER['SCRIPT_NAME']) && isset($_SERVER['HTTP_HOST'])) {
-                $secure = (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] != 'off'))
-                    || (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443');
-                $scheme = ($secure ? 'https' : 'http') . '://' ;
+            $hostArr = explode(':', $_SERVER['HTTP_HOST']);
+            $host = $hostArr[0];
+            $port = isset($hostArr[1]) && (!$secure && $hostArr[1] != 80 || $secure && $hostArr[1] != 443)
+                ? ':'. $hostArr[1]
+                : '';
+            $path = Mage::app()->getRequest()->getBasePath();
 
-                $hostArr = explode(':', $_SERVER['HTTP_HOST']);
-                $host = $hostArr[0];
-                $port = '';
-                if (isset($hostArr[1]) && (!$secure && $hostArr[1] != 80 || $secure && $hostArr[1] != 443)) {
-                    $port = ':' . $hostArr[1];
-                }
-                $path = Mage::app()->getRequest()->getBasePath();
-
-                $baseUrl = $scheme . $host . $port . rtrim($path, '/') . '/';
-            } else {
-                $baseUrl = 'http://localhost/';
-            }
-
-            $options = $this->getOptions();
-            $this->_distroServerVars = array(
-                'root_dir'  => $options->getBaseDir(),
-                'app_dir'   => $options->getAppDir(),
-                'var_dir'   => $options->getVarDir(),
-                'base_url'  => $baseUrl,
-            );
-
-            foreach ($this->_distroServerVars as $k => $v) {
-                $this->_substServerVars['{{' . $k . '}}'] = $v;
-            }
+            return $scheme . $host . $port . rtrim($path, '/') . '/';
         }
-        return $this->_distroServerVars;
-    }
-
-    /**
-     * Replace distro vars with values
-     *
-     * @param array $data
-     * @return string|array
-     */
-    public function substDistroServerVars($data)
-    {
-        $this->getDistroServerVars();
-        return str_replace(
-            array_keys($this->_substServerVars),
-            array_values($this->_substServerVars),
-            $data
-        );
+        return 'http://localhost/';
     }
 
     /**
@@ -1222,33 +1161,6 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
         return new $className($module);
     }
 
-    /**
-     * Get temporary data directory name
-     *
-     * @param   string $path
-     * @param   string $type
-     * @return  string
-     */
-    public function getVarDir($path = null, $type = 'var')
-    {
-        $dir = Mage::getBaseDir($type) . ($path !== null ? DS . $path : '');
-        if (!$this->createDirIfNotExists($dir)) {
-            return false;
-        }
-        return $dir;
-    }
-
-    /**
-     * Create dir if not exists
-     *
-     * @param string $dir
-     * @return bool
-     */
-    public function createDirIfNotExists($dir)
-    {
-        return $this->getOptions()->createDirIfNotExists($dir);
-    }
-
     /**
      * Get module directory by directory type
      *
@@ -1263,7 +1175,9 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
         }
 
         $codePool = (string)$this->getModuleConfig($moduleName)->codePool;
-        $dir = $this->getOptions()->getCodeDir() . DS . $codePool . DS . uc_words($moduleName, DS);
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = $this->_objectManager->get('Mage_Core_Model_Dir');
+        $dir = $dirs->getDir(Mage_Core_Model_Dir::MODULES) . DS . $codePool . DS . uc_words($moduleName, DS);
 
         switch ($type) {
             case 'etc':
@@ -1705,6 +1619,26 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
         return $areas[$areaCode];
     }
 
+    /**
+     * Identify front name of the requested area. Return current area front name if area code is not specified.
+     *
+     * @param string|null $areaCode
+     * @return string
+     * @throws LogicException If front name is not defined.
+     */
+    public function getAreaFrontName($areaCode = null)
+    {
+        $areaCode = empty($areaCode) ? $this->getCurrentAreaCode() : $areaCode;
+        $areaConfig = $this->getAreaConfig($areaCode);
+        if (!isset($areaConfig['frontName'])) {
+            throw new LogicException(sprintf(
+                'Area "%s" must have front name defined in the application config.',
+                $areaCode
+            ));
+        }
+        return $areaConfig['frontName'];
+    }
+
     /**
      * Load allowed areas from config
      *
@@ -1723,7 +1657,7 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
                     continue;
                 }
                 /**
-                 * TODO: Check of 'routers' nodes existance is excessive:
+                 * TODO: Check of 'routers' nodes existence is excessive:
                  * TODO: 'routers' check is moved Mage_Core_Model_Config::getRouters()
                  */
 
@@ -1810,7 +1744,6 @@ class Mage_Core_Model_Config extends Mage_Core_Model_Config_Base
      */
     public function __destruct()
     {
-        $this->_cacheLoadedSections = array();
         $this->_prototype = null;
         parent::__destruct();
     }
diff --git a/app/code/core/Mage/Core/Model/Config/Options.php b/app/code/core/Mage/Core/Model/Config/Options.php
deleted file mode 100644
index 216ad012cbf..00000000000
--- a/app/code/core/Mage/Core/Model/Config/Options.php
+++ /dev/null
@@ -1,325 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Mage
- * @package     Mage_Core
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Configuration options storage and logic
- *
- * @category   Mage
- * @package    Mage_Core
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Mage_Core_Model_Config_Options extends Varien_Object
-{
-    /**
-     * Var directory
-     *
-     * @var string
-     */
-    const VAR_DIRECTORY = 'var';
-
-    /**
-     * Public directory
-     *
-     * @var string
-     */
-    const PUB_DIRECTORY = 'pub';
-
-    /**
-     * Flag cache for existing or already created directories
-     *
-     * @var array
-     */
-    protected $_dirExists = array();
-
-    /**
-     * Flag cache for existing or already created directories
-     *
-     * @var array
-     */
-    protected $_io;
-
-    /**
-     * Initialize default values of the options
-     *
-     * @param array $data
-     */
-    public function __construct(array $data = array())
-    {
-        $this->_io = isset($data['io']) ? $data['io'] : new Varien_Io_File();
-        unset ($data['io']);
-        parent::__construct($data);
-        $appRoot = isset($data['app_dir']) ? $data['app_dir'] : Mage::getRoot();
-        $root   = dirname($appRoot);
-
-        $this->_data['app_dir']     = $appRoot;
-        $this->_data['base_dir']    = $root;
-        $this->_data['code_dir']    = $appRoot . DIRECTORY_SEPARATOR . 'code';
-        $this->_data['design_dir']  = $appRoot . DIRECTORY_SEPARATOR . 'design';
-        $this->_data['etc_dir']     = $appRoot . DIRECTORY_SEPARATOR . 'etc';
-        $this->_data['lib_dir']     = $root . DIRECTORY_SEPARATOR . 'lib';
-        $this->_data['locale_dir']  = $appRoot . DIRECTORY_SEPARATOR . 'locale';
-        $this->_data['pub_dir']     = $root . DIRECTORY_SEPARATOR . 'pub';
-        $this->_data['js_dir']      = $this->_data['pub_dir'] . DIRECTORY_SEPARATOR . 'lib';
-        $this->_data['media_dir']   = isset($data['media_dir'])
-            ? $data['media_dir']
-            : $this->_data['pub_dir'] . DIRECTORY_SEPARATOR . 'media';
-        $this->_data['var_dir']     = $this->getVarDir();
-        $this->_data['tmp_dir']     = $this->_data['var_dir'] . DIRECTORY_SEPARATOR . 'tmp';
-        $this->_data['cache_dir']   = $this->_data['var_dir'] . DIRECTORY_SEPARATOR . 'cache';
-        $this->_data['log_dir']     = $this->_data['var_dir'] . DIRECTORY_SEPARATOR . 'log';
-        $this->_data['session_dir'] = $this->_data['var_dir'] . DIRECTORY_SEPARATOR . 'session';
-        $this->_data['upload_dir']  = $this->_data['media_dir'] . DIRECTORY_SEPARATOR . 'upload';
-        $this->_data['export_dir']  = $this->_data['var_dir'] . DIRECTORY_SEPARATOR . 'export';
-    }
-
-    /**
-     * Directory getter that returm path to directory based on path
-     *
-     * @throws Mage_Core_Exception
-     * @param string $type
-     * @return string
-     */
-    public function getDir($type)
-    {
-        $method = 'get'.ucwords($type).'Dir';
-        $dir = $this->$method();
-        if (!$dir) {
-            throw Mage::exception('Mage_Core', 'Invalid dir type requested: '.$type);
-        }
-        return $dir;
-    }
-
-    /**
-     * Application folder paths getter
-     *
-     * @return string
-     */
-    public function getAppDir()
-    {
-        return $this->_data['app_dir'];
-    }
-
-    /**
-     * Base folder paths getter
-     *
-     * @return string
-     */
-    public function getBaseDir()
-    {
-        return $this->_data['base_dir'];
-    }
-
-    /**
-     * Code folder paths getter
-     *
-     * @return string
-     */
-    public function getCodeDir()
-    {
-        return $this->_data['code_dir'];
-    }
-
-    /**
-     * Design folder paths getter
-     *
-     * @return string
-     */
-    public function getDesignDir()
-    {
-        return $this->_data['design_dir'];
-    }
-
-    /**
-     * Configuration (etc) folder paths getter
-     *
-     * @return string
-     */
-    public function getEtcDir()
-    {
-        return $this->_data['etc_dir'];
-    }
-
-    /**
-     * Libraries folder paths getter
-     *
-     * @return string
-     */
-    public function getLibDir()
-    {
-        return $this->_data['lib_dir'];
-    }
-
-    /**
-     * Locale folder paths getter
-     *
-     * @return string
-     */
-    public function getLocaleDir()
-    {
-        return $this->_data['locale_dir'];
-    }
-
-    /**
-     * Public folder paths getter
-     *
-     * @return string
-     */
-    public function getPubDir()
-    {
-        return $this->_data['pub_dir'];
-    }
-
-    /**
-     * JS libraries folder paths getter
-     *
-     * @return string
-     */
-    public function getJsDir()
-    {
-        return $this->_data['js_dir'];
-    }
-
-    /**
-     * Media folder paths getter
-     *
-     * @return string
-     */
-    public function getMediaDir()
-    {
-        return $this->_data['media_dir'];
-    }
-
-    /**
-     * Var folder paths getter
-     *
-     * @return string
-     * @throws Mage_Core_Exception
-     */
-    public function getVarDir()
-    {
-        $dir = isset($this->_data['var_dir']) ? $this->_data['var_dir']
-            : $this->_data['base_dir'] . DIRECTORY_SEPARATOR . self::VAR_DIRECTORY;
-        if (!$this->createDirIfNotExists($dir)) {
-            throw new Mage_Core_Exception('Unable to find writable var_dir');
-        }
-        return $dir;
-    }
-
-    /**
-     * Temporary folder paths getter
-     *
-     * @return string
-     * @throws Mage_Core_Exception
-     */
-    public function getTmpDir()
-    {
-        $dir = $this->_data['tmp_dir'];
-        if (!$this->createDirIfNotExists($dir)) {
-            throw new Mage_Core_Exception('Unable to find writable tmp_dir');
-        }
-        return $dir;
-    }
-
-    /**
-     * Cache folder paths getter
-     *
-     * @return string
-     */
-    public function getCacheDir()
-    {
-        $dir = $this->_data['cache_dir'];
-        $this->createDirIfNotExists($dir);
-        return $dir;
-    }
-
-    /**
-     * Log folder paths getter
-     *
-     * @return string
-     */
-    public function getLogDir()
-    {
-        $dir = $this->_data['log_dir'];
-        $this->createDirIfNotExists($dir);
-        return $dir;
-    }
-
-    /**
-     * Session folder paths getter
-     *
-     * @return string
-     */
-    public function getSessionDir()
-    {
-        $dir = $this->_data['session_dir'];
-        $this->createDirIfNotExists($dir);
-        return $dir;
-    }
-
-    /**
-     * Files upload folder paths getter
-     *
-     * @return string
-     */
-    public function getUploadDir()
-    {
-        $dir = $this->_data['upload_dir'];
-        $this->createDirIfNotExists($dir);
-        return $dir;
-    }
-
-    /**
-     * Export files folder paths getter
-     *
-     * @return string
-     */
-    public function getExportDir()
-    {
-        $dir = $this->_data['export_dir'];
-        $this->createDirIfNotExists($dir);
-        return $dir;
-    }
-
-    /**
-     * Create writable directory if it not exists
-     *
-     * @param string
-     * @return bool
-     */
-    public function createDirIfNotExists($dir)
-    {
-        if (!empty($this->_dirExists[$dir])) {
-            return true;
-        }
-        try {
-            $this->_io->checkAndCreateFolder($dir);
-        } catch (Exception $e) {
-            return false;
-        }
-        $this->_dirExists[$dir] = true;
-        return true;
-    }
-}
diff --git a/app/code/core/Mage/Core/Model/Design/Fallback.php b/app/code/core/Mage/Core/Model/Design/Fallback.php
index e35d351afc5..a12d50f48e5 100644
--- a/app/code/core/Mage/Core/Model/Design/Fallback.php
+++ b/app/code/core/Mage/Core/Model/Design/Fallback.php
@@ -49,22 +49,75 @@ class Mage_Core_Model_Design_Fallback implements Mage_Core_Model_Design_Fallback
      */
     protected $_appConfig;
 
+    /**
+     * @var Mage_Core_Model_Dir
+     */
+    protected $_dirs = null;
+
+    /**
+     * @var Magento_ObjectManager|null
+     */
+    protected $_objectManager = null;
+
     /**
      * Constructor.
      * Following entries in $params are required: 'area', 'package', 'theme', 'locale'. The 'appConfig' and
      * 'themeConfig' may contain application config and theme config, respectively. If these these entries are not
      * present or null, then they will be retrieved from global application instance.
      *
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Magento_ObjectManager $objectManager
      * @param Magento_Filesystem $filesystem
-     * @param array $data
+     * @param array $params
+     * @throws InvalidArgumentException
      */
-    public function __construct(Magento_Filesystem $filesystem, $data)
-    {
+    public function __construct(
+        Mage_Core_Model_Dir $dirs,
+        Magento_ObjectManager $objectManager,
+        Magento_Filesystem $filesystem,
+        $params
+    ) {
+        $this->_dirs = $dirs;
+        $this->_objectManager = $objectManager;
         $this->_filesystem = $filesystem;
-        $this->_area = $data['area'];
-        $this->_locale = $data['locale'];
-        $this->_theme = $data['themeModel'];
-        $this->_appConfig = isset($data['appConfig']) ? $data['appConfig'] : Mage::getConfig();
+        if (!array_key_exists('area', $params) || !array_key_exists('themeModel', $params)
+            || !array_key_exists('locale', $params)
+        ) {
+            throw new InvalidArgumentException("Missing one of the param keys: 'area', 'themeModel', 'locale'.");
+        }
+        $this->_area = $params['area'];
+        $this->_theme = $params['themeModel'];
+        $this->_locale = $params['locale'];
+    }
+
+    /**
+     * Get area code
+     *
+     * @return string
+     */
+    public function getArea()
+    {
+        return $this->_area;
+    }
+
+    /**
+     * Get theme code
+     *
+     * @return string
+     */
+    public function getTheme()
+    {
+        return $this->_theme->getThemeCode();
+    }
+
+    /**
+     * Get locale code
+     *
+     * @return null|string
+     */
+    public function getLocale()
+    {
+        return $this->_locale;
     }
 
     /**
@@ -76,7 +129,7 @@ class Mage_Core_Model_Design_Fallback implements Mage_Core_Model_Design_Fallback
      */
     public function getFile($file, $module = null)
     {
-        $dir = $this->_appConfig->getOptions()->getDesignDir();
+        $dir = $this->_dirs->getDir(Mage_Core_Model_Dir::THEMES);
         $dirs = array();
         $themeModel = $this->_theme;
         while ($themeModel) {
@@ -85,7 +138,12 @@ class Mage_Core_Model_Design_Fallback implements Mage_Core_Model_Design_Fallback
             $themeModel = $themeModel->getParentTheme();
         }
 
-        $moduleDir = $module ? array($this->_appConfig->getModuleDir('view', $module) . "/{$this->_area}") : array();
+        if ($module) {
+            $moduleDir = array($this->_objectManager->get('Mage_Core_Model_Config')->getModuleDir('view', $module)
+                . "/{$this->_area}");
+        } else {
+            $moduleDir = array();
+        }
         return $this->_fallback($file, $dirs, $module, $moduleDir);
     }
 
@@ -97,7 +155,7 @@ class Mage_Core_Model_Design_Fallback implements Mage_Core_Model_Design_Fallback
      */
     public function getLocaleFile($file)
     {
-        $dir = $this->_appConfig->getOptions()->getDesignDir();
+        $dir = $this->_dirs->getDir(Mage_Core_Model_Dir::THEMES);
         $dirs = array();
         $themeModel = $this->_theme;
         while ($themeModel) {
@@ -118,8 +176,8 @@ class Mage_Core_Model_Design_Fallback implements Mage_Core_Model_Design_Fallback
      */
     public function getViewFile($file, $module = null)
     {
-        $dir = $this->_appConfig->getOptions()->getDesignDir();
-        $moduleDir = $module ? $this->_appConfig->getModuleDir('view', $module) : '';
+        $dir = $this->_dirs->getDir(Mage_Core_Model_Dir::THEMES);
+        $moduleDir = $module ? $this->_objectManager->get('Mage_Core_Model_Config')->getModuleDir('view', $module) : '';
 
         $dirs = array();
         $themeModel = $this->_theme;
@@ -131,7 +189,7 @@ class Mage_Core_Model_Design_Fallback implements Mage_Core_Model_Design_Fallback
         }
 
         $extraDirs = array(
-            $this->_appConfig->getOptions()->getJsDir(),
+            $this->_dirs->getDir(Mage_Core_Model_Dir::PUB_LIB),
             Mage::getDesign()->getCustomizationDir()
         );
 
diff --git a/app/code/core/Mage/Core/Model/Design/Fallback/CachingProxy.php b/app/code/core/Mage/Core/Model/Design/Fallback/CachingProxy.php
index 68e23926eea..6d0ab0f4b39 100644
--- a/app/code/core/Mage/Core/Model/Design/Fallback/CachingProxy.php
+++ b/app/code/core/Mage/Core/Model/Design/Fallback/CachingProxy.php
@@ -30,21 +30,6 @@
  */
 class Mage_Core_Model_Design_Fallback_CachingProxy implements Mage_Core_Model_Design_FallbackInterface
 {
-    /**
-     * @var string
-     */
-    protected $_area;
-
-    /**
-     * @var Mage_Core_Model_Theme
-     */
-    protected $_theme;
-
-    /**
-     * @var string|null
-     */
-    protected $_locale;
-
     /**
      * Whether object can save map changes upon destruction
      *
@@ -71,7 +56,7 @@ class Mage_Core_Model_Design_Fallback_CachingProxy implements Mage_Core_Model_De
      *
      * @var array
      */
-    protected $_map;
+    protected $_map = array();
 
     /**
      * Proxied fallback model
@@ -81,78 +66,62 @@ class Mage_Core_Model_Design_Fallback_CachingProxy implements Mage_Core_Model_De
     protected $_fallback;
 
     /**
-     * Directory to keep map file
-     *
-     * @var string
+     * @var Magento_Filesystem
      */
-    protected $_mapDir;
+    protected $_filesystem;
 
     /**
      * Path to Magento base directory
      *
      * @var string
      */
-    protected $_basePath;
-
-    /**
-     * @var Magento_Filesystem
-     */
-    protected $_filesystem;
+    protected $_baseDir;
 
     /**
-     * Constructor.
-     * Following entries in $params are required: 'area', 'package', 'theme', 'locale', 'canSaveMap',
-     * 'mapDir', 'baseDir'.
+     * Read the class map according to provided fallback model and parameters
      *
+     * @param Mage_Core_Model_Design_Fallback $fallback
      * @param Magento_Filesystem $filesystem
-     * @param array $data
-     */
-    public function __construct(Magento_Filesystem $filesystem, array $data = array())
-    {
+     * @param string $mapDir directory where to look the map files in
+     * @param string $baseDir base directory path to prepend to file paths
+     * @param bool $canSaveMap whether to update map file in destructor
+     * @throws InvalidArgumentException
+     */
+    public function __construct(
+        Mage_Core_Model_Design_Fallback $fallback,
+        Magento_Filesystem $filesystem,
+        $mapDir,
+        $baseDir,
+        $canSaveMap = true
+    ) {
+        $this->_fallback = $fallback;
         $this->_filesystem = $filesystem;
-        $this->_area = $data['area'];
-        $this->_theme = $data['themeModel'];
-        $this->_locale = $data['locale'];
-        $this->_canSaveMap = $data['canSaveMap'];
-        $this->_mapDir = $data['mapDir'];
-        $this->_basePath = $data['baseDir'] ? $data['baseDir'] . DIRECTORY_SEPARATOR : '';
-
-        $this->_mapFile =
-            "{$this->_mapDir}/{$this->_area}_{$this->_theme->getId()}_{$this->_locale}.ser";
-        $this->_map = $this->_filesystem->isFile($this->_mapFile)
-            ? unserialize($this->_filesystem->read($this->_mapFile))
-            : array();
+        if (!$filesystem->isDirectory($baseDir)) {
+            throw new InvalidArgumentException("Wrong base directory specified: '{$baseDir}'");
+        }
+        $this->_baseDir = $baseDir;
+        $this->_canSaveMap = $canSaveMap;
+        $this->_mapFile = $mapDir . DIRECTORY_SEPARATOR
+            . "{$fallback->getArea()}_{$fallback->getTheme()}_{$fallback->getLocale()}.ser";
+        if ($this->_filesystem->isFile($this->_mapFile)) {
+            $this->_map = unserialize($this->_filesystem->read($this->_mapFile));
+        }
     }
 
+    /**
+     * Write the serialized class map to the file
+     */
     public function __destruct()
     {
         if ($this->_isMapChanged && $this->_canSaveMap) {
-            if (!$this->_filesystem->isDirectory($this->_mapDir)) {
-                $this->_filesystem->createDirectory($this->_mapDir, 0777);
+            $dir = dirname($this->_mapFile);
+            if (!$this->_filesystem->isDirectory($dir)) {
+                $this->_filesystem->createDirectory($dir, 0777);
             }
             $this->_filesystem->write($this->_mapFile, serialize($this->_map));
         }
     }
 
-    /**
-     * Return instance of fallback model. Create it, if it has not been created yet.
-     *
-     * @return Mage_Core_Model_Design_Fallback
-     */
-    protected function _getFallback()
-    {
-        if (!$this->_fallback) {
-            $this->_fallback = Mage::getModel('Mage_Core_Model_Design_Fallback', array(
-                'data' => array(
-                    'area'       => $this->_area,
-                    'themeModel' => $this->_theme,
-                    'locale'     => $this->_locale
-                )
-            ));
-        }
-        return $this->_fallback;
-    }
-
     /**
      * Return relative file name from map
      *
@@ -167,7 +136,7 @@ class Mage_Core_Model_Design_Fallback_CachingProxy implements Mage_Core_Model_De
         if (isset($this->_map[$mapKey])) {
             $value =  $this->_map[$mapKey];
             if ((string) $value !== '') {
-                return $this->_basePath . $value;
+                return $this->_baseDir . DIRECTORY_SEPARATOR . $value;
             } else {
                 return $value;
             }
@@ -183,26 +152,23 @@ class Mage_Core_Model_Design_Fallback_CachingProxy implements Mage_Core_Model_De
      * @param string $file
      * @param string|null $module
      * @param string $filePath
-     * @return Mage_Core_Model_Design_Fallback_CachingProxy
-     * @throws Mage_Core_Exception
+     * @throws Magento_Exception
      */
     protected function _setToMap($prefix, $file, $module, $filePath)
     {
-        $basePathLen = strlen($this->_basePath);
-        if (((string)$filePath !== '') && strncmp($filePath, $this->_basePath, $basePathLen)) {
-            throw new Mage_Core_Exception(
-                "Attempt to store fallback path '{$filePath}', which is not within '{$this->_basePath}'"
+        $pattern = $this->_baseDir . DIRECTORY_SEPARATOR;
+        if (0 !== strpos($filePath, $pattern, 0)) {
+            throw new Magento_Exception(
+                "Attempt to store fallback path '{$filePath}', which is not within '{$pattern}'"
             );
         }
-
         $mapKey = "$prefix|$file|$module";
-        $this->_map[$mapKey] = substr($filePath, $basePathLen);
+        $this->_map[$mapKey] = substr($filePath, strlen($pattern));
         $this->_isMapChanged = true;
-        return $this;
     }
 
     /**
-     * Get existing file name, using map and fallback mechanism
+     * Proxy to Mage_Core_Model_Design_Fallback::getFile()
      *
      * @param string $file
      * @param string|null $module
@@ -212,14 +178,14 @@ class Mage_Core_Model_Design_Fallback_CachingProxy implements Mage_Core_Model_De
     {
         $result = $this->_getFromMap('theme', $file, $module);
         if (!$result) {
-            $result = $this->_getFallback()->getFile($file, $module);
+            $result = $this->_fallback->getFile($file, $module);
             $this->_setToMap('theme', $file, $module, $result);
         }
         return $result;
     }
 
     /**
-     * Get locale file name, using map and fallback mechanism
+     * Proxy to Mage_Core_Model_Design_Fallback::getLocaleFile()
      *
      * @param string $file
      * @return string
@@ -228,14 +194,14 @@ class Mage_Core_Model_Design_Fallback_CachingProxy implements Mage_Core_Model_De
     {
         $result = $this->_getFromMap('locale', $file);
         if (!$result) {
-            $result = $this->_getFallback()->getLocaleFile($file);
+            $result = $this->_fallback->getLocaleFile($file);
             $this->_setToMap('locale', $file, null, $result);
         }
         return $result;
     }
 
     /**
-     * Get Theme file name, using map and fallback mechanism
+     * Proxy to Mage_Core_Model_Design_Fallback::getViewFile()
      *
      * @param string $file
      * @param string|null $module
@@ -245,22 +211,23 @@ class Mage_Core_Model_Design_Fallback_CachingProxy implements Mage_Core_Model_De
     {
         $result = $this->_getFromMap('view', $file, $module);
         if (!$result) {
-            $result = $this->_getFallback()->getViewFile($file, $module);
+            $result = $this->_fallback->getViewFile($file, $module);
             $this->_setToMap('view', $file, $module, $result);
         }
         return $result;
     }
 
     /**
-     * Object notified, that theme file was published, thus it can return published file name on next calls
+     * Object notified, that view file was published, thus it can return published file name on next calls
      *
      * @param string $publicFilePath
      * @param string $file
      * @param string|null $module
-     * @return Mage_Core_Model_Design_FallbackInterface
+     * @return Mage_Core_Model_Design_Fallback_CachingProxy
      */
     public function notifyViewFilePublished($publicFilePath, $file, $module = null)
     {
-        return $this->_setToMap('view', $file, $module, $publicFilePath);
+        $this->_setToMap('view', $file, $module, $publicFilePath);
+        return $this;
     }
 }
diff --git a/app/code/core/Mage/Core/Model/Design/Package.php b/app/code/core/Mage/Core/Model/Design/Package.php
index 4be237dd863..97b7c23ad9b 100644
--- a/app/code/core/Mage/Core/Model/Design/Package.php
+++ b/app/code/core/Mage/Core/Model/Design/Package.php
@@ -84,9 +84,19 @@ class Mage_Core_Model_Design_Package
     /**#@-*/
 
     /**
-     * Path to configuration node for file duplication
+     * Path to configuration node that indicates how to materialize view files: with or without "duplication"
      */
-    const XML_PATH_ALLOW_DUPLICATION = 'default/design/theme/allow_view_files_duplication';
+    const XML_PATH_ALLOW_DUPLICATION = 'global/design/theme/allow_view_files_duplication';
+
+    /**
+     * Path to config node that allows automatically updating map files in runtime
+     */
+    const XML_PATH_ALLOW_MAP_UPDATE = 'global/dev/design_fallback/allow_map_update';
+
+    /**
+     * Sub-directory where to store maps of view files fallback (if used)
+     */
+    const FALLBACK_MAP_DIR = 'maps/fallback';
 
     /**
      * PCRE that matches non-absolute URLs in CSS content
@@ -255,36 +265,29 @@ class Mage_Core_Model_Design_Package
      * @param array $params
      * @return string|int
      */
-    public function getConfigurationDesignTheme($area = null, $params = array())
+    public function getConfigurationDesignTheme($area = null, array $params = array())
     {
         if (!$area) {
             $area = $this->getArea();
         }
-        $useId = isset($params['useId']) ? $params['useId'] : true;
         $store = isset($params['store']) ? $params['store'] : null;
 
-        $designTheme = (string)Mage::getStoreConfig($this->getConfigPathByArea($area, $useId), $store);
-        if (empty($designTheme)) {
-            $designTheme = (string)Mage::getConfig()->getNode($this->getConfigPathByArea($area, $useId));
+        if ($this->_isThemePerStoveView($area)) {
+            return Mage::getStoreConfig(self::XML_PATH_THEME_ID, $store)
+                ?: (string)Mage::getConfig()->getNode($area . '/' . self::XML_PATH_THEME);
         }
-        return $designTheme;
+        return (string)Mage::getConfig()->getNode($area . '/' . self::XML_PATH_THEME);
     }
 
-
     /**
-     * Get configuration xml path to current theme for area
+     * Whether themes in specified area are supposed to be configured per store view
      *
      * @param string $area
-     * @param bool $useId
-     * @return string
+     * @return bool
      */
-    public function getConfigPathByArea($area, $useId = true)
+    private function _isThemePerStoveView($area)
     {
-        $xmlPath = $useId ? self::XML_PATH_THEME_ID : self::XML_PATH_THEME;
-        if ($area !== self::DEFAULT_AREA) {
-            $xmlPath = $area . '/' . $xmlPath;
-        }
-        return $xmlPath;
+        return $area == self::DEFAULT_AREA;
     }
 
     /**
@@ -324,7 +327,7 @@ class Mage_Core_Model_Design_Package
         }
 
         if (!empty($params['themeId'])) {
-            $params['themeModel'] = $this->_getLoadDesignTheme($params['themeId']);
+            $params['themeModel'] = $this->_getLoadDesignTheme($params['themeId'], $params['area']);
         } elseif (!empty($params['package']) && isset($params['theme'])) {
             $themePath = $params['package'] . '/' . $params['theme'];
             $params['themeModel'] = $this->_getLoadDesignTheme($themePath, $params['area']);
@@ -419,18 +422,30 @@ class Mage_Core_Model_Design_Package
      */
     protected function _getFallback($params)
     {
-        if (!isset($params['skipProxy'])) {
-            $params['skipProxy'] = $this->_isDeveloperMode();
-        }
+        $skipProxy = (isset($params['skipProxy']) && $params['skipProxy']) ?: $this->_isDeveloperMode();
 
         $cacheKey = join('|', array(
             $params['area'],
             $params['themeModel']->getCacheKey(),
             $params['locale'],
-            $params['skipProxy']
+            $skipProxy
         ));
         if (!isset($this->_fallback[$cacheKey])) {
-            $this->_fallback[$cacheKey] = $this->_createFallback($params);
+            $fallback = Mage::getObjectManager()->create('Mage_Core_Model_Design_Fallback', array('params' => $params));
+            if ($skipProxy) {
+                $this->_fallback[$cacheKey] = $fallback;
+            } else {
+                /** @var $dirs Mage_Core_Model_Dir */
+                $dirs = Mage::getObjectManager()->get('Mage_Core_Model_Dir');
+                $proxy = new Mage_Core_Model_Design_Fallback_CachingProxy(
+                    $fallback,
+                    $this->_filesystem,
+                    $dirs->getDir(Mage_Core_Model_Dir::VAR_DIR) . DIRECTORY_SEPARATOR . self::FALLBACK_MAP_DIR,
+                    $dirs->getDir(Mage_Core_Model_Dir::ROOT),
+                    (bool)(string)Mage::app()->getConfig()->getNode(self::XML_PATH_ALLOW_MAP_UPDATE)
+                );
+                $this->_fallback[$cacheKey] = $proxy;
+            }
         }
         return $this->_fallback[$cacheKey];
     }
@@ -546,19 +561,16 @@ class Mage_Core_Model_Design_Package
      */
     protected function _getPublicFileUrl($file, $isSecure = null)
     {
-        $publicDirUrlTypes = array(
-            Mage_Core_Model_Store::URL_TYPE_THEME  => $this->getPublicDir(),
-            Mage_Core_Model_Store::URL_TYPE_JS    => Mage::getBaseDir('js'),
-        );
-        foreach ($publicDirUrlTypes as $publicUrlType => $publicDir) {
-            $publicDir .= DS;
-            if (strpos($file, $publicDir) !== 0) {
-                continue;
+        foreach (array(
+            Mage_Core_Model_Store::URL_TYPE_LIB => Mage_Core_Model_Dir::PUB_LIB,
+            Mage_Core_Model_Store::URL_TYPE_MEDIA => Mage_Core_Model_Dir::MEDIA
+        ) as $urlType => $dirType) {
+            $dir = Mage::getBaseDir($dirType);
+            if (strpos($file, $dir) === 0) {
+                $relativePath = ltrim(substr($file, strlen($dir)), DIRECTORY_SEPARATOR);
+                $relativePath = str_replace(DIRECTORY_SEPARATOR, '/', $relativePath);
+                return Mage::getBaseUrl($urlType, $isSecure) . $relativePath;
             }
-            $url = str_replace($publicDir, '', $file);
-            $url = str_replace(DS, '/', $url);
-            $url = Mage::getBaseUrl($publicUrlType, $isSecure) . $url;
-            return $url;
         }
         throw new Magento_Exception(
             "Cannot build URL for the file '$file' because it does not reside in a public directory."
@@ -708,7 +720,7 @@ class Mage_Core_Model_Design_Package
      */
     protected function _needToProcessFile($filePath)
     {
-        $jsPath = Mage::getBaseDir('js') . DS;
+        $jsPath = Mage::getBaseDir(Mage_Core_Model_Dir::PUB_LIB) . DS;
         if (strncmp($filePath, $jsPath, strlen($jsPath)) === 0) {
             return false;
         }
@@ -761,7 +773,7 @@ class Mage_Core_Model_Design_Package
      */
     public function getPublicDir()
     {
-        return Mage::getBaseDir('media') . DIRECTORY_SEPARATOR . self::PUBLIC_BASE_THEME_DIR;
+        return Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA) . DIRECTORY_SEPARATOR . self::PUBLIC_BASE_THEME_DIR;
     }
 
     /**
@@ -771,7 +783,7 @@ class Mage_Core_Model_Design_Package
      */
     public function getCustomizationDir()
     {
-        return Mage::getBaseDir('media') . DIRECTORY_SEPARATOR . Mage_Core_Model_Design_Package::PUBLIC_BASE_THEME_DIR
+        return Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA) . DIRECTORY_SEPARATOR . Mage_Core_Model_Design_Package::PUBLIC_BASE_THEME_DIR
             . DIRECTORY_SEPARATOR . Mage_Core_Model_Design_Package::PUBLIC_CUSTOMIZATION_THEME_DIR;
     }
 
@@ -807,7 +819,7 @@ class Mage_Core_Model_Design_Package
      */
     protected function _buildPublicViewSufficientFilename($filename, array $params)
     {
-        $designDir = Mage::getBaseDir('design') . DS;
+        $designDir = Mage::getBaseDir(Mage_Core_Model_Dir::THEMES) . DS;
         if (0 === strpos($filename, $designDir)) {
             // theme file
             $publicFile = substr($filename, strlen($designDir));
@@ -877,7 +889,7 @@ class Mage_Core_Model_Design_Package
             $relativeThemeFile = $fileUrl;
         } else {
             /* Check if module file overridden on theme level based on _module property and file path */
-            if ($params['module'] && strpos($parentFilePath, Mage::getBaseDir('design')) === 0) {
+            if ($params['module'] && strpos($parentFilePath, Mage::getBaseDir(Mage_Core_Model_Dir::THEMES)) === 0) {
                 /* Add module directory to relative URL for canonization */
                 $relativeThemeFile = dirname($params['module'] . DS . $parentFileName)
                     . DS . $fileUrl;
@@ -944,7 +956,7 @@ class Mage_Core_Model_Design_Package
     {
         $filesToMerge = array();
         $mergedFile = array();
-        $jsDir = Mage::getBaseDir('js');
+        $jsDir = Mage::getBaseDir(Mage_Core_Model_Dir::PUB_LIB);
         $publicDir = $this->_buildPublicViewFilename('');
         foreach ($files as $file) {
             $params = array();
diff --git a/app/code/core/Mage/Core/Model/Dir.php b/app/code/core/Mage/Core/Model/Dir.php
new file mode 100644
index 00000000000..02d94af059f
--- /dev/null
+++ b/app/code/core/Mage/Core/Model/Dir.php
@@ -0,0 +1,311 @@
+<?php
+/**
+ * Application file system directories dictionary
+ *
+ * Provides information about what directories are available in the application
+ * Serves as customizaiton point to specify different directories or add own
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Core_Model_Dir
+{
+    /**
+     * Code base root
+     */
+    const ROOT = 'base';
+
+    /**
+     * Most of entire application
+     */
+    const APP = 'app';
+
+    /**
+     * Modules
+     */
+    const MODULES = 'code';
+
+    /**
+     * Themes
+     */
+    const THEMES = 'design';
+
+    /**
+     * Initial configuration of the application
+     */
+    const CONFIG = 'etc';
+
+    /**
+     * Libraries or third-party components
+     */
+    const LIB = 'lib';
+
+    /**
+     * Files with translation of system labels and messages from en_US to other languages
+     */
+    const LOCALE = 'locale';
+
+    /**
+     * Directory within document root of a web-server to access static view files publicly
+     */
+    const PUB = 'pub';
+
+    /**
+     * Libraries/components that need to be accessible publicly through web-server (such as various DHTML components)
+     */
+    const PUB_LIB = 'pub_lib';
+
+    /**
+     * Storage of files entered or generated by the end-user
+     */
+    const MEDIA = 'media';
+
+    /**
+     * Various files generated by the system in runtime
+     */
+    const VAR_DIR = 'var';
+
+    /**
+     * Temporary files
+     */
+    const TMP = 'tmp';
+
+    /**
+     * File system caching directory (if file system caching is used)
+     */
+    const CACHE = 'cache';
+
+    /**
+     * Logs of system messages and errors
+     */
+    const LOG = 'log';
+
+    /**
+     * File system session directory (if file system session storage is used)
+     */
+    const SESSION = 'session';
+
+    /**
+     * Temporary directory for uploading files by end-user
+     */
+    const UPLOAD = 'upload';
+
+    /**
+     * Default values for directories (and URIs)
+     *
+     * Format: array(<code> => <relative_path>)
+     *
+     * @var array
+     */
+    private static $_defaults = array(
+        self::ROOT    => '',
+        self::APP     => 'app',
+        self::MODULES => 'app/code',
+        self::THEMES  => 'app/design',
+        self::CONFIG  => 'app/etc',
+        self::LIB     => 'lib',
+        self::LOCALE  => 'app/locale',
+        self::VAR_DIR => 'var',
+        self::TMP     => 'var/tmp',
+        self::CACHE   => 'var/cache',
+        self::LOG     => 'var/log',
+        self::SESSION => 'var/session',
+        self::PUB     => 'pub',
+        self::PUB_LIB => 'pub/lib',
+        self::MEDIA   => 'pub/media',
+        self::UPLOAD  => 'pub/media/upload',
+    );
+
+    /**
+     * Paths of URIs designed for building URLs
+     *
+     * Values are to be initialized in constructor.
+     * They are declared like this here for convenience of distinguishing which directories are intended to be URIs.
+     *
+     * @var array
+     */
+    private $_uris = array(
+        self::PUB     => '',
+        self::PUB_LIB => '',
+        self::MEDIA   => '',
+        self::UPLOAD  => '',
+    );
+
+    /**
+     * Absolute paths to directories
+     *
+     * @var array
+     */
+    private $_dirs = array();
+
+    /**
+     * List of directories that application requires to be writable in order to operate
+     *
+     * @return array
+     */
+    public static function getWritableDirCodes()
+    {
+        return array(self::MEDIA, self::VAR_DIR, self::TMP, self::CACHE, self::LOG, self::SESSION);
+    }
+
+    /**
+     * Initialize URIs and paths
+     *
+     * @param string $baseDir
+     * @param array $uris custom URIs
+     * @param array $dirs custom directories (full system paths)
+     */
+    public function __construct($baseDir, array $uris = array(), array $dirs = array())
+    {
+        // uris
+        foreach (array_keys($this->_uris) as $code) {
+            $this->_uris[$code] = self::$_defaults[$code];
+        }
+        foreach ($uris as $code => $uri) {
+            $this->_setUri($code, $uri);
+        }
+        foreach ($this->_getDefaultReplacements($uris) as $code => $replacement) {
+            $this->_setUri($code, $replacement);
+        }
+
+        // dirs
+        foreach (self::$_defaults as $code => $path) {
+            $this->_setDir($code, $baseDir . ($path ? DIRECTORY_SEPARATOR . $path : ''));
+        }
+        foreach ($dirs as $code => $path) {
+            $this->_setDir($code, $path);
+        }
+        foreach ($this->_getDefaultReplacements($dirs) as $code => $replacement) {
+            $this->_setDir($code, $replacement);
+        }
+    }
+
+    /**
+     * URI getter
+     *
+     * @param string $code
+     * @return string|bool
+     */
+    public function getUri($code)
+    {
+        return isset($this->_uris[$code]) ? $this->_uris[$code] : false;
+    }
+
+    /**
+     * Set URI
+     *
+     * The method is private on purpose: it must be used only in constructor. Users of this object must not be able
+     * to alter its state, otherwise it may compromise application integrity.
+     * Path must be usable as a fragment of a URL path.
+     * For interoperability and security purposes, no uppercase or "upper directory" paths like "." or ".."
+     *
+     * @param $code
+     * @param $uri
+     * @throws InvalidArgumentException
+     */
+    private function _setUri($code, $uri)
+    {
+        if (!preg_match('/^([a-z0-9_]+[a-z0-9\._]*(\/[a-z0-9_]+[a-z0-9\._]*)*)?$/', $uri)) {
+            throw new InvalidArgumentException(
+                "Must be relative directory path in lowercase with '/' directory separator: '{$uri}'"
+            );
+        }
+        $this->_uris[$code] = $uri;
+    }
+
+    /**
+     * Directory path getter
+     *
+     * @param string $code
+     * @return string|bool
+     */
+    public function getDir($code)
+    {
+        return isset($this->_dirs[$code]) ? $this->_dirs[$code] : false;
+    }
+
+    /**
+     * Set directory
+     *
+     * @param string $code
+     * @param string $path
+     */
+    private function _setDir($code, $path)
+    {
+        $this->_dirs[$code] = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $path);
+    }
+
+    /**
+     * Using default relations, find replacements for child directories if their parent has changed
+     *
+     * For example, "var" has children "var/tmp" and "var/cache". If "var" is customized as "var.test", and its children
+     * are not, then they will be automatically replaced to "var.test/tmp" and "var.test/cache"
+     *
+     * @param array $source
+     * @return array
+     */
+    private function _getDefaultReplacements(array $source)
+    {
+        $result = array();
+        foreach ($source as $parentCode => $parent) {
+            foreach ($this->_getChildren($parentCode) as $childCode) {
+                if (!isset($source[$childCode])) {
+                    if (empty(self::$_defaults[$parentCode])) {
+                        $fragment = self::$_defaults[$childCode];
+                    } else {
+                        $fragment = str_replace(self::$_defaults[$parentCode], '', self::$_defaults[$childCode]);
+                    }
+                    $fragment = ltrim($fragment, '/');
+                    if (!empty($parent)) {
+                        $fragment = '/' . $fragment;
+                    }
+                    $result[$childCode] = $parent . $fragment;
+                }
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Analyze defaults and determine child codes of specified element
+     *
+     * @param string $code
+     * @return array
+     */
+    private function _getChildren($code)
+    {
+        $result = array();
+        if (!isset(self::$_defaults[$code])) {
+            return $result;
+        }
+        $parent = self::$_defaults[$code];
+        foreach (self::$_defaults as $childCode => $child) {
+            if ($code != $childCode) {
+                if ($parent && $child && 0 === strpos($child, $parent)) {
+                    $result[] = $childCode;
+                } elseif (empty($parent)) {
+                    $result[] = $childCode;
+                }
+            }
+        }
+        return $result;
+    }
+}
diff --git a/app/code/core/Mage/Core/Model/Encryption.php b/app/code/core/Mage/Core/Model/Encryption.php
index 1e8f48b92e2..2882f5c4111 100755
--- a/app/code/core/Mage/Core/Model/Encryption.php
+++ b/app/code/core/Mage/Core/Model/Encryption.php
@@ -38,18 +38,41 @@ class Mage_Core_Model_Encryption
      */
     protected $_crypt;
     /**
-     * @var Mage_Core_Helper_Data
+     * @var string
      */
     protected $_helper;
 
+    /**
+     * @var Magento_ObjectManager|null
+     */
+    protected $_objectManager = null;
+
+    /**
+     * @param Magento_ObjectManager $objectManager
+     */
+    public function __construct(Magento_ObjectManager $objectManager)
+    {
+        $this->_objectManager = $objectManager;
+    }
+
     /**
      * Set helper instance
      *
-     * @param Mage_Core_Helper_Data $helper
+     * @param Mage_Core_Helper_Data|string $helper
      * @return Mage_Core_Model_Encryption
+     * @throws InvalidArgumentException
      */
     public function setHelper($helper)
     {
+        if (!is_string($helper)) {
+            if ($helper instanceof Mage_Core_Helper_Data) {
+                $helper = get_class($helper);
+            } else {
+                throw new InvalidArgumentException(
+                    'Input parameter "$helper" must be either "string" or instance of "Mage_Core_Helper_Data"'
+                );
+            }
+        }
         $this->_helper = $helper;
         return $this;
     }
@@ -69,7 +92,7 @@ class Mage_Core_Model_Encryption
     public function getHash($password, $salt = false)
     {
         if (is_integer($salt)) {
-            $salt = $this->_helper->getRandomString($salt);
+            $salt = $this->_objectManager->get($this->_helper)->getRandomString($salt);
         }
         return $salt === false ? $this->hash($password) : $this->hash($salt . $password) . ':' . $salt;
     }
diff --git a/app/code/core/Mage/Core/Model/Layout/Argument/Processor.php b/app/code/core/Mage/Core/Model/Layout/Argument/Processor.php
index 3d6184ecd09..e9fdc1f5413 100644
--- a/app/code/core/Mage/Core/Model/Layout/Argument/Processor.php
+++ b/app/code/core/Mage/Core/Model/Layout/Argument/Processor.php
@@ -38,11 +38,6 @@ class Mage_Core_Model_Layout_Argument_Processor
      */
     protected $_handlerFactory;
 
-    /**
-     * @var Mage_Core_Model_Config
-     */
-    protected $_objectFactory;
-
     /**
      * @var Mage_Core_Model_Layout_Argument_Updater
      */
diff --git a/app/code/core/Mage/Core/Model/Layout/Merge.php b/app/code/core/Mage/Core/Model/Layout/Merge.php
index 5cd7ef0d454..e168830d79f 100644
--- a/app/code/core/Mage/Core/Model/Layout/Merge.php
+++ b/app/code/core/Mage/Core/Model/Layout/Merge.php
@@ -111,7 +111,7 @@ class Mage_Core_Model_Layout_Merge
             $this->_theme = $arguments['theme'];
         } elseif (isset($arguments['area'])) {
             $this->_area = $arguments['area'];
-            $this->_theme = Mage::getDesign()->getConfigurationDesignTheme($arguments['area']);
+            $this->_theme = null;
         } else {
             $this->_area = Mage::getDesign()->getArea();
             $this->_theme = Mage::getDesign()->getDesignTheme()->getId();
diff --git a/app/code/core/Mage/Core/Model/Layout/ScheduledStructure.php b/app/code/core/Mage/Core/Model/Layout/ScheduledStructure.php
index e49727f6038..324b874be1c 100644
--- a/app/code/core/Mage/Core/Model/Layout/ScheduledStructure.php
+++ b/app/code/core/Mage/Core/Model/Layout/ScheduledStructure.php
@@ -339,19 +339,4 @@ class Mage_Core_Model_Layout_ScheduledStructure
         $this->_scheduledElements = array();
         $this->_scheduledStructure = array();
     }
-
-    /**
-     * Cleanup circular references
-     *
-     * Destructor should be called explicitly in order to work around the PHP bug
-     * https://bugs.php.net/bug.php?id=62468
-     */
-    public function  __destruct()
-    {
-        $this->_scheduledStructure = array();
-        $this->_scheduledElements = array();
-        $this->_scheduledMoves = array();
-        $this->_scheduledRemoves = array();
-        $this->_scheduledPaths = array();
-    }
 }
diff --git a/app/code/core/Mage/Core/Model/Logger.php b/app/code/core/Mage/Core/Model/Logger.php
index 402828073ce..b3f1509a396 100644
--- a/app/code/core/Mage/Core/Model/Logger.php
+++ b/app/code/core/Mage/Core/Model/Logger.php
@@ -42,18 +42,13 @@ class Mage_Core_Model_Logger
     protected $_loggers = array();
 
     /**
-     * @var Mage_Core_Model_Config
+     * @var Mage_Core_Model_Dir
      */
-    protected $_config = null;
+    protected $_dirs = null;
 
-    /**
-     * Instantiate with config model
-     *
-     * @param Mage_Core_Model_Config $config
-     */
-    public function __construct(Mage_Core_Model_Config $config)
+    public function __construct(Mage_Core_Model_Dir $dirs)
     {
-        $this->_config = $config;
+        $this->_dirs = $dirs;
     }
 
     /**
@@ -63,16 +58,17 @@ class Mage_Core_Model_Logger
      *
      * @param string $loggerKey
      * @param string $fileOrWrapper
+     * @param string $writerClass
      * @return Mage_Core_Model_Logger
      * @link http://php.net/wrappers
      */
-    public function addStreamLog($loggerKey, $fileOrWrapper = '')
+    public function addStreamLog($loggerKey, $fileOrWrapper = '', $writerClass = '')
     {
         $file = $fileOrWrapper ?: "{$loggerKey}.log";
         if (!preg_match('#^[a-z][a-z0-9+.-]*\://#i', $file)) {
-            $file = $this->_config->getOptions()->getLogDir() . DIRECTORY_SEPARATOR . $file;
+            $logDir = $this->_dirs->getDir(Mage_Core_Model_Dir::LOG);
+            $file = $logDir . DIRECTORY_SEPARATOR . $file;
         }
-        $writerClass = (string)$this->_config->getNode('global/log/core/writer_model');
         if (!$writerClass || !is_subclass_of($writerClass, 'Zend_Log_Writer_Stream')) {
             $writerClass = 'Zend_Log_Writer_Stream';
         }
@@ -89,13 +85,15 @@ class Mage_Core_Model_Logger
      * Reset all loggers and initialize them according to store configuration
      *
      * @param Mage_Core_Model_Store $store
+     * @param Mage_Core_Model_Config $config
      */
-    public function initForStore(Mage_Core_Model_Store $store)
+    public function initForStore(Mage_Core_Model_Store $store, Mage_Core_Model_Config $config)
     {
         $this->_loggers = array();
         if ($store->getConfig('dev/log/active')) {
-            $this->addStreamLog(self::LOGGER_SYSTEM, $store->getConfig('dev/log/file'));
-            $this->addStreamLog(self::LOGGER_EXCEPTION, $store->getConfig('dev/log/exception_file'));
+            $writer = (string)$config->getNode('global/log/core/writer_model');
+            $this->addStreamLog(self::LOGGER_SYSTEM, $store->getConfig('dev/log/file'), $writer);
+            $this->addStreamLog(self::LOGGER_EXCEPTION, $store->getConfig('dev/log/exception_file'), $writer);
         }
     }
 
diff --git a/app/code/core/Mage/Core/Model/Magento/Api.php b/app/code/core/Mage/Core/Model/Magento/Api.php
new file mode 100644
index 00000000000..fdb10b15f73
--- /dev/null
+++ b/app/code/core/Mage/Core/Model/Magento/Api.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Core
+ * @copyright  Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Magento info API
+ *
+ * @category    Mage
+ * @package     Mage_Core
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Core_Model_Magento_Api extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Retrieve information about current Magento installation
+     *
+     * @return array
+     */
+    public function info()
+    {
+        $result = array();
+        $result['magento_edition'] = Mage::getEdition();
+        $result['magento_version'] = Mage::getVersion();
+
+        return $result;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Core/_files/load_configuration.php b/app/code/core/Mage/Core/Model/Magento/Api/V2.php
similarity index 81%
rename from dev/tests/integration/testsuite/Mage/Core/_files/load_configuration.php
rename to app/code/core/Mage/Core/Model/Magento/Api/V2.php
index b6f8c24ac67..84f9698af28 100644
--- a/dev/tests/integration/testsuite/Mage/Core/_files/load_configuration.php
+++ b/app/code/core/Mage/Core/Model/Magento/Api/V2.php
@@ -18,14 +18,19 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category   Mage
- * @package    Mage_Core
+ * @category    Mage
+ * @package     Mage_Directory
  * @copyright  Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-$areaConfig = Mage::getModel(
-    'Mage_Core_Model_Config_Base',
-    array('sourceData' => dirname(__FILE__).'/etc/config.xml')
-);
-Mage::app()->getConfig()->extend($areaConfig);
+/**
+ * Magento info API V2
+ *
+ * @category   Mage
+ * @package    Mage_Core
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Core_Model_Magento_Api_V2 extends Mage_Core_Model_Magento_Api
+{
+}
diff --git a/app/code/core/Mage/Core/Model/Observer.php b/app/code/core/Mage/Core/Model/Observer.php
index c848b029c9c..2229101f412 100644
--- a/app/code/core/Mage/Core/Model/Observer.php
+++ b/app/code/core/Mage/Core/Model/Observer.php
@@ -117,7 +117,7 @@ class Mage_Core_Model_Observer
         $baseDir = $observer->getEvent()->getBaseDir();
         $pathPattern = $observer->getEvent()->getPathPattern();
         try {
-            Mage::getModel('Mage_Core_Model_Theme_Registration')->register($baseDir, $pathPattern);
+            Mage::getObjectManager()->get('Mage_Core_Model_Theme_Registration')->register($baseDir, $pathPattern);
         } catch (Mage_Core_Exception $e) {
             Mage::logException($e);
         }
diff --git a/app/code/core/Mage/Core/Model/Store.php b/app/code/core/Mage/Core/Model/Store.php
index a5fade2330f..87c2a644dc0 100644
--- a/app/code/core/Mage/Core/Model/Store.php
+++ b/app/code/core/Mage/Core/Model/Store.php
@@ -48,21 +48,26 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
      */
     const ENTITY = 'core_store';
 
-    /**
-     * Configuration pathes
-     */
-    const XML_PATH_STORE_STORE_NAME       = 'general/store_information/name';
-    const XML_PATH_STORE_STORE_PHONE      = 'general/store_information/phone';
-    const XML_PATH_STORE_IN_URL           = 'web/url/use_store';
-    const XML_PATH_USE_REWRITES           = 'web/seo/use_rewrites';
-    const XML_PATH_UNSECURE_BASE_URL      = 'web/unsecure/base_url';
-    const XML_PATH_SECURE_BASE_URL        = 'web/secure/base_url';
-    const XML_PATH_SECURE_IN_FRONTEND     = 'web/secure/use_in_frontend';
-    const XML_PATH_SECURE_IN_ADMINHTML    = 'web/secure/use_in_adminhtml';
-    const XML_PATH_SECURE_BASE_LINK_URL   = 'web/secure/base_link_url';
-    const XML_PATH_UNSECURE_BASE_LINK_URL = 'web/unsecure/base_link_url';
-    const XML_PATH_OFFLOADER_HEADER       = 'web/secure/offloader_header';
-    const XML_PATH_PRICE_SCOPE            = 'catalog/price/scope';
+    /**#@+
+     * Configuration paths
+     */
+    const XML_PATH_STORE_STORE_NAME        = 'general/store_information/name';
+    const XML_PATH_STORE_STORE_PHONE       = 'general/store_information/phone';
+    const XML_PATH_STORE_IN_URL            = 'web/url/use_store';
+    const XML_PATH_USE_REWRITES            = 'web/seo/use_rewrites';
+    const XML_PATH_UNSECURE_BASE_URL       = 'web/unsecure/base_url';
+    const XML_PATH_SECURE_BASE_URL         = 'web/secure/base_url';
+    const XML_PATH_SECURE_IN_FRONTEND      = 'web/secure/use_in_frontend';
+    const XML_PATH_SECURE_IN_ADMINHTML     = 'web/secure/use_in_adminhtml';
+    const XML_PATH_SECURE_BASE_LINK_URL    = 'web/secure/base_link_url';
+    const XML_PATH_UNSECURE_BASE_LINK_URL  = 'web/unsecure/base_link_url';
+    const XML_PATH_SECURE_BASE_LIB_URL     = 'web/secure/base_lib_url';
+    const XML_PATH_UNSECURE_BASE_LIB_URL   = 'web/unsecure/base_lib_url';
+    const XML_PATH_SECURE_BASE_MEDIA_URL   = 'web/secure/base_media_url';
+    const XML_PATH_UNSECURE_BASE_MEDIA_URL = 'web/unsecure/base_media_url';
+    const XML_PATH_OFFLOADER_HEADER        = 'web/secure/offloader_header';
+    const XML_PATH_PRICE_SCOPE             = 'catalog/price/scope';
+    /**#@- */
 
     /**
      * Price scope constants
@@ -76,9 +81,8 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
     const URL_TYPE_LINK                   = 'link';
     const URL_TYPE_DIRECT_LINK            = 'direct_link';
     const URL_TYPE_WEB                    = 'web';
-    const URL_TYPE_JS                     = 'js';
+    const URL_TYPE_LIB                    = 'lib';
     const URL_TYPE_MEDIA                  = 'media';
-    const URL_TYPE_THEME                  = 'theme';
 
     /**
      * Code constants
@@ -106,6 +110,11 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
      */
     const MEDIA_REWRITE_SCRIPT            = 'get.php/';
 
+    /**
+     * A placeholder for generating base URL
+     */
+    const BASE_URL_PLACEHOLDER            = '{{base_url}}';
+
     /**
      * Cache flag
      *
@@ -134,13 +143,6 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
      */
     protected $_priceFilter;
 
-    /**
-     * Website model
-     *
-     * @var Mage_Core_Model_Website
-     */
-    protected $_website;
-
     /**
      * Group model
      *
@@ -405,29 +407,26 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
     }
 
     /**
-     * Set website model
+     * Set relation to the website
      *
      * @param Mage_Core_Model_Website $website
      */
     public function setWebsite(Mage_Core_Model_Website $website)
     {
-        $this->_website = $website;
+        $this->setWebsiteId($website->getId());
     }
 
     /**
      * Retrieve store website
      *
-     * @return Mage_Core_Model_Website
+     * @return Mage_Core_Model_Website|bool
      */
     public function getWebsite()
     {
         if (is_null($this->getWebsiteId())) {
             return false;
         }
-        if (is_null($this->_website)) {
-            $this->_website = Mage::app()->getWebsite($this->getWebsiteId());
-        }
-        return $this->_website;
+        return Mage::app()->getWebsite($this->getWebsiteId());
     }
 
     /**
@@ -463,24 +462,17 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
         if (is_string($sValue) && preg_match('/{{(.*)}}.*/', $sValue, $matches)) {
             $placeholder = $matches[1];
             $url = false;
-            if ($placeholder == 'unsecure_base_url' || $placeholder == 'unsecure_public_url') {
+            if ($placeholder == 'unsecure_base_url') {
                 $url = $this->getConfig(self::XML_PATH_UNSECURE_BASE_URL);
-            } elseif ($placeholder == 'secure_base_url' || $placeholder == 'secure_public_url') {
+            } elseif ($placeholder == 'secure_base_url') {
                 $url = $this->getConfig(self::XML_PATH_SECURE_BASE_URL);
             }
-            if ($placeholder == 'unsecure_public_url' || $placeholder == 'secure_public_url') {
-                $pubName = Mage_Core_Model_Config_Options::PUB_DIRECTORY;
-                $url.= (substr(dirname($_SERVER['SCRIPT_FILENAME']), -4) == '/' . $pubName) ? '' : $pubName . '/';
-                // @TODO: investigate how to build correct public URLs from API
-                if (Mage::registry('custom_entry_point')) {
-                    $url .= $pubName . '/';
-                }
-            }
 
             if ($url) {
                 $sValue = str_replace('{{' . $placeholder . '}}', $url, $sValue);
-            } elseif (strpos($sValue, '{{base_url}}') !== false) {
-                $sValue = Mage::getConfig()->substDistroServerVars($sValue);
+            } elseif (strpos($sValue, Mage_Core_Model_Store::BASE_URL_PLACEHOLDER) !== false) {
+                $distroBaseUrl = Mage::getConfig()->getDistroBaseUrl();
+                $sValue = str_replace(Mage_Core_Model_Store::BASE_URL_PLACEHOLDER, $distroBaseUrl, $sValue);
             }
         }
 
@@ -489,19 +481,6 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
         return $sValue;
     }
 
-    /**
-     * Retrieve default base path
-     *
-     * @return string
-     */
-    public function getDefaultBasePath()
-    {
-        if (!isset($_SERVER['SCRIPT_NAME'])) {
-            return '/';
-        }
-        return rtrim(Mage::app()->getRequest()->getBasePath() . '/') . '/';
-    }
-
     /**
      * Retrieve url using store configuration specific
      *
@@ -532,47 +511,57 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
     {
         $cacheKey = $type . '/' . (is_null($secure) ? 'null' : ($secure ? 'true' : 'false'));
         if (!isset($this->_baseUrlCache[$cacheKey])) {
+            $secure = is_null($secure) ? $this->isCurrentlySecure() : (bool)$secure;
+            /** @var $dirs Mage_Core_Model_Dir */
+            $dirs = Mage::getObjectManager()->get('Mage_Core_Model_Dir');
+            
             switch ($type) {
                 case self::URL_TYPE_WEB:
-                    $secure = is_null($secure) ? $this->isCurrentlySecure() : (bool)$secure;
-                    $url = $this->getConfig('web/' . ($secure ? 'secure' : 'unsecure') . '/base_url');
+                    $path = $secure ? self::XML_PATH_SECURE_BASE_URL : self::XML_PATH_UNSECURE_BASE_URL;
+                    $url = $this->getConfig($path);
                     break;
 
                 case self::URL_TYPE_LINK:
-                    $secure = (bool) $secure;
-                    $url = $this->getConfig('web/' . ($secure ? 'secure' : 'unsecure') . '/base_link_url');
+                    $path = $secure ? self::XML_PATH_SECURE_BASE_LINK_URL : self::XML_PATH_UNSECURE_BASE_LINK_URL;
+                    $url = $this->getConfig($path);
                     $url = $this->_updatePathUseRewrites($url);
                     $url = $this->_updatePathUseStoreView($url);
                     break;
 
                 case self::URL_TYPE_DIRECT_LINK:
-                    $secure = (bool) $secure;
-                    $url = $this->getConfig('web/' . ($secure ? 'secure' : 'unsecure') . '/base_link_url');
+                    $path = $secure ? self::XML_PATH_SECURE_BASE_LINK_URL : self::XML_PATH_UNSECURE_BASE_LINK_URL;
+                    $url = $this->getConfig($path);
                     $url = $this->_updatePathUseRewrites($url);
                     break;
 
-                case self::URL_TYPE_JS:
-                    $secure = is_null($secure) ? $this->isCurrentlySecure() : (bool) $secure;
-                    $url = $this->getConfig('web/' . ($secure ? 'secure' : 'unsecure') . '/base_public_url') . 'lib/';
-                    break;
-
-                case self::URL_TYPE_THEME:
-                    $secure = is_null($secure) ? $this->isCurrentlySecure() : (bool) $secure;
-                    $url = $this->getConfig('web/' . ($secure ? 'secure' : 'unsecure') . '/base_public_url')
-                        . 'media/theme/';
+                case self::URL_TYPE_LIB:
+                    $path = $secure ? self::XML_PATH_SECURE_BASE_LIB_URL : self::XML_PATH_UNSECURE_BASE_LIB_URL;
+                    $url = $this->getConfig($path);
+                    if (!$url) {
+                        $url = $this->getBaseUrl(self::URL_TYPE_WEB, $secure)
+                            . $dirs->getUri(Mage_Core_Model_Dir::PUB_LIB);
+                    }
                     break;
 
                 case self::URL_TYPE_MEDIA:
-                    $url = $this->_updateMediaPathUseRewrites($secure);
+                    $url = $this->_getMediaScriptUrl($dirs, $secure);
+                    if (!$url) {
+                        $path = $secure ? self::XML_PATH_SECURE_BASE_MEDIA_URL : self::XML_PATH_UNSECURE_BASE_MEDIA_URL;
+                        $url = $this->getConfig($path);
+                        if (!$url) {
+                            $url = $this->getBaseUrl(self::URL_TYPE_WEB, $secure)
+                                . $dirs->getUri(Mage_Core_Model_Dir::MEDIA);
+                        }
+                    }
                     break;
 
                 default:
-                    throw Mage::exception('Mage_Core', Mage::helper('Mage_Core_Helper_Data')->__('Invalid base url type'));
+                    throw new InvalidArgumentException('Invalid base url type');
             }
 
-            if (false !== strpos($url, '{{base_url}}')) {
-                $baseUrl = Mage::getConfig()->substDistroServerVars('{{base_url}}');
-                $url = str_replace('{{base_url}}', $baseUrl, $url);
+            if (false !== strpos($url, Mage_Core_Model_Store::BASE_URL_PLACEHOLDER)) {
+                $distroBaseUrl = Mage::getConfig()->getDistroBaseUrl();
+                $url = str_replace(Mage_Core_Model_Store::BASE_URL_PLACEHOLDER, $distroBaseUrl, $url);
             }
 
             $this->_baseUrlCache[$cacheKey] = rtrim($url, '/') . '/';
@@ -619,22 +608,19 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
      * If we use Database file storage and server doesn't support rewrites (.htaccess in media folder)
      * we have to put name of fetching media script exactly into URL
      *
-     * @param null|boolean $secure
-     * @param string $type
-     * @return string
+     * @param Mage_Core_Model_Dir $dirs
+     * @param bool $secure
+     * @return string|bool
      */
-    protected function _updateMediaPathUseRewrites($secure = null, $type = self::URL_TYPE_MEDIA)
+    protected function _getMediaScriptUrl(Mage_Core_Model_Dir $dirs, $secure)
     {
-        $secure = is_null($secure) ? $this->isCurrentlySecure() : (bool) $secure;
-        $secureStringFlag = $secure ? 'secure' : 'unsecure';
-        $url = $this->getConfig('web/' . $secureStringFlag . '/base_' . $type . '_url');
         if (!$this->getConfig(self::XML_PATH_USE_REWRITES)
             && Mage::helper('Mage_Core_Helper_File_Storage_Database')->checkDbUsage()
         ) {
-            $urlStart = $this->getConfig('web/' . $secureStringFlag . '/base_public_url');
-            $url = str_replace($urlStart, $urlStart . self::MEDIA_REWRITE_SCRIPT, $url);
+            return $this->getBaseUrl(self::URL_TYPE_WEB, $secure) . $dirs->getUri(Mage_Core_Model_Dir::PUB)
+                . '/' . self::MEDIA_REWRITE_SCRIPT;
         }
-        return $url;
+        return false;
     }
 
     /**
@@ -1009,23 +995,20 @@ class Mage_Core_Model_Store extends Mage_Core_Model_Abstract
      */
     public function setGroup($group)
     {
-        $this->_group = $group;
+        $this->setGroupId($group->getId());
     }
 
     /**
      * Retrieve group model
      *
-     * @return Mage_Core_Model_Store_Group
+     * @return Mage_Core_Model_Store_Group|bool
      */
     public function getGroup()
     {
         if (is_null($this->getGroupId())) {
             return false;
         }
-        if (is_null($this->_group)) {
-            $this->_group = Mage::getModel('Mage_Core_Model_Store_Group')->load($this->getGroupId());
-        }
-        return $this->_group;
+        return Mage::app()->getGroup($this->getGroupId());
     }
 
     /**
diff --git a/app/code/core/Mage/Core/Model/Store/Api.php b/app/code/core/Mage/Core/Model/Store/Api.php
new file mode 100644
index 00000000000..5f125dc368a
--- /dev/null
+++ b/app/code/core/Mage/Core/Model/Store/Api.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.
+ *
+ * @category    Mage
+ * @package     Mage_Core
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Store API
+ *
+ * @category    Mage
+ * @package     Mage_Core
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+
+class Mage_Core_Model_Store_Api extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Retrieve stores list
+     *
+     * @return array
+     */
+    public function items()
+    {
+        // Retrieve stores
+        $stores = Mage::app()->getStores();
+
+        // Make result array
+        $result = array();
+        foreach ($stores as $store) {
+            $result[] = array(
+                'store_id'    => $store->getId(),
+                'code'        => $store->getCode(),
+                'website_id'  => $store->getWebsiteId(),
+                'group_id'    => $store->getGroupId(),
+                'name'        => $store->getName(),
+                'sort_order'  => $store->getSortOrder(),
+                'is_active'   => $store->getIsActive()
+            );
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve store data
+     *
+     * @param string|int $storeId
+     * @return array
+     */
+    public function info($storeId)
+    {
+        // Retrieve store info
+        try {
+            $store = Mage::app()->getStore($storeId);
+        } catch (Mage_Core_Model_Store_Exception $e) {
+            $this->_fault('store_not_exists');
+        }
+
+        if (!$store->getId()) {
+            $this->_fault('store_not_exists');
+        }
+
+        // Basic store data
+        $result = array();
+        $result['store_id'] = $store->getId();
+        $result['code'] = $store->getCode();
+        $result['website_id'] = $store->getWebsiteId();
+        $result['group_id'] = $store->getGroupId();
+        $result['name'] = $store->getName();
+        $result['sort_order'] = $store->getSortOrder();
+        $result['is_active'] = $store->getIsActive();
+
+        return $result;
+    }
+
+}
diff --git a/app/code/core/Mage/Adminhtml/Block/Abstract.php b/app/code/core/Mage/Core/Model/Store/Api/V2.php
similarity index 85%
rename from app/code/core/Mage/Adminhtml/Block/Abstract.php
rename to app/code/core/Mage/Core/Model/Store/Api/V2.php
index 6731c563995..66dad500410 100644
--- a/app/code/core/Mage/Adminhtml/Block/Abstract.php
+++ b/app/code/core/Mage/Core/Model/Store/Api/V2.php
@@ -19,18 +19,18 @@
  * needs please refer to http://www.magentocommerce.com for more information.
  *
  * @category    Mage
- * @package     Mage_Adminhtml
+ * @package     Mage_Directory
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
 /**
+ * Directory Country Api V2
+ *
  * @category   Mage
- * @package    Mage_Adminhtml
+ * @package    Mage_Core
  * @author     Magento Core Team <core@magentocommerce.com>
- * @deprecated Moved to module Mage_Backend
  */
-class Mage_Adminhtml_Block_Abstract extends Mage_Backend_Block_Abstract
+class Mage_Core_Model_Store_Api_V2 extends Mage_Core_Model_Store_Api
 {
-
 }
diff --git a/app/code/core/Mage/Core/Model/Store/Group.php b/app/code/core/Mage/Core/Model/Store/Group.php
index f53b7712b06..6b5bff23f59 100644
--- a/app/code/core/Mage/Core/Model/Store/Group.php
+++ b/app/code/core/Mage/Core/Model/Store/Group.php
@@ -92,13 +92,6 @@ class Mage_Core_Model_Store_Group extends Mage_Core_Model_Abstract
      */
     protected $_defaultStore;
 
-    /**
-     * Website model
-     *
-     * @var Mage_Core_Model_Website
-     */
-    protected $_website;
-
     /**
      * @var bool
      */
@@ -268,29 +261,26 @@ class Mage_Core_Model_Store_Group extends Mage_Core_Model_Abstract
     }
 
     /**
-     * Set website model
+     * Set relation to the website
      *
      * @param Mage_Core_Model_Website $website
      */
     public function setWebsite(Mage_Core_Model_Website $website)
     {
-        $this->_website = $website;
+        $this->setWebsiteId($website->getId());
     }
 
     /**
      * Retrieve website model
      *
-     * @return Mage_Core_Model_Website
+     * @return Mage_Core_Model_Website|bool
      */
     public function getWebsite()
     {
         if (is_null($this->getWebsiteId())) {
             return false;
         }
-        if (is_null($this->_website)) {
-            $this->_website = Mage::app()->getWebsite($this->getWebsiteId());
-        }
-        return $this->_website;
+        return Mage::app()->getWebsite($this->getWebsiteId());
     }
 
     /**
diff --git a/app/code/core/Mage/Core/Model/Theme.php b/app/code/core/Mage/Core/Model/Theme.php
index 2bf939db1ee..ab0f6e6484e 100644
--- a/app/code/core/Mage/Core/Model/Theme.php
+++ b/app/code/core/Mage/Core/Model/Theme.php
@@ -380,7 +380,8 @@ class Mage_Core_Model_Theme extends Mage_Core_Model_Abstract
      */
     public static function getPreviewImageDirectoryUrl()
     {
-        return Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_THEME) . self::IMAGE_DIR_PREVIEW . '/';
+        return Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA)
+            . Mage_Core_Model_Design_Package::PUBLIC_BASE_THEME_DIR . '/' . self::IMAGE_DIR_PREVIEW . '/';
     }
 
     /**
diff --git a/app/code/core/Mage/Core/Model/Theme/Registration.php b/app/code/core/Mage/Core/Model/Theme/Registration.php
index 4ba0e34826e..5671f150471 100644
--- a/app/code/core/Mage/Core/Model/Theme/Registration.php
+++ b/app/code/core/Mage/Core/Model/Theme/Registration.php
@@ -94,8 +94,6 @@ class Mage_Core_Model_Theme_Registration
             $this->_registerThemeRecursively($theme);
         }
 
-        $this->registerDefaultThemes();
-
         /** @var $dbCollection Mage_Core_Model_Resource_Theme_Collection */
         $dbCollection = $this->getThemeModel()->getResourceCollection();
         $dbCollection->checkParentInThemes();
@@ -139,53 +137,6 @@ class Mage_Core_Model_Theme_Registration
         return $this;
     }
 
-    /**
-     * Get default theme design paths specified in configuration
-     *
-     * @return array
-     */
-    protected function _getDefaultThemes()
-    {
-        $themesByArea = array();
-        $themeItems = $this->_collection->getItems();
-        /** @var $theme Mage_Core_Model_Theme */
-        foreach ($themeItems as $theme) {
-            $area = $theme->getArea();
-            if (!isset($themesByArea[$area])) {
-                $themePath = $this->_getDesign()->getConfigurationDesignTheme($area, array('useId' => false));
-                $fullPath = $area . '/' . $themePath;
-                $themesByArea[$area] = isset($themeItems[$fullPath]) ? $themeItems[$fullPath] : null;
-            }
-        }
-        return $themesByArea;
-    }
-
-    /**
-     * Set default themes stored in configuration
-     *
-     * @return Mage_Core_Model_Theme_Registration
-     */
-    public function registerDefaultThemes()
-    {
-        /** @var $theme Mage_Core_Model_Theme */
-        foreach ($this->_getDefaultThemes() as $area => $theme) {
-            if ($theme && $theme->getId()) {
-                Mage::app()->getConfig()->saveConfig($this->_getDesign()->getConfigPathByArea($area), $theme->getId());
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * Get current design model
-     *
-     * @return Mage_Core_Model_Design_Package
-     */
-    protected function _getDesign()
-    {
-        return Mage::getDesign();
-    }
-
     /**
      * Get theme from DB by full path
      *
diff --git a/app/code/core/Mage/Core/Model/Theme/Service.php b/app/code/core/Mage/Core/Model/Theme/Service.php
index 9d77b139ace..dbbd7e2bc11 100644
--- a/app/code/core/Mage/Core/Model/Theme/Service.php
+++ b/app/code/core/Mage/Core/Model/Theme/Service.php
@@ -121,8 +121,7 @@ class Mage_Core_Model_Theme_Service
     public function assignThemeToStores(
         $themeId,
         array $stores = array(),
-        $scope = Mage_Core_Model_Config::SCOPE_STORES,
-        $area = Mage_Core_Model_App_Area::AREA_FRONTEND
+        $scope = Mage_Core_Model_Config::SCOPE_STORES
     ) {
         /** @var $theme Mage_Core_Model_Theme */
         $theme = $this->_themeFactory->create()->load($themeId);
@@ -132,7 +131,7 @@ class Mage_Core_Model_Theme_Service
 
         $themeCustomization = $theme->isVirtual() ? $theme : $this->createThemeCustomization($theme);
 
-        $configPath = $this->_design->getConfigPathByArea($area);
+        $configPath = Mage_Core_Model_Design_Package::XML_PATH_THEME_ID;
 
         // Unassign given theme from stores that were unchecked
         /** @var $config Mage_Core_Model_Config_Data */
@@ -158,7 +157,6 @@ class Mage_Core_Model_Theme_Service
                 'themeId'            => $themeId,
                 'stores'             => $stores,
                 'scope'              => $scope,
-                'area'               => $area,
                 'theme'              => $theme,
                 'themeCustomization' => $themeCustomization,
             )
diff --git a/app/code/core/Mage/Core/Model/Translate.php b/app/code/core/Mage/Core/Model/Translate.php
index 9b149871abb..6d4f65d0c66 100644
--- a/app/code/core/Mage/Core/Model/Translate.php
+++ b/app/code/core/Mage/Core/Model/Translate.php
@@ -112,13 +112,20 @@ class Mage_Core_Model_Translate
      */
     protected $_localeHierarchy = array();
 
+    /**
+     * @var Mage_Core_Model_Design_Package
+     */
+    protected $_designPackage;
+
     /**
      * Initialize translate model
      *
+     * @param Mage_Core_Model_Design_Package $designPackage
      * @param array $data
      */
-    public function __construct(array $data = array())
+    public function __construct(Mage_Core_Model_Design_Package $designPackage, array $data = array())
     {
+        $this->_designPackage = $designPackage;
         if (isset($data['locale_hierarchy']) && is_array($data['locale_hierarchy'])) {
             $this->_localeHierarchy = $data['locale_hierarchy'];
         } else {
@@ -207,7 +214,7 @@ class Mage_Core_Model_Translate
             $this->_config[self::CONFIG_KEY_STORE] = Mage::app()->getStore()->getId();
         }
         if (!isset($this->_config[self::CONFIG_KEY_DESIGN_THEME])) {
-            $this->_config[self::CONFIG_KEY_DESIGN_THEME] = Mage::getDesign()->getDesignTheme()->getId();
+            $this->_config[self::CONFIG_KEY_DESIGN_THEME] = $this->_designPackage->getDesignTheme()->getId();
         }
         return $this;
     }
@@ -266,6 +273,7 @@ class Mage_Core_Model_Translate
      *
      * @param array $data
      * @param string $scope
+     * @param boolean $forceReload
      * @return Mage_Core_Model_Translate
      */
     protected function _addData($data, $scope, $forceReload=false)
@@ -313,7 +321,7 @@ class Mage_Core_Model_Translate
     {
         $requiredLocaleList = $this->_composeRequiredLocaleList($this->getLocale());
         foreach ($requiredLocaleList as $locale) {
-            $file = Mage::getDesign()->getLocaleFileName('translate.csv', array('locale' => $locale));
+            $file = $this->_designPackage->getLocaleFileName('translate.csv', array('locale' => $locale));
             $this->_addData($this->_getFileData($file), false, $forceReload);
         }
         return $this;
@@ -322,6 +330,7 @@ class Mage_Core_Model_Translate
     /**
      * Loading current store translation from DB
      *
+     * @param boolean $forceReload
      * @return Mage_Core_Model_Translate
      */
     protected function _loadDbTranslation($forceReload = false)
@@ -517,7 +526,6 @@ class Mage_Core_Model_Translate
     /**
      * Loading data cache
      *
-     * @param   string $area
      * @return  array | false
      */
     protected function _loadCache()
@@ -533,7 +541,6 @@ class Mage_Core_Model_Translate
     /**
      * Saving data cache
      *
-     * @param   string $area
      * @return  Mage_Core_Model_Translate
      */
     protected function _saveCache()
diff --git a/app/code/core/Mage/Core/etc/api.xml b/app/code/core/Mage/Core/etc/api.xml
new file mode 100644
index 00000000000..648c653c8c9
--- /dev/null
+++ b/app/code/core/Mage/Core/etc/api.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Core
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <core_store translate="title" module="Mage_Core">
+                <model>Mage_Core_Model_Store_Api</model>
+                <title>Store API</title>
+                <acl>core/store</acl>
+                <methods>
+                    <list translate="title" module="Mage_Core">
+                        <title>Retrieve store list</title>
+                        <method>items</method>
+                        <acl>core/store/list</acl>
+                    </list>
+                    <info translate="title" module="Mage_Core">
+                        <title>Retrieve store data</title>
+                        <acl>core/store/info</acl>
+                    </info>
+                </methods>
+                <faults module="Mage_Core">
+                    <store_not_exists>
+                        <code>100</code>
+                        <message>Requested store view is not found.</message>
+                    </store_not_exists>
+                </faults>
+            </core_store>
+            <core_magento translate="title" module="Mage_Core">
+                <model>Mage_Core_Model_Magento_Api</model>
+                <title>Magento info API</title>
+                <acl>core/magento</acl>
+                <methods>
+                    <info translate="title" module="Mage_Core">
+                        <title>Get info about current Magento installation</title>
+                        <acl>core/magento/info</acl>
+                    </info>
+                </methods>
+            </core_magento>
+        </resources>
+        <resources_alias>
+            <store>core_store</store>
+            <magento>core_magento</magento>
+        </resources_alias>
+        <v2>
+            <resources_function_prefix>
+                <store>store</store>
+                <magento>magento</magento>
+            </resources_function_prefix>
+        </v2>
+        <rest>
+            <mapping>
+            </mapping>
+        </rest>
+        <acl>
+            <resources>
+                <core translate="title" module="Mage_Core">
+                    <title>Core</title>
+                    <sort_order>1</sort_order>
+                    <store translate="title" module="Mage_Core">
+                        <title>Store</title>
+                        <info translate="title" module="Mage_Core">
+                            <title>Retrieve store data</title>
+                        </info>
+                        <list translate="title" module="Mage_Core">
+                            <title>List of stores</title>
+                        </list>
+                    </store>
+                    <magento translate="title" module="Mage_Core">
+                        <title>Magento info</title>
+                        <info translate="title" module="Mage_Core">
+                            <title>Retrieve info about current Magento installation</title>
+                        </info>
+                    </magento>
+                </core>
+            </resources>
+        </acl>
+    </api>
+</config>
diff --git a/app/code/core/Mage/Core/etc/config.xml b/app/code/core/Mage/Core/etc/config.xml
index 7cfcd73d5ce..c93420ebf08 100644
--- a/app/code/core/Mage/Core/etc/config.xml
+++ b/app/code/core/Mage/Core/etc/config.xml
@@ -71,6 +71,11 @@
                 </collections>
             </types>
         </cache>
+        <design>
+            <theme>
+                <allow_view_files_duplication>1</allow_view_files_duplication>
+            </theme>
+        </design>
         <session>
             <validation>
                 <http_user_agent_skip>
@@ -116,6 +121,11 @@
         </di>
     </global>
     <frontend>
+        <design>
+            <theme>
+                <full_name>default/demo</full_name>
+            </theme>
+        </design>
         <events>
             <controller_action_layout_generate_blocks_after>
                 <observers>
@@ -217,10 +227,6 @@
     </install>
     <default>
         <design>
-            <theme>
-                <full_name>default/demo</full_name>
-                <allow_view_files_duplication>1</allow_view_files_duplication>
-            </theme>
             <pagination>
                 <list_allow_all>1</list_allow_all>
                 <pagination_frame>5</pagination_frame>
@@ -308,15 +314,11 @@
                 <base_url>{{base_url}}</base_url>
                 <base_web_url>{{unsecure_base_url}}</base_web_url>
                 <base_link_url>{{unsecure_base_url}}</base_link_url>
-                <base_public_url>{{unsecure_public_url}}</base_public_url>
-                <base_media_url>{{unsecure_public_url}}media/</base_media_url>
             </unsecure>
             <secure>
-                <base_url>{{base_url}}</base_url>
+                <base_url>{{unsecure_base_url}}</base_url>
                 <base_web_url>{{secure_base_url}}</base_web_url>
                 <base_link_url>{{secure_base_url}}</base_link_url>
-                <base_public_url>{{secure_public_url}}</base_public_url>
-                <base_media_url>{{secure_public_url}}media/</base_media_url>
                 <use_in_frontend>0</use_in_frontend>
                 <use_in_adminhtml>0</use_in_adminhtml>
                 <offloader_header>SSL_OFFLOADED</offloader_header>
diff --git a/app/code/core/Mage/Core/etc/wsdl.xml b/app/code/core/Mage/Core/etc/wsdl.xml
new file mode 100644
index 00000000000..8f3116b73f2
--- /dev/null
+++ b/app/code/core/Mage/Core/etc/wsdl.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
+    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
+            <complexType name="storeEntity">
+                <all>
+                    <element name="store_id" type="xsd:int" />
+                    <element name="code" type="xsd:string" />
+                    <element name="website_id" type="xsd:int" />
+                    <element name="group_id" type="xsd:int" />
+                    <element name="name" type="xsd:string" />
+                    <element name="sort_order" type="xsd:int" />
+                    <element name="is_active" type="xsd:int" />
+                </all>
+            </complexType>
+            <complexType name="storeEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:storeEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="magentoInfoEntity">
+                <all>
+                    <element name="magento_version" type="xsd:string" />
+                    <element name="magento_edition" type="xsd:string" />
+                </all>
+            </complexType>
+        </schema>
+    </types>
+    <message name="storeListRequest">
+        <part name="sessionId" type="xsd:string" />
+    </message>
+    <message name="storeListResponse">
+        <part name="stores" type="typens:storeEntityArray" />
+    </message>
+    <message name="magentoInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+    </message>
+    <message name="magentoInfoResponse">
+        <part name="info" type="typens:magentoInfoEntity" />
+    </message>
+    <message name="storeInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="storeId" type="xsd:string" />
+    </message>
+    <message name="storeInfoResponse">
+        <part name="info" type="typens:storeEntity" />
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="storeList">
+            <documentation>List of stores</documentation>
+            <input message="typens:storeListRequest" />
+            <output message="typens:storeListResponse" />
+        </operation>
+        <operation name="storeInfo">
+            <documentation>Store view info</documentation>
+            <input message="typens:storeInfoRequest" />
+            <output message="typens:storeInfoResponse" />
+        </operation>
+        <operation name="magentoInfo">
+            <documentation>Info about current Magento installation</documentation>
+            <input message="typens:magentoInfoRequest" />
+            <output message="typens:magentoInfoResponse" />
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="storeList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="storeInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="magentoInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/Core/etc/wsi.xml b/app/code/core/Mage/Core/etc/wsi.xml
new file mode 100644
index 00000000000..7e2b3b71557
--- /dev/null
+++ b/app/code/core/Mage/Core/etc/wsi.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="storeEntity">
+                <xsd:sequence>
+                    <xsd:element name="store_id" type="xsd:int" />
+                    <xsd:element name="code" type="xsd:string" />
+                    <xsd:element name="website_id" type="xsd:int" />
+                    <xsd:element name="group_id" type="xsd:int" />
+                    <xsd:element name="name" type="xsd:string" />
+                    <xsd:element name="sort_order" type="xsd:int" />
+                    <xsd:element name="is_active" type="xsd:int" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="storeEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:storeEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="magentoInfoEntity">
+                <xsd:sequence>
+                    <xsd:element minOccurs="1" maxOccurs="1" name="magento_version" type="xsd:string" />
+                    <xsd:element minOccurs="1" maxOccurs="1" name="magento_edition" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:element name="storeListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="storeListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:storeEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="storeInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="storeId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="storeInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:storeEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="magentoInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="magentoInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:magentoInfoEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="storeListRequest">
+        <wsdl:part name="parameters" element="typens:storeListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="storeListResponse">
+        <wsdl:part name="parameters" element="typens:storeListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="storeInfoRequest">
+        <wsdl:part name="parameters" element="typens:storeInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="storeInfoResponse">
+        <wsdl:part name="parameters" element="typens:storeInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="magentoInfoRequest">
+        <wsdl:part name="parameters" element="typens:magentoInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="magentoInfoResponse">
+        <wsdl:part name="parameters" element="typens:magentoInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="storeList">
+            <wsdl:documentation>List of stores</wsdl:documentation>
+            <wsdl:input message="typens:storeListRequest" />
+            <wsdl:output message="typens:storeListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="storeInfo">
+            <wsdl:documentation>Store view info</wsdl:documentation>
+            <wsdl:input message="typens:storeInfoRequest" />
+            <wsdl:output message="typens:storeInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="magentoInfo">
+            <wsdl:documentation>Info about current Magento installation</wsdl:documentation>
+            <wsdl:input message="typens:magentoInfoRequest" />
+            <wsdl:output message="typens:magentoInfoResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="storeList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="storeInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="magentoInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="{{var wsdl.name}}Service">
+        <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/Customer/Model/Address/Api.php b/app/code/core/Mage/Customer/Model/Address/Api.php
new file mode 100644
index 00000000000..8ff9218547c
--- /dev/null
+++ b/app/code/core/Mage/Customer/Model/Address/Api.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.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Customer address api
+ *
+ * @category   Mage
+ * @package    Mage_Customer
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Customer_Model_Address_Api extends Mage_Customer_Model_Api_Resource
+{
+    protected $_mapAttributes = array(
+        'customer_address_id' => 'entity_id'
+    );
+
+    public function __construct()
+    {
+        $this->_ignoredAttributeCodes[] = 'parent_id';
+    }
+
+    /**
+     * Retrive customer addresses list
+     *
+     * @param int $customerId
+     * @return array
+     */
+    public function items($customerId)
+    {
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')
+            ->load($customerId);
+        /* @var $customer Mage_Customer_Model_Customer */
+
+        if (!$customer->getId()) {
+            $this->_fault('customer_not_exists');
+        }
+
+        $result = array();
+        foreach ($customer->getAddresses() as $address) {
+            $data = $address->toArray();
+            $row  = array();
+
+            foreach ($this->_mapAttributes as $attributeAlias => $attributeCode) {
+                $row[$attributeAlias] = isset($data[$attributeCode]) ? $data[$attributeCode] : null;
+            }
+
+            foreach ($this->getAllowedAttributes($address) as $attributeCode => $attribute) {
+                if (isset($data[$attributeCode])) {
+                    $row[$attributeCode] = $data[$attributeCode];
+                }
+            }
+
+            $row['is_default_billing'] = $customer->getDefaultBilling() == $address->getId();
+            $row['is_default_shipping'] = $customer->getDefaultShipping() == $address->getId();
+
+            $result[] = $row;
+
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve address data
+     *
+     * @param int $addressId
+     * @return array
+     */
+    public function info($addressId)
+    {
+        $address = Mage::getModel('Mage_Customer_Model_Address')
+            ->load($addressId);
+
+        if (!$address->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        $result = array();
+
+        foreach ($this->_mapAttributes as $attributeAlias => $attributeCode) {
+            $result[$attributeAlias] = $address->getData($attributeCode);
+        }
+
+        foreach ($this->getAllowedAttributes($address) as $attributeCode => $attribute) {
+            $result[$attributeCode] = $address->getData($attributeCode);
+        }
+
+
+        if ($customer = $address->getCustomer()) {
+            $result['is_default_billing']  = $customer->getDefaultBilling() == $address->getId();
+            $result['is_default_shipping'] = $customer->getDefaultShipping() == $address->getId();
+        }
+
+        return $result;
+    }
+
+    /**
+     * Delete address
+     *
+     * @param int $addressId
+     * @return boolean
+     */
+    public function delete($addressId)
+    {
+        $address = Mage::getModel('Mage_Customer_Model_Address')
+            ->load($addressId);
+
+        if (!$address->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        try {
+            $address->delete();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_deleted', $e->getMessage());
+        }
+
+        return true;
+    }
+} // Class Mage_Customer_Model_Address_Api End
diff --git a/app/code/core/Mage/Customer/Model/Address/Api/V2.php b/app/code/core/Mage/Customer/Model/Address/Api/V2.php
new file mode 100644
index 00000000000..953c798b1e2
--- /dev/null
+++ b/app/code/core/Mage/Customer/Model/Address/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Customer address api V2
+ *
+ * @category   Mage
+ * @package    Mage_Customer
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Customer_Model_Address_Api_V2 extends Mage_Customer_Model_Address_Api
+{
+    /**
+     * Create new address for customer
+     *
+     * @param int $customerId
+     * @param array $addressData
+     * @return int
+     */
+    public function create($customerId, $addressData)
+    {
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')
+            ->load($customerId);
+        /* @var $customer Mage_Customer_Model_Customer */
+
+        if (!$customer->getId()) {
+            $this->_fault('customer_not_exists');
+        }
+
+        $address = Mage::getModel('Mage_Customer_Model_Address');
+
+        foreach ($this->getAllowedAttributes($address) as $attributeCode=>$attribute) {
+            if (isset($addressData->$attributeCode)) {
+                $address->setData($attributeCode, $addressData->$attributeCode);
+            }
+        }
+
+        if (isset($addressData->is_default_billing)) {
+            $address->setIsDefaultBilling($addressData->is_default_billing);
+        }
+
+        if (isset($addressData->is_default_shipping)) {
+            $address->setIsDefaultShipping($addressData->is_default_shipping);
+        }
+
+        $address->setCustomerId($customer->getId());
+
+        $valid = $address->validate();
+
+        if (is_array($valid)) {
+            $this->_fault('data_invalid', implode("\n", $valid));
+        }
+
+        try {
+            $address->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return $address->getId();
+    }
+
+    /**
+     * Retrieve address data
+     *
+     * @param int $addressId
+     * @return array
+     */
+    public function info($addressId)
+    {
+        $address = Mage::getModel('Mage_Customer_Model_Address')
+            ->load($addressId);
+
+        if (!$address->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        $result = array();
+
+        foreach ($this->_mapAttributes as $attributeAlias => $attributeCode) {
+            $result[$attributeAlias] = $address->getData($attributeCode);
+        }
+
+        foreach ($this->getAllowedAttributes($address) as $attributeCode => $attribute) {
+            $result[$attributeCode] = $address->getData($attributeCode);
+        }
+
+
+        if ($customer = $address->getCustomer()) {
+            $result['is_default_billing']  = $customer->getDefaultBilling() == $address->getId();
+            $result['is_default_shipping'] = $customer->getDefaultShipping() == $address->getId();
+        }
+
+        return $result;
+    }
+
+    /**
+     * Update address data
+     *
+     * @param int $addressId
+     * @param array $addressData
+     * @return boolean
+     */
+    public function update($addressId, $addressData)
+    {
+        $address = Mage::getModel('Mage_Customer_Model_Address')
+            ->load($addressId);
+
+        if (!$address->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        foreach ($this->getAllowedAttributes($address) as $attributeCode=>$attribute) {
+            if (isset($addressData->$attributeCode)) {
+                $address->setData($attributeCode, $addressData->$attributeCode);
+            }
+        }
+
+        if (isset($addressData->is_default_billing)) {
+            $address->setIsDefaultBilling($addressData->is_default_billing);
+        }
+
+        if (isset($addressData->is_default_shipping)) {
+            $address->setIsDefaultShipping($addressData->is_default_shipping);
+        }
+
+        $valid = $address->validate();
+        if (is_array($valid)) {
+            $this->_fault('data_invalid', implode("\n", $valid));
+        }
+
+        try {
+            $address->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+} // Class Mage_Customer_Model_Address_Api End
diff --git a/app/code/core/Mage/Customer/Model/Api/Resource.php b/app/code/core/Mage/Customer/Model/Api/Resource.php
new file mode 100644
index 00000000000..109181556b3
--- /dev/null
+++ b/app/code/core/Mage/Customer/Model/Api/Resource.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.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Customer abstract API resource
+ *
+ * @category   Mage
+ * @package    Mage_Customer
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Customer_Model_Api_Resource extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Default ignored attribute codes
+     *
+     * @var array
+     */
+    protected $_ignoredAttributeCodes = array('entity_id', 'attribute_set_id', 'entity_type_id');
+
+    /**
+     * Default ignored attribute types
+     *
+     * @var array
+     */
+    protected $_ignoredAttributeTypes = array();
+
+    /**
+     * Check is attribute allowed
+     *
+     * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
+     * @param array $attributes
+     * @return boolean
+     */
+    protected function _isAllowedAttribute($attribute, array $filter = null)
+    {
+        if (!is_null($filter)
+            && !( in_array($attribute->getAttributeCode(), $filter)
+                  || in_array($attribute->getAttributeId(), $filter))) {
+            return false;
+        }
+
+        return !in_array($attribute->getFrontendInput(), $this->_ignoredAttributeTypes)
+               && !in_array($attribute->getAttributeCode(), $this->_ignoredAttributeCodes);
+    }
+
+    /**
+     * Return list of allowed attributes
+     *
+     * @param Mage_Eav_Model_Entity_Abstract $entity
+     * @param array $filter
+     * @return array
+     */
+    public function getAllowedAttributes($entity, array $filter = null)
+    {
+        $attributes = $entity->getResource()
+                        ->loadAllAttributes($entity)
+                        ->getAttributesByCode();
+        $result = array();
+        foreach ($attributes as $attribute) {
+            if ($this->_isAllowedAttribute($attribute, $filter)) {
+                $result[$attribute->getAttributeCode()] = $attribute;
+            }
+        }
+
+        return $result;
+    }
+} // Class Mage_Customer_Model_Api_Resource End
diff --git a/app/code/core/Mage/Customer/Model/Customer/Api.php b/app/code/core/Mage/Customer/Model/Customer/Api.php
new file mode 100644
index 00000000000..75469a0f3d3
--- /dev/null
+++ b/app/code/core/Mage/Customer/Model/Customer/Api.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.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Customer api
+ *
+ * @category   Mage
+ * @package    Mage_Customer
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Customer_Model_Customer_Api extends Mage_Customer_Model_Api_Resource
+{
+    protected $_mapAttributes = array(
+        'customer_id' => 'entity_id'
+    );
+    /**
+     * Prepare data to insert/update.
+     * Creating array for stdClass Object
+     *
+     * @param stdClass $data
+     * @return array
+     */
+    protected function _prepareData($data)
+    {
+       foreach ($this->_mapAttributes as $attributeAlias=>$attributeCode) {
+            if(isset($data[$attributeAlias]))
+            {
+                $data[$attributeCode] = $data[$attributeAlias];
+                unset($data[$attributeAlias]);
+            }
+        }
+        return $data;
+    }
+
+    /**
+     * Create new customer
+     *
+     * @param array $customerData
+     * @return int
+     */
+    public function create($customerData)
+    {
+        $customerData = $this->_prepareData($customerData);
+        try {
+            $customer = Mage::getModel('Mage_Customer_Model_Customer')
+                ->setData($customerData)
+                ->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+        return $customer->getId();
+    }
+
+    /**
+     * Retrieve customer data
+     *
+     * @param int $customerId
+     * @param array $attributes
+     * @return array
+     */
+    public function info($customerId, $attributes = null)
+    {
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')->load($customerId);
+
+        if (!$customer->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        if (!is_null($attributes) && !is_array($attributes)) {
+            $attributes = array($attributes);
+        }
+
+        $result = array();
+
+        foreach ($this->_mapAttributes as $attributeAlias=>$attributeCode) {
+            $result[$attributeAlias] = $customer->getData($attributeCode);
+        }
+
+        foreach ($this->getAllowedAttributes($customer, $attributes) as $attributeCode=>$attribute) {
+            $result[$attributeCode] = $customer->getData($attributeCode);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve customers data
+     *
+     * @param  object|array $filters
+     * @return array
+     */
+    public function items($filters)
+    {
+        $collection = Mage::getModel('Mage_Customer_Model_Customer')->getCollection()->addAttributeToSelect('*');
+        /** @var $apiHelper Mage_Api_Helper_Data */
+        $apiHelper = Mage::helper('Mage_Api_Helper_Data');
+        $filters = $apiHelper->parseFilters($filters, $this->_mapAttributes);
+        try {
+            foreach ($filters as $field => $value) {
+                $collection->addFieldToFilter($field, $value);
+            }
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('filters_invalid', $e->getMessage());
+        }
+        $result = array();
+        foreach ($collection as $customer) {
+            $data = $customer->toArray();
+            $row  = array();
+            foreach ($this->_mapAttributes as $attributeAlias => $attributeCode) {
+                $row[$attributeAlias] = (isset($data[$attributeCode]) ? $data[$attributeCode] : null);
+            }
+            foreach ($this->getAllowedAttributes($customer) as $attributeCode => $attribute) {
+                if (isset($data[$attributeCode])) {
+                    $row[$attributeCode] = $data[$attributeCode];
+                }
+            }
+            $result[] = $row;
+        }
+
+        return $result;
+    }
+
+    /**
+     * Update customer data
+     *
+     * @param int $customerId
+     * @param array $customerData
+     * @return boolean
+     */
+    public function update($customerId, $customerData)
+    {
+        $customerData = $this->_prepareData($customerData);
+
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')->load($customerId);
+
+        if (!$customer->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        foreach ($this->getAllowedAttributes($customer) as $attributeCode=>$attribute) {
+            if (isset($customerData[$attributeCode])) {
+                $customer->setData($attributeCode, $customerData[$attributeCode]);
+            }
+        }
+
+        $customer->save();
+        return true;
+    }
+
+    /**
+     * Delete customer
+     *
+     * @param int $customerId
+     * @return boolean
+     */
+    public function delete($customerId)
+    {
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')->load($customerId);
+
+        if (!$customer->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        try {
+            $customer->delete();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('not_deleted', $e->getMessage());
+        }
+
+        return true;
+    }
+
+} // Class Mage_Customer_Model_Customer_Api End
diff --git a/app/code/core/Mage/Customer/Model/Customer/Api/V2.php b/app/code/core/Mage/Customer/Model/Customer/Api/V2.php
new file mode 100644
index 00000000000..bf85c7f144e
--- /dev/null
+++ b/app/code/core/Mage/Customer/Model/Customer/Api/V2.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Customer api V2
+ *
+ * @category   Mage
+ * @package    Mage_Customer
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Customer_Model_Customer_Api_V2 extends Mage_Customer_Model_Customer_Api
+{
+    /**
+     * Prepare data to insert/update.
+     * Creating array for stdClass Object
+     *
+     * @param stdClass $data
+     * @return array
+     */
+    protected function _prepareData($data)
+    {
+        if (null !== ($_data = get_object_vars($data))) {
+            return parent::_prepareData($_data);
+        }
+        return array();
+    }
+}
diff --git a/app/code/core/Mage/Customer/Model/Group/Api.php b/app/code/core/Mage/Customer/Model/Group/Api.php
new file mode 100644
index 00000000000..a4ee0448257
--- /dev/null
+++ b/app/code/core/Mage/Customer/Model/Group/Api.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Customer groups api
+ *
+ * @category   Mage
+ * @package    Mage_Customer
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Customer_Model_Group_Api extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Retrieve groups
+     *
+     * @return array
+     */
+    public function items()
+    {
+        $collection = Mage::getModel('Mage_Customer_Model_Group')->getCollection();
+
+        $result = array();
+        foreach ($collection as $group) {
+            /* @var $group Mage_Customer_Model_Group */
+            $result[] = $group->toArray(array('customer_group_id', 'customer_group_code'));
+        }
+
+        return $result;
+    }
+}
diff --git a/app/code/core/Mage/Customer/Model/Group/Api/V2.php b/app/code/core/Mage/Customer/Model/Group/Api/V2.php
new file mode 100644
index 00000000000..13a3e260aef
--- /dev/null
+++ b/app/code/core/Mage/Customer/Model/Group/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Customer groups api V2
+ *
+ * @category   Mage
+ * @package    Mage_Customer
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Customer_Model_Group_Api_V2 extends Mage_Customer_Model_Group_Api
+{
+}
diff --git a/app/code/core/Mage/Customer/etc/api.xml b/app/code/core/Mage/Customer/etc/api.xml
new file mode 100644
index 00000000000..5a0522bfdc6
--- /dev/null
+++ b/app/code/core/Mage/Customer/etc/api.xml
@@ -0,0 +1,179 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Customer
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <customer translate="title" module="Mage_Customer">
+                <model>Mage_Customer_Model_Customer_Api</model>
+                <title>Customer API</title>
+                <acl>customer</acl>
+                <methods>
+                    <list translate="title" module="Mage_Customer">
+                        <title>Retrieve customers</title>
+                        <method>items</method>
+                        <acl>customer/info</acl>
+                    </list>
+                    <create translate="title" module="Mage_Customer">
+                        <title>Create customer</title>
+                        <acl>customer/create</acl>
+                    </create>
+                    <info translate="title" module="Mage_Customer">
+                        <title>Retrieve customer data</title>
+                        <acl>customer/info</acl>
+                    </info>
+                    <update translate="title" module="Mage_Customer">
+                        <title>Update customer data</title>
+                        <acl>customer/update</acl>
+                    </update>
+                    <delete translate="title" module="Mage_Customer">
+                        <title>Delete customer</title>
+                        <acl>customer/delete</acl>
+                    </delete>
+                </methods>
+                <faults module="Mage_Customer">
+                    <data_invalid>
+                        <code>100</code>
+                        <message>Provided customer data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <filters_invalid>
+                        <code>101</code>
+                        <message>Specified filters are invalid. Details are in error message.</message>
+                    </filters_invalid>
+                    <not_exists>
+                        <code>102</code>
+                        <message>Customer does not exist.</message>
+                    </not_exists>
+                    <not_deleted>
+                        <code>103</code>
+                        <message>Customer is not deleted. Details are in error message.</message>
+                    </not_deleted>
+                </faults>
+            </customer>
+            <customer_group>
+                <model>Mage_Customer_Model_Group_Api</model>
+                <title>Customer's Groups API</title>
+                <acl>customer</acl>
+                <methods>
+                    <list translate="title" module="Mage_Customer">
+                        <title>Retrieve customer groups</title>
+                        <method>items</method>
+                    </list>
+                </methods>
+            </customer_group>
+            <customer_address>
+                <model>Mage_Customer_Model_Address_Api</model>
+                <title>Customer Address API</title>
+                <acl>customer/address</acl>
+                <methods>
+                    <list translate="title" module="Mage_Customer">
+                        <title>Retrieve customer addresses</title>
+                        <method>items</method>
+                        <acl>customer/address/info</acl>
+                    </list>
+                    <create translate="title" module="Mage_Customer">
+                        <title>Create customer address</title>
+                        <acl>customer/address/create</acl>
+                    </create>
+                    <info translate="title" module="Mage_Customer">
+                        <title>Retrieve address data</title>
+                        <acl>customer/address/info</acl>
+                    </info>
+                    <update translate="title" module="Mage_Customer">
+                        <title>Update customer address data</title>
+                        <acl>customer/address/update</acl>
+                    </update>
+                    <delete translate="title" module="Mage_Customer">
+                        <title>Delete customer address</title>
+                        <acl>customer/address/delete</acl>
+                    </delete>
+                </methods>
+                <faults module="Mage_Customer">
+                    <data_invalid>
+                        <code>100</code>
+                        <message>Provided address data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <customer_not_exists>
+                        <code>101</code>
+                        <message>Customer does not exist.</message>
+                    </customer_not_exists>
+                    <not_exists>
+                        <code>102</code>
+                        <message>Address does not exist.</message>
+                    </not_exists>
+                    <not_deleted>
+                        <code>103</code>
+                        <message>Address is not deleted. Details are in error message.</message>
+                    </not_deleted>
+                </faults>
+            </customer_address>
+        </resources>
+        <v2>
+            <resources_function_prefix>
+                <customer>customerCustomer</customer>
+                <customer_group>customerGroup</customer_group>
+                <customer_address>customerAddress</customer_address>
+            </resources_function_prefix>
+        </v2>
+        <acl>
+            <resources>
+                <customer translate="title" module="Mage_Customer">
+                     <title>Customers</title>
+                     <sort_order>3</sort_order>
+                     <create translate="title" module="Mage_Customer">
+                        <title>Create</title>
+                     </create>
+                     <update translate="title" module="Mage_Customer">
+                        <title>Update</title>
+                     </update>
+                     <delete translate="title" module="Mage_Customer">
+                        <title>Delete</title>
+                     </delete>
+                     <info translate="title" module="Mage_Customer">
+                        <title>Retrieve customer info</title>
+                     </info>
+                     <address translate="title" module="Mage_Customer">
+                         <title>Addresses</title>
+                         <sort_order>100</sort_order>
+                         <create translate="title" module="Mage_Customer">
+                            <title>Create</title>
+                         </create>
+                         <update translate="title" module="Mage_Customer">
+                            <title>Update</title>
+                         </update>
+                         <delete translate="title" module="Mage_Customer">
+                            <title>Delete</title>
+                         </delete>
+                         <info translate="title" module="Mage_Customer">
+                            <title>Retrieve address info</title>
+                         </info>
+                     </address>
+                </customer>
+            </resources>
+        </acl>
+    </api>
+</config>
diff --git a/app/code/core/Mage/Customer/etc/wsdl.xml b/app/code/core/Mage/Customer/etc/wsdl.xml
new file mode 100644
index 00000000000..133b8876396
--- /dev/null
+++ b/app/code/core/Mage/Customer/etc/wsdl.xml
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
+    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
+            <complexType name="customerCustomerEntityToCreate">
+                <all>
+                    <element name="customer_id" type="xsd:int" minOccurs="0" />
+                    <element name="email" type="xsd:string" minOccurs="0" />
+                    <element name="firstname" type="xsd:string" minOccurs="0" />
+                    <element name="lastname" type="xsd:string" minOccurs="0" />
+                    <element name="password" type="xsd:string" minOccurs="0" />
+                    <element name="website_id" type="xsd:int" minOccurs="0" />
+                    <element name="store_id" type="xsd:int" minOccurs="0" />
+                    <element name="group_id" type="xsd:int" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="customerCustomerEntity">
+                <all>
+                    <element name="customer_id" type="xsd:int" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="store_id" type="xsd:int" minOccurs="0" />
+                    <element name="website_id" type="xsd:int" minOccurs="0" />
+                    <element name="created_in" type="xsd:string" minOccurs="0" />
+                    <element name="email" type="xsd:string" minOccurs="0" />
+                    <element name="firstname" type="xsd:string" minOccurs="0" />
+                    <element name="middlename" type="xsd:string" minOccurs="0" />
+                    <element name="lastname" type="xsd:string" minOccurs="0" />
+                    <element name="group_id" type="xsd:int" minOccurs="0" />
+                    <element name="prefix" type="xsd:string" minOccurs="0" />
+                    <element name="suffix" type="xsd:string" minOccurs="0" />
+                    <element name="dob" type="xsd:string" minOccurs="0" />
+                    <element name="taxvat" type="xsd:string" minOccurs="0" />
+                    <element name="confirmation" type="xsd:boolean" minOccurs="0" />
+                    <element name="password_hash" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="customerCustomerEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:customerCustomerEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="customerGroupEntity">
+                <all>
+                    <element name="customer_group_id" type="xsd:int" />
+                    <element name="customer_group_code" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="customerGroupEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:customerGroupEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="customerAddressEntityCreate">
+                <all>
+                    <element name="city" type="xsd:string" minOccurs="0" />
+                    <element name="company" type="xsd:string" minOccurs="0" />
+                    <element name="country_id" type="xsd:string" minOccurs="0" />
+                    <element name="fax" type="xsd:string" minOccurs="0" />
+                    <element name="firstname" type="xsd:string" minOccurs="0" />
+                    <element name="lastname" type="xsd:string" minOccurs="0" />
+                    <element name="middlename" type="xsd:string" minOccurs="0" />
+                    <element name="postcode" type="xsd:string" minOccurs="0" />
+                    <element name="prefix" type="xsd:string" minOccurs="0" />
+                    <element name="region_id" type="xsd:int" minOccurs="0" />
+                    <element name="region" type="xsd:string" minOccurs="0" />
+                    <element name="street" type="typens:ArrayOfString" minOccurs="0" />
+                    <element name="suffix" type="xsd:string" minOccurs="0" />
+                    <element name="telephone" type="xsd:string" minOccurs="0" />
+                    <element name="is_default_billing" type="xsd:boolean" minOccurs="0" />
+                    <element name="is_default_shipping" type="xsd:boolean" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="customerAddressEntityItem">
+                <all>
+                    <element name="customer_address_id" type="xsd:int" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="city" type="xsd:string" minOccurs="0" />
+                    <element name="company" type="xsd:string" minOccurs="0" />
+                    <element name="country_id" type="xsd:string" minOccurs="0" />
+                    <element name="fax" type="xsd:string" minOccurs="0" />
+                    <element name="firstname" type="xsd:string" minOccurs="0" />
+                    <element name="lastname" type="xsd:string" minOccurs="0" />
+                    <element name="middlename" type="xsd:string" minOccurs="0" />
+                    <element name="postcode" type="xsd:string" minOccurs="0" />
+                    <element name="prefix" type="xsd:string" minOccurs="0" />
+                    <element name="region" type="xsd:string" minOccurs="0" />
+                    <element name="region_id" type="xsd:int" minOccurs="0" />
+                    <element name="street" type="xsd:string" minOccurs="0" />
+                    <element name="suffix" type="xsd:string" minOccurs="0" />
+                    <element name="telephone" type="xsd:string" minOccurs="0" />
+                    <element name="is_default_billing" type="xsd:boolean" minOccurs="0" />
+                    <element name="is_default_shipping" type="xsd:boolean" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="customerAddressEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:customerAddressEntityItem[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+        </schema>
+    </types>
+    <message name="customerCustomerListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="filters" type="typens:filters" />
+    </message>
+    <message name="customerCustomerListResponse">
+        <part name="storeView" type="typens:customerCustomerEntityArray" />
+    </message>
+    <message name="customerCustomerCreateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="customerData" type="typens:customerCustomerEntityToCreate" />
+    </message>
+    <message name="customerCustomerCreateResponse">
+        <part name="result" type="xsd:int" />
+    </message>
+    <message name="customerCustomerInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="customerId" type="xsd:int" />
+        <part name="attributes" type="typens:ArrayOfString" />
+    </message>
+    <message name="customerCustomerInfoResponse">
+        <part name="customerInfo" type="typens:customerCustomerEntity" />
+    </message>
+    <message name="customerCustomerUpdateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="customerId" type="xsd:int" />
+        <part name="customerData" type="typens:customerCustomerEntityToCreate" />
+    </message>
+    <message name="customerCustomerUpdateResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="customerCustomerDeleteRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="customerId" type="xsd:int" />
+    </message>
+    <message name="customerCustomerDeleteResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="customerGroupListRequest">
+        <part name="sessionId" type="xsd:string" />
+    </message>
+    <message name="customerGroupListResponse">
+        <part name="result" type="typens:customerGroupEntityArray" />
+    </message>
+    <message name="customerAddressListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="customerId" type="xsd:int" />
+    </message>
+    <message name="customerAddressListResponse">
+        <part name="result" type="typens:customerAddressEntityArray" />
+    </message>
+    <message name="customerAddressCreateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="customerId" type="xsd:int" />
+        <part name="addressData" type="typens:customerAddressEntityCreate" />
+    </message>
+    <message name="customerAddressCreateResponse">
+        <part name="result" type="xsd:int" />
+    </message>
+    <message name="customerAddressInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="addressId" type="xsd:int" />
+    </message>
+    <message name="customerAddressInfoResponse">
+        <part name="info" type="typens:customerAddressEntityItem" />
+    </message>
+    <message name="customerAddressUpdateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="addressId" type="xsd:int" />
+        <part name="addressData" type="typens:customerAddressEntityCreate" />
+    </message>
+    <message name="customerAddressUpdateResponse">
+        <part name="info" type="xsd:boolean" />
+    </message>
+    <message name="customerAddressDeleteRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="addressId" type="xsd:int" />
+    </message>
+    <message name="customerAddressDeleteResponse">
+        <part name="info" type="xsd:boolean" />
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="customerCustomerList">
+            <documentation>Retrieve customers</documentation>
+            <input message="typens:customerCustomerListRequest" />
+            <output message="typens:customerCustomerListResponse" />
+        </operation>
+        <operation name="customerCustomerCreate">
+            <documentation>Create customer</documentation>
+            <input message="typens:customerCustomerCreateRequest" />
+            <output message="typens:customerCustomerCreateResponse" />
+        </operation>
+        <operation name="customerCustomerInfo">
+            <documentation>Retrieve customer data</documentation>
+            <input message="typens:customerCustomerInfoRequest" />
+            <output message="typens:customerCustomerInfoResponse" />
+        </operation>
+        <operation name="customerCustomerUpdate">
+            <documentation>Update customer data</documentation>
+            <input message="typens:customerCustomerUpdateRequest" />
+            <output message="typens:customerCustomerUpdateResponse" />
+        </operation>
+        <operation name="customerCustomerDelete">
+            <documentation>Delete customer</documentation>
+            <input message="typens:customerCustomerDeleteRequest" />
+            <output message="typens:customerCustomerDeleteResponse" />
+        </operation>
+        <operation name="customerGroupList">
+            <documentation>Retrieve customer groups</documentation>
+            <input message="typens:customerGroupListRequest" />
+            <output message="typens:customerGroupListResponse" />
+        </operation>
+        <operation name="customerAddressList">
+            <documentation>Retrieve customer addresses</documentation>
+            <input message="typens:customerAddressListRequest" />
+            <output message="typens:customerAddressListResponse" />
+        </operation>
+        <operation name="customerAddressCreate">
+            <documentation>Create customer address</documentation>
+            <input message="typens:customerAddressCreateRequest" />
+            <output message="typens:customerAddressCreateResponse" />
+        </operation>
+        <operation name="customerAddressInfo">
+            <documentation>Retrieve customer address data</documentation>
+            <input message="typens:customerAddressInfoRequest" />
+            <output message="typens:customerAddressInfoResponse" />
+        </operation>
+        <operation name="customerAddressUpdate">
+            <documentation>Update customer address data</documentation>
+            <input message="typens:customerAddressUpdateRequest" />
+            <output message="typens:customerAddressUpdateResponse" />
+        </operation>
+        <operation name="customerAddressDelete">
+            <documentation>Delete customer address</documentation>
+            <input message="typens:customerAddressDeleteRequest" />
+            <output message="typens:customerAddressDeleteResponse" />
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="customerCustomerList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerCustomerCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerCustomerInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerCustomerUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerCustomerDelete">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerGroupList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerAddressList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerAddressCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerAddressInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerAddressUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="customerAddressDelete">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+</definitions>
diff --git a/app/code/core/Mage/Customer/etc/wsi.xml b/app/code/core/Mage/Customer/etc/wsi.xml
new file mode 100644
index 00000000000..abef413cafc
--- /dev/null
+++ b/app/code/core/Mage/Customer/etc/wsi.xml
@@ -0,0 +1,507 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="customerCustomerEntityToCreate">
+                <xsd:sequence>
+                    <xsd:element name="customer_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="email" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="password" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="website_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="store_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="group_id" type="xsd:int" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="customerCustomerEntity">
+                <xsd:sequence>
+                    <xsd:element name="customer_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="website_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="created_in" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="email" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="middlename" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="group_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="prefix" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="suffix" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="dob" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="taxvat" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="confirmation" type="xsd:boolean" minOccurs="0" />
+                    <xsd:element name="password_hash" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="customerCustomerEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:customerCustomerEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="customerGroupEntity">
+                <xsd:sequence>
+                    <xsd:element name="customer_group_id" type="xsd:int" />
+                    <xsd:element name="customer_group_code" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="customerGroupEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:customerGroupEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="customerAddressEntityCreate">
+                <xsd:sequence>
+                    <xsd:element name="city" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="company" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="country_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="fax" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="middlename" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="postcode" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="prefix" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="region_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="region" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="street" type="typens:ArrayOfString" minOccurs="0" />
+                    <xsd:element name="suffix" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="telephone" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_default_billing" type="xsd:boolean" minOccurs="0" />
+                    <xsd:element name="is_default_shipping" type="xsd:boolean" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="customerAddressEntityItem">
+                <xsd:sequence>
+                    <xsd:element name="customer_address_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="city" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="company" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="country_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="fax" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="middlename" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="postcode" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="prefix" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="region" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="region_id" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="street" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="suffix" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="telephone" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_default_billing" type="xsd:boolean" minOccurs="0" />
+                    <xsd:element name="is_default_shipping" type="xsd:boolean" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="customerAddressEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:customerAddressEntityItem" />
+                </xsd:sequence>
+            </xsd:complexType>
+
+
+            <xsd:element name="customerCustomerListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="filters" type="typens:filters" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:customerCustomerEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerData" type="typens:customerCustomerEntityToCreate" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerId" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="attributes" type="typens:ArrayOfString" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:customerCustomerEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerData" type="typens:customerCustomerEntityToCreate" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerDeleteRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerId" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerCustomerDeleteResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerGroupListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerGroupListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:customerGroupEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerId" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:customerAddressEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="customerId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="addressData" type="typens:customerAddressEntityCreate" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="addressId" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:customerAddressEntityItem" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="addressId" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="addressData" type="typens:customerAddressEntityCreate" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressDeleteRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="addressId" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="customerAddressDeleteResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="customerCustomerListRequest">
+        <wsdl:part name="parameters" element="typens:customerCustomerListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerListResponse">
+        <wsdl:part name="parameters" element="typens:customerCustomerListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerCreateRequest">
+        <wsdl:part name="parameters" element="typens:customerCustomerCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerCreateResponse">
+        <wsdl:part name="parameters" element="typens:customerCustomerCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerInfoRequest">
+        <wsdl:part name="parameters" element="typens:customerCustomerInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerInfoResponse">
+        <wsdl:part name="parameters" element="typens:customerCustomerInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerUpdateRequest">
+        <wsdl:part name="parameters" element="typens:customerCustomerUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerUpdateResponse">
+        <wsdl:part name="parameters" element="typens:customerCustomerUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerDeleteRequest">
+        <wsdl:part name="parameters" element="typens:customerCustomerDeleteRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerCustomerDeleteResponse">
+        <wsdl:part name="parameters" element="typens:customerCustomerDeleteResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerGroupListRequest">
+        <wsdl:part name="parameters" element="typens:customerGroupListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerGroupListResponse">
+        <wsdl:part name="parameters" element="typens:customerGroupListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressListRequest">
+        <wsdl:part name="parameters" element="typens:customerAddressListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressListResponse">
+        <wsdl:part name="parameters" element="typens:customerAddressListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressCreateRequest">
+        <wsdl:part name="parameters" element="typens:customerAddressCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressCreateResponse">
+        <wsdl:part name="parameters" element="typens:customerAddressCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressInfoRequest">
+        <wsdl:part name="parameters" element="typens:customerAddressInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressInfoResponse">
+        <wsdl:part name="parameters" element="typens:customerAddressInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressUpdateRequest">
+        <wsdl:part name="parameters" element="typens:customerAddressUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressUpdateResponse">
+        <wsdl:part name="parameters" element="typens:customerAddressUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressDeleteRequest">
+        <wsdl:part name="parameters" element="typens:customerAddressDeleteRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="customerAddressDeleteResponse">
+        <wsdl:part name="parameters" element="typens:customerAddressDeleteResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="customerCustomerList">
+            <wsdl:documentation>Retrieve customers</wsdl:documentation>
+            <wsdl:input message="typens:customerCustomerListRequest" />
+            <wsdl:output message="typens:customerCustomerListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerCustomerCreate">
+            <wsdl:documentation>Create customer</wsdl:documentation>
+            <wsdl:input message="typens:customerCustomerCreateRequest" />
+            <wsdl:output message="typens:customerCustomerCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerCustomerInfo">
+            <wsdl:documentation>Retrieve customer data</wsdl:documentation>
+            <wsdl:input message="typens:customerCustomerInfoRequest" />
+            <wsdl:output message="typens:customerCustomerInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerCustomerUpdate">
+            <wsdl:documentation>Update customer data</wsdl:documentation>
+            <wsdl:input message="typens:customerCustomerUpdateRequest" />
+            <wsdl:output message="typens:customerCustomerUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerCustomerDelete">
+            <wsdl:documentation>Delete customer</wsdl:documentation>
+            <wsdl:input message="typens:customerCustomerDeleteRequest" />
+            <wsdl:output message="typens:customerCustomerDeleteResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerGroupList">
+            <wsdl:documentation>Retrieve customer groups</wsdl:documentation>
+            <wsdl:input message="typens:customerGroupListRequest" />
+            <wsdl:output message="typens:customerGroupListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressList">
+            <wsdl:documentation>Retrieve customer addresses</wsdl:documentation>
+            <wsdl:input message="typens:customerAddressListRequest" />
+            <wsdl:output message="typens:customerAddressListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressCreate">
+            <wsdl:documentation>Create customer address</wsdl:documentation>
+            <wsdl:input message="typens:customerAddressCreateRequest" />
+            <wsdl:output message="typens:customerAddressCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressInfo">
+            <wsdl:documentation>Retrieve customer address data</wsdl:documentation>
+            <wsdl:input message="typens:customerAddressInfoRequest" />
+            <wsdl:output message="typens:customerAddressInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressUpdate">
+            <wsdl:documentation>Update customer address data</wsdl:documentation>
+            <wsdl:input message="typens:customerAddressUpdateRequest" />
+            <wsdl:output message="typens:customerAddressUpdateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressDelete">
+            <wsdl:documentation>Delete customer address</wsdl:documentation>
+            <wsdl:input message="typens:customerAddressDeleteRequest" />
+            <wsdl:output message="typens:customerAddressDeleteResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="customerCustomerList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerCustomerCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerCustomerInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerCustomerUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerCustomerDelete">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerGroupList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="customerAddressDelete">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/DesignEditor/Block/Adminhtml/Editor/Toolbar/HandlesHierarchy.php b/app/code/core/Mage/DesignEditor/Block/Adminhtml/Editor/Toolbar/HandlesHierarchy.php
index 6bc9731cdb0..13a588e6677 100644
--- a/app/code/core/Mage/DesignEditor/Block/Adminhtml/Editor/Toolbar/HandlesHierarchy.php
+++ b/app/code/core/Mage/DesignEditor/Block/Adminhtml/Editor/Toolbar/HandlesHierarchy.php
@@ -61,6 +61,8 @@ class Mage_DesignEditor_Block_Adminhtml_Editor_Toolbar_HandlesHierarchy
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_DesignEditor_Model_Url_Handle $vdeUrlBuilder
      * @param array $data
@@ -79,6 +81,8 @@ class Mage_DesignEditor_Block_Adminhtml_Editor_Toolbar_HandlesHierarchy
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_DesignEditor_Model_Url_Handle $vdeUrlBuilder,
         array $data = array()
@@ -86,7 +90,8 @@ class Mage_DesignEditor_Block_Adminhtml_Editor_Toolbar_HandlesHierarchy
         $this->_vdeUrlBuilder = $vdeUrlBuilder;
 
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
+        );
     }
 
     /**
diff --git a/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/List/Abstract.php b/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/List/Abstract.php
index 3d50b570c6f..a5ff2933c1b 100644
--- a/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/List/Abstract.php
+++ b/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/List/Abstract.php
@@ -28,12 +28,12 @@
  * Abstract theme list
  *
  * @method Mage_Core_Model_Resource_Theme_Collection getCollection()
- * @method Mage_Backend_Block_Abstract setCollection(Mage_Core_Model_Resource_Theme_Collection $collection)
+ * @method Mage_Core_Block_Template setCollection(Mage_Core_Model_Resource_Theme_Collection $collection)
  *
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 abstract class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_List_Abstract
-    extends Mage_Backend_Block_Abstract
+    extends Mage_Core_Block_Template
 {
     /**
      * Application model
@@ -54,6 +54,8 @@ abstract class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_List_Abstract
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_App $app
      * @param array $data
@@ -72,13 +74,15 @@ abstract class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_List_Abstract
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_App $app,
         array $data = array()
     ) {
         $this->_app = $app;
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
     }
 
diff --git a/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/List/Available.php b/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/List/Available.php
index aba1c01d1d6..26bead77691 100644
--- a/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/List/Available.php
+++ b/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/List/Available.php
@@ -52,6 +52,8 @@ class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_List_Available
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_App $app
      * @param Mage_Core_Model_Theme_Service $serviceModel
@@ -71,6 +73,8 @@ class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_List_Available
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_App $app,
         Mage_Core_Model_Theme_Service $serviceModel,
@@ -79,7 +83,7 @@ class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_List_Available
         $this->_serviceModel = $serviceModel;
 
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $app, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $app, $data
         );
     }
 
diff --git a/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/StoreView.php b/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/StoreView.php
index a7de4a69673..0aa20e7f09e 100644
--- a/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/StoreView.php
+++ b/app/code/core/Mage/DesignEditor/Block/Adminhtml/Theme/Selector/StoreView.php
@@ -55,6 +55,8 @@ class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_StoreView extends Mage_Ba
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_Resource_Website_Collection $websiteCollection
      * @param Mage_Core_Model_Theme_Service $serviceModel
@@ -74,6 +76,8 @@ class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_StoreView extends Mage_Ba
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_Resource_Website_Collection $websiteCollection,
         Mage_Core_Model_Theme_Service $serviceModel,
@@ -83,7 +87,8 @@ class Mage_DesignEditor_Block_Adminhtml_Theme_Selector_StoreView extends Mage_Ba
         $this->_serviceModel = $serviceModel;
 
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
+        );
     }
 
     /**
diff --git a/app/code/core/Mage/DesignEditor/Controller/Varien/Router/Standard.php b/app/code/core/Mage/DesignEditor/Controller/Varien/Router/Standard.php
index af2bacc37bb..f402c76a074 100644
--- a/app/code/core/Mage/DesignEditor/Controller/Varien/Router/Standard.php
+++ b/app/code/core/Mage/DesignEditor/Controller/Varien/Router/Standard.php
@@ -27,14 +27,9 @@
 class Mage_DesignEditor_Controller_Varien_Router_Standard extends Mage_Core_Controller_Varien_Router_Base
 {
     /**
-     * @var Mage_Backend_Model_Auth_Session
+     * @var Magento_ObjectManager
      */
-    protected $_backendSession;
-
-    /**
-     * @var Mage_DesignEditor_Helper_Data
-     */
-    protected $_helper;
+    protected $_objectManager;
 
     /**
      * Routers that must not been matched
@@ -43,48 +38,25 @@ class Mage_DesignEditor_Controller_Varien_Router_Standard extends Mage_Core_Cont
      */
     protected $_excludedRouters = array('admin', 'vde');
 
-    /**
-     * Layout factory
-     *
-     * @var Mage_DesignEditor_Model_State
-     */
-    protected $_editorState;
-
-    /**
-     * Configuration model
-     *
-     * @var Mage_Core_Model_Config
-     */
-    protected $_configuration;
-
     /**
      * @param Mage_Core_Controller_Varien_Action_Factory $controllerFactory
+     * @param Magento_ObjectManager $objectManager
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_App $app
      * @param string $areaCode
      * @param string $baseController
-     * @param Mage_Backend_Model_Auth_Session $backendSession
-     * @param Mage_DesignEditor_Helper_Data $helper
-     * @param Mage_DesignEditor_Model_State $editorState
-     * @param Mage_Core_Model_Config $configuration
+     * @throws InvalidArgumentException
      */
     public function __construct(
         Mage_Core_Controller_Varien_Action_Factory $controllerFactory,
+        Magento_ObjectManager $objectManager,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_App $app,
         $areaCode,
-        $baseController,
-        Mage_Backend_Model_Auth_Session $backendSession,
-        Mage_DesignEditor_Helper_Data $helper,
-        Mage_DesignEditor_Model_State $editorState,
-        Mage_Core_Model_Config $configuration
+        $baseController
     ) {
         parent::__construct($controllerFactory, $filesystem, $app, $areaCode, $baseController);
-
-        $this->_backendSession = $backendSession;
-        $this->_helper         = $helper;
-        $this->_editorState    = $editorState;
-        $this->_configuration  = $configuration;
+        $this->_objectManager = $objectManager;
     }
 
     /**
@@ -101,7 +73,7 @@ class Mage_DesignEditor_Controller_Varien_Router_Standard extends Mage_Core_Cont
         }
 
         // user must be logged in admin area
-        if (!$this->_backendSession->isLoggedIn()) {
+        if (!$this->_objectManager->get('Mage_Backend_Model_Auth_Session')->isLoggedIn()) {
             return null;
         }
 
@@ -122,7 +94,8 @@ class Mage_DesignEditor_Controller_Varien_Router_Standard extends Mage_Core_Cont
             /** @var $controller Mage_Core_Controller_Varien_ActionAbstract */
             $controller = $router->match($request);
             if ($controller) {
-                $this->_editorState->update($this->_areaCode, $request, $controller);
+                $this->_objectManager->get('Mage_DesignEditor_Model_State')
+                    ->update($this->_areaCode, $request, $controller);
                 break;
             }
         }
@@ -139,7 +112,7 @@ class Mage_DesignEditor_Controller_Varien_Router_Standard extends Mage_Core_Cont
     protected function _isVdeRequest(Mage_Core_Controller_Request_Http $request)
     {
         $url = trim($request->getOriginalPathInfo(), '/');
-        $vdeFrontName = $this->_helper->getFrontName();
+        $vdeFrontName = $this->_objectManager->get('Mage_DesignEditor_Helper_Data')->getFrontName();
         return $url == $vdeFrontName || strpos($url, $vdeFrontName . '/') === 0;
     }
 
@@ -151,7 +124,7 @@ class Mage_DesignEditor_Controller_Varien_Router_Standard extends Mage_Core_Cont
      */
     protected function _prepareVdeRequest(Mage_Core_Controller_Request_Http $request)
     {
-        $vdeFrontName = $this->_helper->getFrontName();
+        $vdeFrontName = $this->_objectManager->get('Mage_DesignEditor_Helper_Data')->getFrontName();
         $noVdePath = substr($request->getPathInfo(), strlen($vdeFrontName) + 1) ?: '/';
         $request->setPathInfo($noVdePath);
         return $this;
@@ -178,9 +151,10 @@ class Mage_DesignEditor_Controller_Varien_Router_Standard extends Mage_Core_Cont
      */
     protected function _overrideConfiguration()
     {
-        $vdeNode = $this->_configuration->getNode(Mage_DesignEditor_Model_Area::AREA_VDE);
+        $vdeNode = $this->_objectManager->get('Mage_Core_Model_Config')
+            ->getNode(Mage_DesignEditor_Model_Area::AREA_VDE);
         if ($vdeNode) {
-            $this->_configuration->getNode(Mage_Core_Model_App_Area::AREA_FRONTEND)
+            $this->_objectManager->get('Mage_Core_Model_Config')->getNode(Mage_Core_Model_App_Area::AREA_FRONTEND)
                 ->extend($vdeNode, true);
         }
     }
diff --git a/app/code/core/Mage/DesignEditor/Model/State.php b/app/code/core/Mage/DesignEditor/Model/State.php
index 1a5807cfc3d..e8e43fbaf45 100644
--- a/app/code/core/Mage/DesignEditor/Model/State.php
+++ b/app/code/core/Mage/DesignEditor/Model/State.php
@@ -235,8 +235,7 @@ class Mage_DesignEditor_Model_State
     {
         $themeId = $this->_backendSession->getData('theme_id');
         if ($themeId !== null) {
-            $path = $this->_designPackage->getConfigPathByArea(Mage_Core_Model_App_Area::AREA_FRONTEND);
-            $this->_application->getStore()->setConfig($path, $themeId);
+            $this->_application->getStore()->setConfig(Mage_Core_Model_Design_Package::XML_PATH_THEME_ID, $themeId);
         }
     }
 
diff --git a/app/code/core/Mage/Directory/Model/Country/Api.php b/app/code/core/Mage/Directory/Model/Country/Api.php
new file mode 100644
index 00000000000..6c8181f7f39
--- /dev/null
+++ b/app/code/core/Mage/Directory/Model/Country/Api.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Directory
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Directory Country Api
+ *
+ * @category   Mage
+ * @package    Mage_Directory
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Directory_Model_Country_Api extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Retrieve countries list
+     *
+     * @return array
+     */
+    public function items()
+    {
+        $collection = Mage::getModel('Mage_Directory_Model_Country')->getCollection();
+
+        $result = array();
+        foreach ($collection as $country) {
+            /* @var $country Mage_Directory_Model_Country */
+            $country->getName(); // Loading name in default locale
+            $result[] = $country->toArray(array('country_id', 'iso2_code', 'iso3_code', 'name'));
+        }
+
+        return $result;
+    }
+} // Class Mage_Directory_Model_Country_Api End
diff --git a/app/code/core/Mage/Directory/Model/Country/Api/V2.php b/app/code/core/Mage/Directory/Model/Country/Api/V2.php
new file mode 100644
index 00000000000..fa4330adadf
--- /dev/null
+++ b/app/code/core/Mage/Directory/Model/Country/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Directory
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Directory Country Api V2
+ *
+ * @category   Mage
+ * @package    Mage_Directory
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Directory_Model_Country_Api_V2 extends Mage_Directory_Model_Country_Api
+{
+}
diff --git a/app/code/core/Mage/Directory/Model/Region/Api.php b/app/code/core/Mage/Directory/Model/Region/Api.php
new file mode 100644
index 00000000000..9a27b552081
--- /dev/null
+++ b/app/code/core/Mage/Directory/Model/Region/Api.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Directory
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Directory Region Api
+ *
+ * @category   Mage
+ * @package    Mage_Directory
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Directory_Model_Region_Api extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Retrieve regions list
+     *
+     * @param string $country
+     * @return array
+     */
+    public function items($country)
+    {
+        try {
+            $country = Mage::getModel('Mage_Directory_Model_Country')->loadByCode($country);
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('country_not_exists', $e->getMessage());
+        }
+
+        if (!$country->getId()) {
+            $this->_fault('country_not_exists');
+        }
+
+        $result = array();
+        foreach ($country->getRegions() as $region) {
+            $region->getName();
+            $result[] = $region->toArray(array('region_id', 'code', 'name'));
+        }
+
+        return $result;
+    }
+} // Class Mage_Directory_Model_Region_Api End
diff --git a/app/code/core/Mage/Directory/Model/Region/Api/V2.php b/app/code/core/Mage/Directory/Model/Region/Api/V2.php
new file mode 100644
index 00000000000..21cb7e3750b
--- /dev/null
+++ b/app/code/core/Mage/Directory/Model/Region/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Directory
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Directory Region Api V2
+ *
+ * @category   Mage
+ * @package    Mage_Directory
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Directory_Model_Region_Api_V2 extends Mage_Directory_Model_Region_Api
+{
+}
diff --git a/app/code/core/Mage/Directory/etc/api.xml b/app/code/core/Mage/Directory/etc/api.xml
new file mode 100644
index 00000000000..a51475857cb
--- /dev/null
+++ b/app/code/core/Mage/Directory/etc/api.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Directory
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <directory_country translate="title" module="Mage_Directory">
+                <model>Mage_Directory_Model_Country_Api</model>
+                <title>Country API</title>
+                <acl>directory/country</acl>
+                <methods>
+                    <list translate="title" module="Mage_Directory">
+                        <title>List of countries</title>
+                        <method>items</method>
+                    </list>
+                </methods>
+            </directory_country>
+            <directory_region translate="title" module="Mage_Directory">
+                <model>Mage_Directory_Model_Region_Api</model>
+                <title>Region API</title>
+                <acl>directory/region</acl>
+                <methods>
+                    <list translate="title" module="Mage_Directory">
+                        <title>List of regions in specified country</title>
+                        <method>items</method>
+                    </list>
+                </methods>
+                <faults module="Mage_Directory">
+                    <country_not_exists>
+                        <code>101</code>
+                        <message>Country does not exist.</message>
+                    </country_not_exists>
+                </faults>
+            </directory_region>
+        </resources>
+        <resources_alias>
+            <country>directory_country</country>
+            <region>directory_region</region>
+        </resources_alias>
+        <v2>
+            <resources_function_prefix>
+                <country>directoryCountry</country>
+                <region>directoryRegion</region>
+            </resources_function_prefix>
+        </v2>
+        <acl>
+            <resources>
+                <directory translate="title" module="Mage_Directory">
+                    <title>Directory</title>
+                    <sort_order>5</sort_order>
+                    <country translate="title" module="Mage_Directory">
+                        <title>Country</title>
+                    </country>
+                    <region translate="title" module="Mage_Directory">
+                        <title>Region</title>
+                    </region>
+                </directory>
+            </resources>
+        </acl>
+    </api>
+</config>
diff --git a/app/code/core/Mage/Directory/etc/wsdl.xml b/app/code/core/Mage/Directory/etc/wsdl.xml
new file mode 100644
index 00000000000..5ace2242939
--- /dev/null
+++ b/app/code/core/Mage/Directory/etc/wsdl.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
+    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
+            <complexType name="directoryCountryEntity">
+                <all>
+                    <element name="country_id" type="xsd:string" />
+                    <element name="iso2_code" type="xsd:string" />
+                    <element name="iso3_code" type="xsd:string" />
+                    <element name="name" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="directoryCountryEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:directoryCountryEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="directoryRegionEntity">
+                <all>
+                    <element name="region_id" type="xsd:string" />
+                    <element name="code" type="xsd:string" />
+                    <element name="name" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="directoryRegionEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:directoryRegionEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+        </schema>
+    </types>
+    <message name="directoryCountryListRequest">
+        <part name="sessionId" type="xsd:string" />
+    </message>
+    <message name="directoryCountryListResponse">
+        <part name="countries" type="typens:directoryCountryEntityArray" />
+    </message>
+    <message name="directoryRegionListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="country" type="xsd:string" />
+    </message>
+    <message name="directoryRegionListResponse">
+        <part name="countries" type="typens:directoryRegionEntityArray" />
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="directoryCountryList">
+            <documentation>List of countries</documentation>
+            <input message="typens:directoryCountryListRequest" />
+            <output message="typens:directoryCountryListResponse" />
+        </operation>
+        <operation name="directoryRegionList">
+            <documentation>List of regions in specified country</documentation>
+            <input message="typens:directoryRegionListRequest" />
+            <output message="typens:directoryRegionListResponse" />
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="directoryCountryList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="directoryRegionList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/Directory/etc/wsi.xml b/app/code/core/Mage/Directory/etc/wsi.xml
new file mode 100644
index 00000000000..eca62b5d0cb
--- /dev/null
+++ b/app/code/core/Mage/Directory/etc/wsi.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="directoryCountryEntity">
+                <xsd:sequence>
+                    <xsd:element name="country_id" type="xsd:string" />
+                    <xsd:element name="iso2_code" type="xsd:string" />
+                    <xsd:element name="iso3_code" type="xsd:string" />
+                    <xsd:element name="name" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="directoryCountryEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:directoryCountryEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="directoryRegionEntity">
+                <xsd:sequence>
+                    <xsd:element name="region_id" type="xsd:string" />
+                    <xsd:element name="code" type="xsd:string" />
+                    <xsd:element name="name" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="directoryRegionEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:directoryRegionEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+
+
+            <xsd:element name="directoryCountryListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="directoryCountryListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:directoryCountryEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="directoryRegionListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="country" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="directoryRegionListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:directoryRegionEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="directoryCountryListRequest">
+        <wsdl:part name="parameters" element="typens:directoryCountryListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="directoryCountryListResponse">
+        <wsdl:part name="parameters" element="typens:directoryCountryListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="directoryRegionListRequest">
+        <wsdl:part name="parameters" element="typens:directoryRegionListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="directoryRegionListResponse">
+        <wsdl:part name="parameters" element="typens:directoryRegionListResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="directoryCountryList">
+            <wsdl:documentation>List of countries</wsdl:documentation>
+            <wsdl:input message="typens:directoryCountryListRequest" />
+            <wsdl:output message="typens:directoryCountryListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="directoryRegionList">
+            <wsdl:documentation>List of regions in specified country</wsdl:documentation>
+            <wsdl:input message="typens:directoryRegionListRequest" />
+            <wsdl:output message="typens:directoryRegionListResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="directoryCountryList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="directoryRegionList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="{{var wsdl.name}}Service">
+        <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php
index 2b69a9385e4..d9ebf8ef190 100644
--- a/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php
+++ b/app/code/core/Mage/Downloadable/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php
@@ -96,7 +96,7 @@ class Mage_Downloadable_Block_Adminhtml_Catalog_Product_Edit_Tab_Downloadable_Li
      */
     public function getPurchasedSeparatelySelect()
     {
-        $select = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+        $select = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setName('product[links_purchased_separately]')
             ->setId('downloadable_link_purchase_type')
             ->setOptions(Mage::getSingleton('Mage_Backend_Model_Config_Source_Yesno')->toOptionArray())
diff --git a/app/code/core/Mage/Downloadable/Model/Link/Api.php b/app/code/core/Mage/Downloadable/Model/Link/Api.php
new file mode 100644
index 00000000000..69d713b961e
--- /dev/null
+++ b/app/code/core/Mage/Downloadable/Model/Link/Api.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.
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Downloadable links API model
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Downloadable_Model_Link_Api extends Mage_Catalog_Model_Api_Resource
+{
+    /**
+     * Return validator instance
+     *
+     * @return Mage_Downloadable_Model_Link_Api_Validator
+     */
+    protected function _getValidator()
+    {
+        return Mage::getSingleton('Mage_Downloadable_Model_Link_Api_Validator');
+    }
+
+    /**
+     * Decode file from base64 and upload it to donwloadable 'tmp' folder
+     *
+     * @param array $fileInfo
+     * @param string $type
+     * @return string
+     */
+    protected function _uploadFile($fileInfo, $type)
+    {
+        $tmpPath = '';
+        if ($type == 'sample') {
+            $tmpPath = Mage_Downloadable_Model_Sample::getBaseTmpPath();
+        } elseif ($type == 'link') {
+            $tmpPath = Mage_Downloadable_Model_Link::getBaseTmpPath();
+        } elseif ($type == 'link_samples') {
+            $tmpPath = Mage_Downloadable_Model_Link::getBaseSampleTmpPath();
+        }
+
+        $result = array();
+        try {
+            $uploader = Mage::getModel('Mage_Downloadable_Model_Link_Api_Uploader', array('file' => $fileInfo));
+            $uploader->setAllowRenameFiles(true);
+            $uploader->setFilesDispersion(true);
+            $result = $uploader->save($tmpPath);
+
+            if (isset($result['file'])) {
+                $fullPath = rtrim($tmpPath, DS) . DS . ltrim($result['file'], DS);
+                Mage::helper('Mage_Core_Helper_File_Storage_Database')->saveFile($fullPath);
+            }
+        } catch (Exception $e) {
+            if ($e->getMessage() != '') {
+                $this->_fault('upload_failed', $e->getMessage());
+            } else {
+                $this->_fault($e->getCode());
+            }
+        }
+
+        $result['status'] = 'new';
+        $result['name'] = substr($result['file'], strrpos($result['file'], '/')+1);
+        return Mage::helper('Mage_Core_Helper_Data')->jsonEncode(array($result));
+    }
+
+    /**
+     * Add downloadable content to product
+     *
+     * @param int|string $productId
+     * @param array $resource
+     * @param string $resourceType
+     * @param string|int|null $store
+     * @param string|null $identifierType ('sku'|'id')
+     * @return boolean
+     */
+    public function add($productId, $resource, $resourceType, $store = null, $identifierType = null)
+    {
+        try {
+            $this->_getValidator()->validateType($resourceType);
+            $this->_getValidator()->validateAttributes($resource, $resourceType);
+        } catch (Exception $e) {
+            $this->_fault('validation_error', $e->getMessage());
+        }
+
+        $resource['is_delete'] = 0;
+        if ($resourceType == 'link') {
+            $resource['link_id'] = 0;
+        } elseif ($resourceType == 'sample') {
+            $resource['sample_id'] = 0;
+        }
+
+        if ($resource['type'] == 'file') {
+            if (isset($resource['file'])) {
+                $resource['file'] = $this->_uploadFile($resource['file'], $resourceType);
+            }
+            unset($resource[$resourceType.'_url']);
+        } elseif ($resource['type'] == 'url') {
+            unset($resource['file']);
+        }
+
+        if ($resourceType == 'link' && $resource['sample']['type'] == 'file') {
+            if (isset($resource['sample']['file'])) {
+                $resource['sample']['file'] = $this->_uploadFile($resource['sample']['file'], 'link_samples');
+            }
+            unset($resource['sample']['url']);
+        } elseif ($resourceType == 'link' && $resource['sample']['type'] == 'url') {
+            $resource['sample']['file'] = null;
+        }
+
+        $product = $this->_getProduct($productId, $store, $identifierType);
+        try {
+            $downloadable = array($resourceType => array($resource));
+            $product->setDownloadableData($downloadable);
+            $product->save();
+        } catch (Exception $e) {
+            $this->_fault('save_error', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Retrieve downloadable product links
+     *
+     * @param int|string $productId
+     * @param string|int $store
+     * @param string $identifierType ('sku'|'id')
+     * @return array
+     */
+    public function items($productId, $store = null, $identifierType = null)
+    {
+        $product = $this->_getProduct($productId, $store, $identifierType);
+
+        $linkArr = array();
+        $links = $product->getTypeInstance()->getLinks($product);
+        $fileHelper = Mage::helper('Mage_Downloadable_Helper_File');
+        foreach ($links as $item) {
+            $tmpLinkItem = array(
+                'link_id' => $item->getId(),
+                'title' => $item->getTitle(),
+                'price' => $item->getPrice(),
+                'number_of_downloads' => $item->getNumberOfDownloads(),
+                'is_shareable' => $item->getIsShareable(),
+                'link_url' => $item->getLinkUrl(),
+                'link_type' => $item->getLinkType(),
+                'sample_file' => $item->getSampleFile(),
+                'sample_url' => $item->getSampleUrl(),
+                'sample_type' => $item->getSampleType(),
+                'sort_order' => $item->getSortOrder()
+            );
+            $file = $fileHelper->getFilePath(
+                Mage_Downloadable_Model_Link::getBasePath(), $item->getLinkFile()
+            );
+
+            if ($item->getLinkFile() && !is_file($file)) {
+                Mage::helper('Mage_Core_Helper_File_Storage_Database')->saveFileToFilesystem($file);
+            }
+
+            if ($item->getLinkFile() && is_file($file)) {
+                $name = $fileHelper->getFileFromPathFile($item->getLinkFile());
+                $tmpLinkItem['file_save'] = array(
+                    array(
+                        'file' => $item->getLinkFile(),
+                        'name' => $name,
+                        'size' => filesize($file),
+                        'status' => 'old'
+                    ));
+            }
+            $sampleFile = $fileHelper->getFilePath(
+                Mage_Downloadable_Model_Link::getBaseSamplePath(), $item->getSampleFile()
+            );
+            if ($item->getSampleFile() && is_file($sampleFile)) {
+                $tmpLinkItem['sample_file_save'] = array(
+                    array(
+                        'file' => $item->getSampleFile(),
+                        'name' => $fileHelper->getFileFromPathFile($item->getSampleFile()),
+                        'size' => filesize($sampleFile),
+                        'status' => 'old'
+                    ));
+            }
+            if ($item->getNumberOfDownloads() == '0') {
+                $tmpLinkItem['is_unlimited'] = 1;
+            }
+            if ($product->getStoreId() && $item->getStoreTitle()) {
+                $tmpLinkItem['store_title'] = $item->getStoreTitle();
+            }
+            if ($product->getStoreId() && Mage::helper('Mage_Downloadable_Helper_Data')->getIsPriceWebsiteScope()) {
+                $tmpLinkItem['website_price'] = $item->getWebsitePrice();
+            }
+            $linkArr[] = $tmpLinkItem;
+        }
+        unset($item);
+        unset($tmpLinkItem);
+        unset($links);
+
+        $samples = $product->getTypeInstance()->getSamples($product)->getData();
+        return array('links' => $linkArr, 'samples' => $samples);
+    }
+
+    /**
+     * Remove downloadable product link
+     * @param string $linkId
+     * @param string $resourceType
+     * @return bool
+     */
+    public function remove($linkId, $resourceType)
+    {
+        try {
+            $this->_getValidator()->validateType($resourceType);
+        } catch (Exception $e) {
+            $this->_fault('validation_error', $e->getMessage());
+        }
+
+        switch($resourceType) {
+            case 'link':
+                $downloadableModel = Mage::getSingleton('Mage_Downloadable_Model_Link');
+                break;
+            case 'sample':
+                $downloadableModel = Mage::getSingleton('Mage_Downloadable_Model_Sample');
+                break;
+        }
+
+        $downloadableModel->load($linkId);
+        if (is_null($downloadableModel->getId())) {
+            $this->_fault('link_was_not_found');
+        }
+
+        try {
+            $downloadableModel->delete();
+        } catch (Exception $e) {
+            $this->_fault('remove_error', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Return loaded downloadable product instance
+     *
+     * @param  int|string $productId (SKU or ID)
+     * @param  int|string $store
+     * @param  string $identifierType
+     * @return Mage_Catalog_Model_Product
+     */
+    protected function _getProduct($productId, $store = null, $identifierType = null)
+    {
+        $product = parent::_getProduct($productId, $store, $identifierType);
+
+        if ($product->getTypeId() !== Mage_Downloadable_Model_Product_Type::TYPE_DOWNLOADABLE) {
+            $this->_fault('product_not_downloadable');
+        }
+
+        return $product;
+    }
+}
diff --git a/app/code/core/Mage/Downloadable/Model/Link/Api/Uploader.php b/app/code/core/Mage/Downloadable/Model/Link/Api/Uploader.php
new file mode 100644
index 00000000000..037577bfb4e
--- /dev/null
+++ b/app/code/core/Mage/Downloadable/Model/Link/Api/Uploader.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.
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * File uploader for API
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Downloadable_Model_Link_Api_Uploader extends Mage_Core_Model_File_Uploader
+{
+    /**
+     * Filename prefix
+     *
+     * @var string
+     */
+    protected $_filePrefix = 'Api';
+
+    /**
+     * Default file type
+     */
+    const DEFAULT_FILE_TYPE = 'application/octet-stream';
+
+    /**
+     * Check if the uploaded file exists
+     *
+     * @throws Exception
+     * @param array $file
+     */
+    public function __construct($file)
+    {
+        $this->_setUploadFile($file);
+        if( !file_exists($this->_file['tmp_name']) ) {
+            throw new Exception('', 'file_not_uploaded');
+        } else {
+            $this->_fileExists = true;
+        }
+    }
+
+    /**
+     * Sets uploaded file info and decodes the file
+     *
+     * @throws Exception
+     * @param array $fileInfo
+     * @return void
+     */
+    private function _setUploadFile($fileInfo)
+    {
+        if (!is_array($fileInfo)) {
+            throw new Exception('', 'file_data_not_correct');
+        }
+
+        $this->_file = $this->_decodeFile($fileInfo);
+        $this->_uploadType = self::SINGLE_STYLE;
+    }
+
+    /**
+     * Decode uploaded file base64 encoded content
+     *
+     * @param array $fileInfo
+     * @return array
+     */
+    private function _decodeFile($fileInfo)
+    {
+        $tmpFileName = $this->_getTmpFilePath();
+
+        $file = new Varien_Io_File();
+        $file->open(array('path' => sys_get_temp_dir()));
+        $file->streamOpen($tmpFileName);
+        $file->streamWrite(base64_decode($fileInfo['base64_content']));
+        $file->streamClose();
+
+        return array(
+            'name' => $fileInfo['name'],
+            'type' => isset($fileInfo['type'])? $fileInfo['type'] : self::DEFAULT_FILE_TYPE,
+            'tmp_name' => $tmpFileName,
+            'error' => 0,
+            'size' => filesize($tmpFileName)
+        );
+    }
+
+    /**
+     * Generate temporary file name
+     *
+     * @return string
+     */
+    private function _getTmpFilePath()
+    {
+        return tempnam(sys_get_temp_dir(), $this->_filePrefix);
+
+    }
+
+    /**
+     * Moves a file
+     *
+     * @param string $sourceFile
+     * @param string $destinationFile
+     * @return bool
+     */
+    protected function _moveFile($sourceFile, $destinationFile)
+    {
+        return rename($sourceFile, $destinationFile);
+    }
+
+}
diff --git a/app/code/core/Mage/Downloadable/Model/Link/Api/V2.php b/app/code/core/Mage/Downloadable/Model/Link/Api/V2.php
new file mode 100644
index 00000000000..d4ae42cc520
--- /dev/null
+++ b/app/code/core/Mage/Downloadable/Model/Link/Api/V2.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Downloadable links API model
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @author Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Downloadable_Model_Link_Api_V2 extends Mage_Downloadable_Model_Link_Api
+{
+    /**
+     * Clean the object, leave only property values
+     *
+     * @param object $var
+     * @return void
+     */
+    protected function _prepareData(&$var)
+    {
+        if (is_object($var)) {
+            $var = get_object_vars($var);
+            foreach ($var as $key => &$value) {
+                $this->_prepareData($value);
+            }
+        }
+    }
+
+    /**
+     * Add downloadable content to product
+     *
+     * @param int|string $productId
+     * @param object $resource
+     * @param string $resourceType
+     * @param string|int $store
+     * @param string $identifierType ('sku'|'id')
+     * @return type
+     */
+    public function add($productId, $resource, $resourceType, $store = null, $identifierType = null)
+    {
+        $this->_prepareData($resource);
+        return parent::add($productId, $resource, $resourceType, $store, $identifierType);
+    }
+}
diff --git a/app/code/core/Mage/Downloadable/Model/Link/Api/Validator.php b/app/code/core/Mage/Downloadable/Model/Link/Api/Validator.php
new file mode 100644
index 00000000000..5ee342e6d17
--- /dev/null
+++ b/app/code/core/Mage/Downloadable/Model/Link/Api/Validator.php
@@ -0,0 +1,286 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Downloadable links validator
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Downloadable_Model_Link_Api_Validator //extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Acceptable resourceTypes array
+     * @var array
+     */
+    protected $_types = array('link', 'sample');
+
+    /**
+     * Acceptable upload types array
+     * @var array
+     */
+    protected $_uploadTypes = array('file', 'url');
+
+    /**
+     * List of all attributes and names endings of validation functions
+     *
+     * @var array
+     */
+    protected $_defaultAttributes = array(
+        'link' => array(
+            'title' => 'Title',                         // $1
+            'price' => 'Price',                         // $2
+            'number_of_downloads' => 'NumOfDownloads',  // if no set is_unlimited to 1 $3
+            'is_unlimited' => 'Unlimited',              // 1|0 $4
+            'is_shareable' => 'Shareable',              // 1|0|2 (2) $5
+            'type' => 'UploadType',                     // file|url (file) $6
+            'file' => 'File',                           // array(name, base64_content) $7
+            'link_url' => 'Url',                        // URL $8
+            'sort_order' => 'Order',                    // int (0) $9
+            'sample' => array(
+                'type' => 'UploadType',                 // file|url (file) $6
+                'file' => 'File',                       // array(name, base64_content) $7
+                'url' => 'Url'                          // URL $8
+            )
+        ),
+        'sample' => array(
+            'title' => 'Title',                         // $1
+            'type' => 'UploadType',                     // file|url (file) $6
+            'file' => 'File',                           // array(name, base64_content) $7
+            'sample_url' => 'Url',                      // URL $8
+            'sort_order' => 'Order'                     // int (0) $9
+        )
+    );
+
+    /**
+     * Get resource types
+     *
+     * @return array
+     */
+    public function getResourceTypes()
+    {
+        return $this->_types;
+    }
+
+    /**
+     * Validate resourceType, it should be one of (links|samples|link_samples)
+     *
+     * @param string $type
+     * @return boolean
+     */
+    public function validateType($type)
+    {
+        if (!in_array($type, $this->getResourceTypes())) {
+            throw new Exception('unknown_resource_type');
+        }
+        return true;
+    }
+
+    /**
+     * Validate all parameters and loads default values for omitted parameters.
+     *
+     * @param array $resource
+     * @param string $resourceType
+     */
+    public function validateAttributes(&$resource, $resourceType)
+    {
+        $fields = $this->_defaultAttributes[$resourceType];
+        $this->_dispatch($resource, $fields);
+
+        $this->completeCheck($resource, $resourceType);
+    }
+
+    /**
+     * Final check
+     *
+     * @param array $resource
+     * @param string $resourceType
+     */
+    public function completeCheck(&$resource, $resourceType)
+    {
+        if ($resourceType == 'link') {
+            if ($resource['type'] == 'file') {
+                $this->validateFileDetails($resource['file']);
+            }
+            if ($resource['type'] == 'url' && empty($resource['link_url'])) {
+                throw new Exception('empty_url');
+            }
+            // sample
+            if ($resource['sample']['type'] == 'file') {
+                $this->validateFileDetails($resource['sample']['file']);
+            }
+            if ($resource['sample']['type'] == 'url' && empty($resource['sample']['url'])) {
+                throw new Exception('empty_url');
+            }
+        }
+        if ($resourceType == 'sample') {
+            if ($resource['type'] == 'file') {
+                $this->validateFileDetails($resource['file']);
+            }
+            if ($resource['type'] == 'url' && empty($resource['sample_url'])) {
+                throw new Exception('empty_url');
+            }
+        }
+    }
+
+    /**
+     * Validate variable, in case of fault throw exception
+     *
+     * @param mixed $var
+     */
+    public function validateFileDetails(&$var)
+    {
+        if (!isset ($var['name']) || !is_string($var['name']) || strlen($var['name']) === 0) {
+            throw new Exception('no_filename');
+        }
+        if (!isset ($var['base64_content'])
+            || !is_string($var['base64_content'])
+            || strlen($var['base64_content']) === 0
+        ) {
+            throw new Exception('no_file_base64_content');
+        }
+    }
+
+    /**
+     * Runs all checks.
+     *
+     * @param array $resource
+     * @param array $fields
+     */
+    protected function _dispatch(&$resource, $fields)
+    {
+        foreach ($fields as $name => $validator) {
+            if (is_string($validator) && strlen($validator) > 0 && array_key_exists($name, $resource)) {
+                $call = 'validate' . $validator;
+                $this->$call($resource[$name]);
+            }
+            if (is_array($validator)) {
+                $this->_dispatch($resource[$name], $validator);
+            }
+        }
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param string $var
+     */
+    public function validateTitle(&$var)
+    {
+        if (!is_string($var) || strlen($var) === 0) {
+           throw new Exception('no_title');
+        }
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param float $var
+     */
+    public function validatePrice(&$var)
+    {
+        $var = is_numeric($var)? floatval($var) : floatval(0);
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param int $var
+     */
+    public function validateNumOfDownloads(&$var)
+    {
+        $var = is_numeric($var)? intval($var) : 0;
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param int|boolean $var
+     */
+    public function validateUnlimited(&$var)
+    {
+        $var = ((is_numeric($var) && $var >= 0 && $var <= 1) || (is_bool($var)))? intval($var) : 0;
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param int $var
+     */
+    public function validateShareable(&$var)
+    {
+        $var = (is_numeric($var) && $var >= 0 && $var <= 2)? intval($var) : 2;
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param array $var
+     */
+    public function validateFile(&$var)
+    {
+        $var = is_array($var)? $var : null;
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param string $var
+     */
+    public function validateUrl(&$var)
+    {
+
+        if (is_string($var) && strlen($var) > 0) {
+            $urlregex = "/^(https?|ftp)\:\/\/([a-z0-9+\!\*\(\)\,\;\?\&\=\$\_\.\-]+(\:[a-z0-9+\!\*\(\)\,\;\?\&\=\$\_\.\-]+)?@)?[a-z0-9\+\$\_\-]+(\.[a-z0-9+\$\_\-]+)*(\:[0-9]{2,5})?(\/([a-z0-9+\$\_\-]\.?)+)*\/?(\?[a-z\+\&\$\_\.\-][a-z0-9\;\:\@\/\&\%\=\+\$\_\.\-]*)?(#[a-z\_\.\-][a-z0-9\+\$\_\.\-]*)?$/i";
+            if (!preg_match($urlregex, $var)) {
+                throw new Exception('url_not_valid');
+            }
+        } else {
+            $var = '';
+        }
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param int $var
+     */
+    public function validateOrder(&$var)
+    {
+        $var = is_numeric($var)? intval($var) : 0;
+    }
+
+    /**
+     * Validate variable, in case of fault loads default entity.
+     *
+     * @param string $var
+     */
+    public function validateUploadType(&$var)
+    {
+        $var = in_array($var, $this->_uploadTypes)? $var : 'file';
+    }
+}
diff --git a/app/code/core/Mage/Downloadable/etc/api.xml b/app/code/core/Mage/Downloadable/etc/api.xml
new file mode 100644
index 00000000000..7b9d2fe8d8a
--- /dev/null
+++ b/app/code/core/Mage/Downloadable/etc/api.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Downloadable
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <catalog_product_downloadable_link translate="title" module="Mage_Downloadable">
+                <model>Mage_Downloadable_Model_Link_Api</model>
+                <title>Category API</title>
+                <acl>downloadable/link</acl>
+                <methods>
+                    <add translate="title" module="Mage_Downloadable">
+                        <title>Add links and samples to downloadable product</title>
+                        <method>add</method>
+                        <acl>downloadable/link/add</acl>
+                    </add>
+                    <list translate="title" module="Mage_Downloadable">
+                        <title>Retrieve links and samples list from downloadable product</title>
+                        <method>items</method>
+                        <acl>downloadable/link/list</acl>
+                    </list>
+                    <remove translate="title" module="Mage_Downloadable">
+                        <title>Remove links and samples from downloadable product</title>
+                        <acl>downloadable/link/remove</acl>
+                    </remove>
+                </methods>
+                <faults module="Mage_Downloadable">
+                    <store_not_exists>
+                        <code>100</code>
+                        <message>Store with requested code or ID does not exist.</message>
+                    </store_not_exists>
+                    <product_not_exists>
+                        <code>101</code>
+                        <message>Product with requested ID does not exist.</message>
+                    </product_not_exists>
+                    <links_and_samples_allowed>
+                        <code>401</code>
+                        <message>The resourceType value is invalid, only "links" and "samples" are allowed.</message>
+                    </links_and_samples_allowed>
+                    <empty_url>
+                        <code>402</code>
+                        <message>URL cannot be empty.</message>
+                    </empty_url>
+                    <no_filename>
+                        <code>403</code>
+                        <message>Filename is omitted or contains not allowed characters.</message>
+                    </no_filename>
+                    <no_file_base64_content>
+                        <code>404</code>
+                        <message>File content should be passed as base64 string. For details, please see http://en.wikipedia.org/wiki/Base64</message>
+                    </no_file_base64_content>
+                    <no_title>
+                        <code>405</code>
+                        <message>Title cannot be empty.</message>
+                    </no_title>
+                    <unknown_resource_type>
+                        <code>406</code>
+                        <message>Content type is invalid, only "link", "link_samples", and "sample" are allowed.</message>
+                    </unknown_resource_type>
+                    <product_not_downloadable>
+                        <code>408</code>
+                        <message>Product type is invalid. Downloadable content can be added only to "downloadable" products.</message>
+                    </product_not_downloadable>
+                    <incorect_file_extension>
+                        <code>409</code>
+                        <message>Filename extension is invalid.</message>
+                    </incorect_file_extension>
+                    <file_size_is_to_big>
+                        <code>410</code>
+                        <message>Uploaded file is too big.</message>
+                    </file_size_is_to_big>
+                    <tmp_dir_is_not_writeable>
+                        <code>411</code>
+                        <message>There are no permissions for writing to temporary folder.</message>
+                    </tmp_dir_is_not_writeable>
+                    <can_not_create_sub_tmp_folder>
+                        <code>411</code>
+                        <message>Cannot create sub folder in temporary folder.</message>
+                    </can_not_create_sub_tmp_folder>
+                    <link_was_not_found>
+                        <code>412</code>
+                        <message>Link or sample with specified ID was not found.</message>
+                    </link_was_not_found>
+                    <incorrect_resource_type>
+                        <code>413</code>
+                        <message>Allowed resource type values for remove method are "links" and "samples".</message>
+                    </incorrect_resource_type>
+                    <save_error>
+                        <code>414</code>
+                        <message>Unable to save action. Details are in error message.</message>
+                    </save_error>
+                    <validation_error>
+                        <code>415</code>
+                        <message>Validation error has occurred.</message>
+                    </validation_error>
+                    <remove_error>
+                        <code>416</code>
+                        <message>Unable to remove link. Details are in error message.</message>
+                    </remove_error>
+                </faults>
+            </catalog_product_downloadable_link>
+        </resources>
+        <resources_alias>
+            <product_downloadable_link>catalog_product_downloadable_link</product_downloadable_link>
+        </resources_alias>
+        <v2>
+            <resources_function_prefix>
+                <product_downloadable_link>catalogProductDownloadableLink</product_downloadable_link>
+            </resources_function_prefix>
+        </v2>
+        <acl>
+            <resources>
+                <catalog>
+                    <product>
+                        <downloadable_link translate="title" module="Mage_Downloadable">
+                            <title>Product downloadable links</title>
+                            <add translate="title" module="Mage_Downloadable">
+                                <title>Add</title>
+                            </add>
+                            <list translate="title" module="Mage_Downloadable">
+                                <title>List</title>
+                            </list>
+                            <remove translate="title" module="Mage_Downloadable">
+                                <title>Remove</title>
+                            </remove>
+                        </downloadable_link>
+                    </product>
+                </catalog>
+            </resources>
+        </acl>
+    </api>
+</config>
diff --git a/app/code/core/Mage/Downloadable/etc/wsdl.xml b/app/code/core/Mage/Downloadable/etc/wsdl.xml
new file mode 100644
index 00000000000..b463be954b2
--- /dev/null
+++ b/app/code/core/Mage/Downloadable/etc/wsdl.xml
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             xmlns="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/"
+                    schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"/>
+            <complexType name="catalogProductDownloadableLinkFileEntity">
+                <all>
+                    <element name="name" type="xsd:string" minOccurs="0" />
+                    <element name="base64_content" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkAddSampleEntity">
+                <all>
+                    <element name="type" type="xsd:string" minOccurs="0" />
+                    <element name="file" type="typens:catalogProductDownloadableLinkFileEntity" minOccurs="0" />
+                    <element name="url" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkAddEntity">
+                <all>
+                    <element name="title" type="xsd:string" minOccurs="1" />
+                    <element name="price" type="xsd:string" minOccurs="0" />
+                    <element name="is_unlimited" type="xsd:int" minOccurs="0" />
+                    <element name="number_of_downloads" type="xsd:int" minOccurs="0" />
+                    <element name="is_shareable" type="xsd:int" minOccurs="0" />
+                    <element name="sample" type="typens:catalogProductDownloadableLinkAddSampleEntity" minOccurs="0" />
+                    <element name="type" type="xsd:string" minOccurs="0" />
+                    <element name="file" type="typens:catalogProductDownloadableLinkFileEntity" minOccurs="0" />
+                    <element name="link_url" type="xsd:string" minOccurs="0" />
+                    <element name="sample_url" type="xsd:string" minOccurs="0" />
+                    <element name="sort_order" type="xsd:int" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkFileInfoEntity">
+                <all>
+                    <element name="file" type="xsd:string" />
+                    <element name="name" type="xsd:string" />
+                    <element name="size" type="xsd:int" />
+                    <element name="status" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkFileInfoEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductDownloadableLinkFileInfoEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkEntity">
+                <all>
+                    <element name="link_id" type="xsd:string" />
+                    <element name="title" type="xsd:string" />
+                    <element name="price" type="xsd:string" />
+                    <element name="number_of_downloads" type="xsd:int" minOccurs="0" />
+                    <element name="is_unlimited" type="xsd:int" minOccurs="0" />
+                    <element name="is_shareable" type="xsd:int" />
+                    <element name="link_url" type="xsd:string" />
+                    <element name="link_type" type="xsd:string" />
+                    <element name="sample_file" type="xsd:string" minOccurs="0" />
+                    <element name="sample_url" type="xsd:string" minOccurs="0" />
+                    <element name="sample_type" type="xsd:string" />
+                    <element name="sort_order" type="xsd:int" />
+                    <element name="file_save" type="typens:catalogProductDownloadableLinkFileInfoEntityArray" minOccurs="0" />
+                    <element name="sample_file_save" type="typens:catalogProductDownloadableLinkFileInfoEntityArray" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductDownloadableLinkEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkSampleEntity">
+                <all>
+                    <element name="sample_id" type="xsd:string" />
+                    <element name="product_id" type="xsd:string" />
+                    <element name="sample_file" type="xsd:string" minOccurs="0" />
+                    <element name="sample_url" type="xsd:string" minOccurs="0" />
+                    <element name="sample_type" type="xsd:string" />
+                    <element name="sort_order" type="xsd:string" />
+                    <element name="default_title" type="xsd:string" />
+                    <element name="store_title" type="xsd:string" />
+                    <element name="title" type="xsd:string" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkSampleEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductDownloadableLinkSampleEntity[]"/>
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductDownloadableLinkInfoEntity">
+                <all>
+                    <element name="links" type="typens:catalogProductDownloadableLinkEntityArray" />
+                    <element name="samples" type="typens:catalogProductDownloadableLinkSampleEntityArray" />
+                </all>
+            </complexType>
+        </schema>
+    </types>
+    <message name="catalogProductDownloadableLinkAddRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="productId" type="xsd:string"/>
+        <part name="resource" type="typens:catalogProductDownloadableLinkAddEntity"/>
+        <part name="resourceType" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+        <part name="identifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductDownloadableLinkAddResponse">
+        <part name="respons" type="xsd:int"/>
+    </message>
+    <message name="catalogProductDownloadableLinkListRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="productId" type="xsd:string"/>
+        <part name="store" type="xsd:string"/>
+        <part name="identifierType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductDownloadableLinkListResponse">
+        <part name="respons" type="typens:catalogProductDownloadableLinkInfoEntity"/>
+    </message>
+    <message name="catalogProductDownloadableLinkRemoveRequest">
+        <part name="sessionId" type="xsd:string"/>
+        <part name="linkId" type="xsd:string"/>
+        <part name="resourceType" type="xsd:string"/>
+    </message>
+    <message name="catalogProductDownloadableLinkRemoveResponse">
+        <part name="respons" type="xsd:boolean"/>
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="catalogProductDownloadableLinkAdd">
+            <documentation>Add links to downloadable product</documentation>
+            <input message="typens:catalogProductDownloadableLinkAddRequest"/>
+            <output message="typens:catalogProductDownloadableLinkAddResponse"/>
+        </operation>
+        <operation name="catalogProductDownloadableLinkList">
+            <documentation>Retrieve list of links and samples for downloadable product</documentation>
+            <input message="typens:catalogProductDownloadableLinkListRequest"/>
+            <output message="typens:catalogProductDownloadableLinkListResponse"/>
+        </operation>
+        <operation name="catalogProductDownloadableLinkRemove">
+            <documentation>Remove links and samples from downloadable product</documentation>
+            <input message="typens:catalogProductDownloadableLinkRemoveRequest"/>
+            <output message="typens:catalogProductDownloadableLinkRemoveResponse"/>
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <operation name="catalogProductDownloadableLinkAdd">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductDownloadableLinkList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+        <operation name="catalogProductDownloadableLinkRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action"/>
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded"
+                           encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+            </output>
+        </operation>
+    </binding>
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}"/>
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/Downloadable/etc/wsi.xml b/app/code/core/Mage/Downloadable/etc/wsi.xml
new file mode 100644
index 00000000000..498eb427f3c
--- /dev/null
+++ b/app/code/core/Mage/Downloadable/etc/wsi.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="catalogProductDownloadableLinkFileEntity">
+                <xsd:sequence>
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base64_content" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkAddSampleEntity">
+                <xsd:sequence>
+                    <xsd:element name="type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="file" type="typens:catalogProductDownloadableLinkFileEntity" minOccurs="0" />
+                    <xsd:element name="url" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkAddEntity">
+                <xsd:sequence>
+                    <xsd:element name="title" type="xsd:string" minOccurs="1" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_unlimited" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="number_of_downloads" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="is_shareable" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="sample" type="typens:catalogProductDownloadableLinkAddSampleEntity" minOccurs="0" />
+                    <xsd:element name="type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="file" type="typens:catalogProductDownloadableLinkFileEntity" minOccurs="0" />
+                    <xsd:element name="link_url" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sample_url" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sort_order" type="xsd:int" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkFileInfoEntity">
+                <xsd:sequence>
+                    <xsd:element name="file" type="xsd:string" />
+                    <xsd:element name="name" type="xsd:string" />
+                    <xsd:element name="size" type="xsd:int" />
+                    <xsd:element name="status" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkFileInfoEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductDownloadableLinkFileInfoEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkEntity">
+                <xsd:sequence>
+                    <xsd:element name="link_id" type="xsd:string" />
+                    <xsd:element name="title" type="xsd:string" />
+                    <xsd:element name="price" type="xsd:string" />
+                    <xsd:element name="number_of_downloads" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="is_unlimited" type="xsd:int" minOccurs="0" />
+                    <xsd:element name="is_shareable" type="xsd:int" />
+                    <xsd:element name="link_url" type="xsd:string" />
+                    <xsd:element name="link_type" type="xsd:string" />
+                    <xsd:element name="sample_file" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sample_url" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sample_type" type="xsd:string" />
+                    <xsd:element name="sort_order" type="xsd:int" />
+                    <xsd:element name="file_save" type="typens:catalogProductDownloadableLinkFileInfoEntityArray" minOccurs="0" />
+                    <xsd:element name="sample_file_save" type="typens:catalogProductDownloadableLinkFileInfoEntityArray" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductDownloadableLinkEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkSampleEntity">
+                <xsd:sequence>
+                    <xsd:element name="sample_id" type="xsd:string" />
+                    <xsd:element name="product_id" type="xsd:string" />
+                    <xsd:element name="sample_file" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sample_url" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sample_type" type="xsd:string" />
+                    <xsd:element name="sort_order" type="xsd:string" />
+                    <xsd:element name="default_title" type="xsd:string" />
+                    <xsd:element name="store_title" type="xsd:string" />
+                    <xsd:element name="title" type="xsd:string" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkSampleEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductDownloadableLinkSampleEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductDownloadableLinkListEntity">
+                <xsd:sequence>
+                    <xsd:element name="links" type="typens:catalogProductDownloadableLinkEntityArray" />
+                    <xsd:element name="samples" type="typens:catalogProductDownloadableLinkSampleEntityArray" />
+                </xsd:sequence>
+            </xsd:complexType>
+
+
+            <xsd:element name="catalogProductDownloadableLinkAddRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="resource" type="typens:catalogProductDownloadableLinkAddEntity" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="resourceType" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductDownloadableLinkAddResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductDownloadableLinkListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductDownloadableLinkListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:catalogProductDownloadableLinkListEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductDownloadableLinkRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="linkId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="resourceType" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductDownloadableLinkRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="catalogProductDownloadableLinkAddRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductDownloadableLinkAddRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductDownloadableLinkAddResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductDownloadableLinkAddResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductDownloadableLinkListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductDownloadableLinkListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductDownloadableLinkListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductDownloadableLinkListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductDownloadableLinkRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductDownloadableLinkRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductDownloadableLinkRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductDownloadableLinkRemoveResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="catalogProductDownloadableLinkAdd">
+            <wsdl:documentation>Add links to downloadable product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductDownloadableLinkAddRequest" />
+            <wsdl:output message="typens:catalogProductDownloadableLinkAddResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductDownloadableLinkList">
+            <wsdl:documentation>Retrieve list of links and samples for downloadable product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductDownloadableLinkListRequest" />
+            <wsdl:output message="typens:catalogProductDownloadableLinkListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductDownloadableLinkRemove">
+            <wsdl:documentation>Remove links and samples from downloadable product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductDownloadableLinkRemoveRequest" />
+            <wsdl:output message="typens:catalogProductDownloadableLinkRemoveResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="catalogProductDownloadableLinkAdd">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductDownloadableLinkList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="catalogProductDownloadableLinkRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/GiftMessage/Model/Api.php b/app/code/core/Mage/GiftMessage/Model/Api.php
new file mode 100644
index 00000000000..776dc6f7c12
--- /dev/null
+++ b/app/code/core/Mage/GiftMessage/Model/Api.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_GiftMessage
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * GiftMessage api
+ *
+ * @category   Mage
+ * @package    Mage_GiftMessage
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_GiftMessage_Model_Api extends Mage_Checkout_Model_Api_Resource_Product
+{
+    /**
+     * Return an Array of attributes.
+     *
+     * @param Array $obj
+     * @return Array
+     */
+    protected function _prepareData($arr)
+    {
+        if (is_array($arr)) {
+            return $arr;
+        }
+        return array();
+    }
+
+    /**
+     * Raise event for setting a giftMessage.
+     *
+     * @param String $entityId
+     * @param Mage_Core_Controller_Request_Http $request
+     * @param Mage_Sales_Model_Quote $quote
+     * @return AssociativeArray
+     */
+    protected function _setGiftMessage($entityId, $request, $quote)
+    {
+
+        /**
+         * Below code will catch exceptions only in DeveloperMode
+         * @see Mage_Core_Model_App::_callObserverMethod($object, $method, $observer)
+         * And result of Mage::dispatchEvent will always return an Object of Mage_Core_Model_App.
+         */
+        try {
+            /** Frontend area events must be loaded as we emulate frontend behavior. */
+            Mage::app()->loadAreaPart(Mage_Core_Model_App_Area::AREA_FRONTEND, Mage_Core_Model_App_Area::PART_EVENTS);
+            Mage::dispatchEvent(
+                'checkout_controller_onepage_save_shipping_method',
+                array('request' => $request, 'quote' => $quote)
+            );
+            return array('entityId' => $entityId, 'result' => true, 'error' => '');
+        } catch (Exception $e) {
+            return array('entityId' => $entityId, 'result' => false, 'error' => $e->getMessage());
+        }
+    }
+
+    /**
+     * Set GiftMessage for a Quote.
+     *
+     * @param String $quoteId
+     * @param AssociativeArray $giftMessage
+     * @param String $store
+     * @return AssociativeArray
+     */
+    public function setForQuote($quoteId, $giftMessage, $store = null)
+    {
+        /** @var $quote Mage_Sales_Model_Quote */
+        $quote = $this->_getQuote($quoteId, $store);
+
+        $giftMessage = $this->_prepareData($giftMessage);
+        if (empty($giftMessage)) {
+            $this->_fault('giftmessage_invalid_data');
+        }
+
+        $giftMessage['type'] = 'quote';
+        $giftMessages = array($quoteId => $giftMessage);
+        $request = new Mage_Core_Controller_Request_Http();
+        $request->setParam("giftmessage", $giftMessages);
+
+        return $this->_setGiftMessage($quote->getId(), $request, $quote);
+    }
+
+    /**
+     * Set a GiftMessage to QuoteItem by product
+     *
+     * @param String $quoteId
+     * @param Array $productsAndMessages
+     * @param String $store
+     * @return array
+     */
+    public function setForQuoteProduct($quoteId, $productsAndMessages, $store = null)
+    {
+        /** @var $quote Mage_Sales_Model_Quote */
+        $quote = $this->_getQuote($quoteId, $store);
+
+        $productsAndMessages = $this->_prepareData($productsAndMessages);
+        if (empty($productsAndMessages)) {
+            $this->_fault('invalid_data');
+        }
+
+        if (count($productsAndMessages) == 2
+                && isset($productsAndMessages['product'])
+                && isset($productsAndMessages['message'])) {
+            $productsAndMessages = array($productsAndMessages);
+        }
+
+        $results = array();
+        foreach ($productsAndMessages as $productAndMessage) {
+            if (isset($productAndMessage['product']) && isset($productAndMessage['message'])) {
+                $product = $this->_prepareData($productAndMessage['product']);
+                if (empty($product)) {
+                    $this->_fault('product_invalid_data');
+                }
+                $message = $this->_prepareData($productAndMessage['message']);
+                if (empty($message)) {
+                    $this->_fault('giftmessage_invalid_data');
+                }
+
+                if (isset($product['product_id'])) {
+                    $productByItem = $this->_getProduct($product['product_id'], $store, "id");
+                } elseif (isset($product['sku'])) {
+                    $productByItem = $this->_getProduct($product['sku'], $store, "sku");
+                } else {
+                    continue;
+                }
+
+                $productObj = $this->_getProductRequest($product);
+                $quoteItem = $this->_getQuoteItemByProduct($quote, $productByItem, $productObj);
+                $results[] = $this->setForQuoteItem($quoteItem->getId(), $message, $store);
+            }
+        }
+
+        return $results;
+    }
+
+    /**
+     * Set GiftMessage for a QuoteItem by its Id.
+     *
+     * @param String $quoteItemId
+     * @param AssociativeArray $giftMessage
+     * @param String $store
+     * @return AssociativeArray
+     */
+    public function setForQuoteItem($quoteItemId, $giftMessage, $store = null)
+    {
+        /** @var $quote Mage_Sales_Model_Quote_Item */
+        $quoteItem = Mage::getModel('Mage_Sales_Model_Quote_Item')->load($quoteItemId);
+        if (is_null($quoteItem->getId())) {
+            $this->_fault("quote_item_not_exists");
+        }
+
+        /** @var $quote Mage_Sales_Model_Quote */
+        $quote = $this->_getQuote($quoteItem->getQuoteId(), $store);
+
+        $giftMessage = $this->_prepareData($giftMessage);
+        $giftMessage['type'] = 'quote_item';
+
+        $giftMessages = array($quoteItem->getId() => $giftMessage);
+
+        $request = new Mage_Core_Controller_Request_Http();
+        $request->setParam("giftmessage", $giftMessages);
+
+        return $this->_setGiftMessage($quoteItemId, $request, $quote);
+    }
+}
diff --git a/app/code/core/Mage/GiftMessage/Model/Api/V2.php b/app/code/core/Mage/GiftMessage/Model/Api/V2.php
new file mode 100644
index 00000000000..16fb55058c6
--- /dev/null
+++ b/app/code/core/Mage/GiftMessage/Model/Api/V2.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_GiftMessage
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * GiftMessage api
+ *
+ * @category   Mage
+ * @package    Mage_GiftMessage
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_GiftMessage_Model_Api_V2 extends Mage_GiftMessage_Model_Api
+{
+
+    /**
+     * Return an Array of Object attributes.
+     *
+     * @param Mixed $data
+     * @return Array
+     */
+    protected function _prepareData($data)
+    {
+        if (is_object($data)) {
+            $arr = get_object_vars($data);
+            foreach ($arr as $key => $value) {
+                $assocArr = array();
+                if (is_array($value)) {
+                    foreach ($value as $v) {
+                        if (is_object($v) && count(get_object_vars($v)) == 2
+                            && isset($v->key) && isset($v->value)
+                        ) {
+                            $assocArr[$v->key] = $v->value;
+                        }
+                    }
+                }
+                if (!empty($assocArr)) {
+                    $arr[$key] = $assocArr;
+                }
+            }
+            $arr = $this->_prepareData($arr);
+            return parent::_prepareData($arr);
+        }
+        if (is_array($data)) {
+            foreach ($data as $key => $value) {
+                if (is_object($value) || is_array($value)) {
+                    $data[$key] = $this->_prepareData($value);
+                } else {
+                    $data[$key] = $value;
+                }
+            }
+            return parent::_prepareData($data);
+        }
+        return $data;
+    }
+
+    /**
+     * Raise event for setting a giftMessage.
+     *
+     * @param String $entityId
+     * @param Mage_Core_Controller_Request_Http $request
+     * @param Mage_Sales_Model_Quote $quote
+     * @return stdClass
+     */
+    protected function _setGiftMessage($entityId, $request, $quote)
+    {
+        $response = new stdClass();
+        $response->entityId = $entityId;
+
+        /**
+         * Below code will catch exceptions only in DeveloperMode
+         *
+         * @see Mage_Core_Model_App::_callObserverMethod($object, $method, $observer)
+         * And result of Mage::dispatchEvent will always return an Object of Mage_Core_Model_App.
+         */
+        try {
+            /** Frontend area events must be loaded as we emulate frontend behavior. */
+            Mage::app()->loadAreaPart(Mage_Core_Model_App_Area::AREA_FRONTEND, Mage_Core_Model_App_Area::PART_EVENTS);
+            Mage::dispatchEvent(
+                'checkout_controller_onepage_save_shipping_method',
+                array('request' => $request, 'quote' => $quote)
+            );
+            $response->result = true;
+            $response->error = '';
+        } catch (Exception $e) {
+            $response->result = false;
+            $response->error = $e->getMessage();
+        }
+        return $response;
+    }
+
+}
diff --git a/app/code/core/Mage/GiftMessage/etc/api.xml b/app/code/core/Mage/GiftMessage/etc/api.xml
new file mode 100644
index 00000000000..fe1225eaca9
--- /dev/null
+++ b/app/code/core/Mage/GiftMessage/etc/api.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_GiftMessage
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <giftmessage translate="title" module="Mage_GiftMessage">
+                <model>Mage_GiftMessage_Model_Api</model>
+                <title>Gift Message API</title>
+                <acl>giftmessage/set</acl>
+                <methods>
+                    <setForQuote translate="title" module="Mage_GiftMessage">
+                        <title>Add gift message for shopping cart</title>
+                        <method>setForQuote</method>
+                        <acl>giftmessage/set</acl>
+                    </setForQuote>
+                    <setForQuoteItem translate="title" module="Mage_GiftMessage">
+                        <title>Add gift messages for quote item of shopping cart</title>
+                        <method>setForQuoteItem</method>
+                        <acl>giftmessage/set</acl>
+                    </setForQuoteItem>
+                    <setForQuoteProduct translate="title" module="Mage_GiftMessage">
+                        <title>Add gift messages to products of shopping cart</title>
+                        <method>setForQuoteProduct</method>
+                        <acl>giftmessage/set</acl>
+                    </setForQuoteProduct>
+                </methods>
+                <faults module="Mage_GiftMessage">
+                    <store_not_exists>
+                        <code>1001</code>
+                        <message>Cannot perform operation because store does not exist.</message>
+                    </store_not_exists>
+                    <quote_not_exists>
+                        <code>1002</code>
+                        <message>Cannot perform operation because quote does not exist.</message>
+                    </quote_not_exists>
+                    <giftmessage_invalid_data>
+                        <code>1101</code>
+                        <message>Gift message data is not valid.</message>
+                    </giftmessage_invalid_data>
+                    <product_invalid_data>
+                        <code>1102</code>
+                        <message>Product data is not valid.</message>
+                    </product_invalid_data>
+                    <quote_item_not_exists>
+                        <code>1103</code>
+                        <message>Quote item does not exist.</message>
+                    </quote_item_not_exists>
+                </faults>
+            </giftmessage>
+        </resources>
+        <acl>
+            <resources>
+                <giftmessage translate="title" module="Mage_Checkout">
+                    <title>Gift Message</title>
+                    <set translate="title" module="Mage_Checkout">
+                        <title>Add gift messages to shopping cart</title>
+                    </set>
+                </giftmessage>
+            </resources>
+        </acl>
+        <v2>
+            <resources_function_prefix>
+                <giftmessage>giftMessage</giftmessage>
+            </resources_function_prefix>
+        </v2>
+    </api>
+</config>
diff --git a/app/code/core/Mage/GiftMessage/etc/wsdl.xml b/app/code/core/Mage/GiftMessage/etc/wsdl.xml
new file mode 100644
index 00000000000..9fd677d2cac
--- /dev/null
+++ b/app/code/core/Mage/GiftMessage/etc/wsdl.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
+    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
+            <complexType name="giftMessageEntity">
+                <sequence>
+                    <element name="from" type="xsd:string" minOccurs="0" />
+                    <element name="to" type="xsd:string" minOccurs="0" />
+                    <element name="message" type="xsd:string" minOccurs="0" />
+                </sequence>
+            </complexType>
+            <complexType name="giftMessageResponse">
+                <sequence>
+                    <element name="entityId" type="xsd:string" minOccurs="0" />
+                    <element name="result" type="xsd:boolean" minOccurs="0" />
+                    <element name="error" type="xsd:string" minOccurs="0" />
+                </sequence>
+            </complexType>
+            <complexType name="giftMessageResponseArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:giftMessageResponse[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="giftMessageAssociativeProductsEntity">
+                <sequence>
+                    <element name="product" type="typens:shoppingCartProductEntity" />
+                    <element name="message" type="typens:giftMessageEntity" />
+                </sequence>
+            </complexType>
+            <complexType name="giftMessageAssociativeProductsEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:giftMessageAssociativeProductsEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+        </schema>
+    </types>
+    <message name="giftMessageForQuoteRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="quoteId" type="xsd:string" />
+        <part name="giftMessage" type="typens:giftMessageEntity" />
+        <part name="storeId" type="xsd:string" />
+    </message>
+    <message name="giftMessageForQuoteResponse">
+        <part name="result" type="typens:giftMessageResponse" />
+    </message>
+    <message name="giftMessageForQuoteItemRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="quoteItemId" type="xsd:string" />
+        <part name="giftMessage" type="typens:giftMessageEntity" />
+        <part name="storeId" type="xsd:string" />
+    </message>
+    <message name="giftMessageForQuoteItemResponse">
+        <part name="result" type="typens:giftMessageResponse" />
+    </message>
+    <message name="giftMessageForQuoteProductRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="quoteId" type="xsd:string" />
+        <part name="productsAndMessages" type="typens:giftMessageAssociativeProductsEntityArray" />
+        <part name="storeId" type="xsd:string" />
+    </message>
+    <message name="giftMessageForQuoteProductResponse">
+        <part name="result" type="typens:giftMessageResponseArray" />
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="giftMessageSetForQuote">
+            <documentation>Set a gift message to the cart</documentation>
+            <input message="typens:giftMessageForQuoteRequest" />
+            <output message="typens:giftMessageForQuoteResponse" />
+        </operation>
+        <operation name="giftMessageSetForQuoteItem">
+            <documentation>Setting a gift messages to the quote item</documentation>
+            <input message="typens:giftMessageForQuoteItemRequest" />
+            <output message="typens:giftMessageForQuoteItemResponse" />
+        </operation>
+        <operation name="giftMessageSetForQuoteProduct">
+            <documentation>Setting a gift messages to the quote items by products</documentation>
+            <input message="typens:giftMessageForQuoteProductRequest" />
+            <output message="typens:giftMessageForQuoteProductResponse" />
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="giftMessageSetForQuote">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="giftMessageSetForQuoteItem">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="giftMessageSetForQuoteProduct">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/GiftMessage/etc/wsi.xml b/app/code/core/Mage/GiftMessage/etc/wsi.xml
new file mode 100644
index 00000000000..155d52646b5
--- /dev/null
+++ b/app/code/core/Mage/GiftMessage/etc/wsi.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="giftMessageEntity">
+                <xsd:sequence>
+                    <xsd:element name="from" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="to" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="message" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="giftMessageResponse">
+                <xsd:sequence>
+                    <xsd:element name="entityId" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="result" type="xsd:boolean" minOccurs="0" />
+                    <xsd:element name="error" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="giftMessageResponseArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:giftMessageResponse" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="giftMessageAssociativeProductsEntity">
+                <xsd:sequence>
+                    <xsd:element name="product" type="typens:shoppingCartProductEntity" />
+                    <xsd:element name="message" type="typens:giftMessageEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="giftMessageAssociativeProductsEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:giftMessageAssociativeProductsEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+
+
+            <xsd:element name="giftMessageForQuoteRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="giftMessage" type="typens:giftMessageEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="giftMessageForQuoteResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:giftMessageResponse" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="giftMessageForQuoteItemRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteItemId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="giftMessage" type="typens:giftMessageEntity" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="giftMessageForQuoteItemResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:giftMessageResponse" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="giftMessageForQuoteProductRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="productsAndMessages" type="typens:giftMessageAssociativeProductsEntityArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="giftMessageForQuoteProductResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:giftMessageResponseArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="giftMessageForQuoteRequest">
+        <wsdl:part name="parameters" element="typens:giftMessageForQuoteRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="giftMessageForQuoteResponse">
+        <wsdl:part name="parameters" element="typens:giftMessageForQuoteResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="giftMessageForQuoteItemRequest">
+        <wsdl:part name="parameters" element="typens:giftMessageForQuoteItemRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="giftMessageForQuoteItemResponse">
+        <wsdl:part name="parameters" element="typens:giftMessageForQuoteItemResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="giftMessageForQuoteProductRequest">
+        <wsdl:part name="parameters" element="typens:giftMessageForQuoteProductRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="giftMessageForQuoteProductResponse">
+        <wsdl:part name="parameters" element="typens:giftMessageForQuoteProductResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="giftMessageSetForQuote">
+            <wsdl:documentation>Set a gift message to the cart</wsdl:documentation>
+            <wsdl:input message="typens:giftMessageForQuoteRequest" />
+            <wsdl:output message="typens:giftMessageForQuoteResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="giftMessageSetForQuoteItem">
+            <wsdl:documentation>Setting a gift messages to the quote item</wsdl:documentation>
+            <wsdl:input message="typens:giftMessageForQuoteItemRequest" />
+            <wsdl:output message="typens:giftMessageForQuoteItemResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="giftMessageSetForQuoteProduct">
+            <wsdl:documentation>Setting a gift messages to the quote items by products</wsdl:documentation>
+            <wsdl:input message="typens:giftMessageForQuoteProductRequest" />
+            <wsdl:output message="typens:giftMessageForQuoteProductResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="giftMessageSetForQuote">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="giftMessageSetForQuoteItem">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="giftMessageSetForQuoteProduct">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/GoogleShopping/Block/Adminhtml/Types/Edit/Attributes.php b/app/code/core/Mage/GoogleShopping/Block/Adminhtml/Types/Edit/Attributes.php
index 88033575fa8..ead66fc53bf 100644
--- a/app/code/core/Mage/GoogleShopping/Block/Adminhtml/Types/Edit/Attributes.php
+++ b/app/code/core/Mage/GoogleShopping/Block/Adminhtml/Types/Edit/Attributes.php
@@ -124,7 +124,7 @@ class Mage_GoogleShopping_Block_Adminhtml_Types_Edit_Attributes
      */
     public function getAttributesSelectHtml($escapeJsQuotes = false)
     {
-        $select = $this->getLayout()->createBlock('Mage_Adminhtml_Block_Html_Select')
+        $select = $this->getLayout()->createBlock('Mage_Core_Block_Html_Select')
             ->setId($this->getFieldId().'_{{index}}_attribute')
             ->setName($this->getFieldName().'[{{index}}][attribute_id]')
             ->setOptions($this->_getAttributes($this->getAttributeSetId(), $escapeJsQuotes));
diff --git a/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Edit/Before.php b/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Edit/Before.php
index 7226ecf9506..c7f565c4189 100644
--- a/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Edit/Before.php
+++ b/app/code/core/Mage/ImportExport/Block/Adminhtml/Import/Edit/Before.php
@@ -48,6 +48,8 @@ class Mage_ImportExport_Block_Adminhtml_Import_Edit_Before extends Mage_Backend_
     protected $_importModel;
 
     /**
+     * Constructor
+     *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
      * @param Mage_Core_Model_Event_Manager $eventManager
@@ -59,6 +61,8 @@ class Mage_ImportExport_Block_Adminhtml_Import_Edit_Before extends Mage_Backend_
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Helper_Data $coreHelper
      * @param Mage_ImportExport_Model_Import $importModel
@@ -77,13 +81,15 @@ class Mage_ImportExport_Block_Adminhtml_Import_Edit_Before extends Mage_Backend_
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Helper_Data $coreHelper,
         Mage_ImportExport_Model_Import $importModel,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
         $this->_coreHelper = $coreHelper;
         $this->_importModel = $importModel;
diff --git a/app/code/core/Mage/ImportExport/Model/Import/Entity/Product.php b/app/code/core/Mage/ImportExport/Model/Import/Entity/Product.php
index dc5a07c6b9d..9cf9de8f593 100644
--- a/app/code/core/Mage/ImportExport/Model/Import/Entity/Product.php
+++ b/app/code/core/Mage/ImportExport/Model/Import/Entity/Product.php
@@ -1195,14 +1195,18 @@ class Mage_ImportExport_Model_Import_Entity_Product extends Mage_ImportExport_Mo
 
             $this->_fileUploader->init();
 
-            $tmpDir     = Mage::getConfig()->getOptions()->getMediaDir() . '/import';
-            $destDir    = Mage::getConfig()->getOptions()->getMediaDir() . '/catalog/product';
-            if (!is_writable($destDir)) {
-                @mkdir($destDir, 0777, true);
+            $mediaDir = Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA);
+            if (!$mediaDir) {
+                throw new Magento_Exception('Media directory is unavailable.');
             }
+            $tmpDir = "{$mediaDir}/import";
             if (!$this->_fileUploader->setTmpDir($tmpDir)) {
                 Mage::throwException("File directory '{$tmpDir}' is not readable.");
             }
+            $destDir = "{$mediaDir}/catalog/product";
+            if (!is_dir($destDir)) {
+                mkdir($destDir, 0777, true);
+            }
             if (!$this->_fileUploader->setDestDir($destDir)) {
                 Mage::throwException("File directory '{$destDir}' is not writable.");
             }
diff --git a/app/code/core/Mage/Index/Model/Lock/Storage.php b/app/code/core/Mage/Index/Model/Lock/Storage.php
index 66e9ee2a9c6..9df3af7dccf 100644
--- a/app/code/core/Mage/Index/Model/Lock/Storage.php
+++ b/app/code/core/Mage/Index/Model/Lock/Storage.php
@@ -30,9 +30,9 @@
 class Mage_Index_Model_Lock_Storage
 {
     /**
-     * @var Mage_Core_Model_Config
+     * @var Mage_Core_Model_Dir
      */
-    protected $_configuration;
+    protected $_dirs;
 
     /**
      * @var Mage_Index_Model_Process_FileFactory
@@ -47,14 +47,14 @@ class Mage_Index_Model_Lock_Storage
     protected $_fileHandlers = array();
 
     /**
-     * @param Mage_Core_Model_Config $configuration
+     * @param Mage_Core_Model_Dir $dirs
      * @param Mage_Index_Model_Process_FileFactory $fileFactory
      */
     public function __construct(
-        Mage_Core_Model_Config $configuration,
+        Mage_Core_Model_Dir $dirs,
         Mage_Index_Model_Process_FileFactory $fileFactory
     ) {
-        $this->_configuration = $configuration;
+        $this->_dirs = $dirs;
         $this->_fileFactory   = $fileFactory;
     }
 
@@ -68,8 +68,9 @@ class Mage_Index_Model_Lock_Storage
     {
         if (!isset($this->_fileHandlers[$processId])) {
             $file = $this->_fileFactory->createFromArray();
-            $varDirectory = $this->_configuration->getVarDir('locks');
+            $varDirectory = $this->_dirs->getDir(Mage_Core_Model_Dir::VAR_DIR) . DIRECTORY_SEPARATOR . 'locks';
             $file->setAllowCreateFolders(true);
+
             $file->open(array('path' => $varDirectory));
             $fileName = 'index_process_' . $processId . '.lock';
             $file->streamOpen($fileName);
diff --git a/app/code/core/Mage/Install/Helper/Data.php b/app/code/core/Mage/Install/Helper/Data.php
index f90aef95120..d73c915e021 100644
--- a/app/code/core/Mage/Install/Helper/Data.php
+++ b/app/code/core/Mage/Install/Helper/Data.php
@@ -29,65 +29,4 @@
  */
 class Mage_Install_Helper_Data extends Mage_Core_Helper_Abstract
 {
-    /**
-     * The list of var children directories that have to be cleaned before the install
-     *
-     * @var array
-     */
-    protected $_varSubFolders;
-
-    /**
-     * @var Magento_Filesystem
-     */
-    protected $_filesystem;
-
-    public function __construct(Magento_Filesystem $filesystem)
-    {
-        $this->_filesystem = $filesystem;
-    }
-
-    /**
-     * Delete all service folders from var directory
-     */
-    public function cleanVarFolder()
-    {
-        foreach ($this->getVarSubFolders() as $folder) {
-            try {
-                $this->_filesystem->delete($folder);
-            } catch (Magento_Filesystem_Exception $e) {
-            }
-        }
-    }
-
-    /**
-     * Retrieve the list of service directories located in var folder
-     *
-     * @return array
-     */
-    public function getVarSubFolders()
-    {
-        if ($this->_varSubFolders == null) {
-            $this->_varSubFolders = array(
-                Mage::getConfig()->getTempVarDir() . DS . 'session',
-                Mage::getConfig()->getTempVarDir() . DS . 'cache',
-                Mage::getConfig()->getTempVarDir() . DS . 'locks',
-                Mage::getConfig()->getTempVarDir() . DS . 'log',
-                Mage::getConfig()->getTempVarDir() . DS . 'report',
-                Mage::getConfig()->getTempVarDir() . DS . 'maps'
-            );
-        }
-        return $this->_varSubFolders;
-    }
-
-    /**
-     * Set the list of service directories located in var folder
-     *
-     * @param array $varSubFolders
-     * @return Mage_Install_Helper_Data
-     */
-    public function setVarSubFolders(array $varSubFolders)
-    {
-        $this->_varSubFolders = $varSubFolders;
-        return $this;
-    }
 }
diff --git a/app/code/core/Mage/Install/Model/Config.php b/app/code/core/Mage/Install/Model/Config.php
index 00cd5f4a3e0..6ed540a871b 100644
--- a/app/code/core/Mage/Install/Model/Config.php
+++ b/app/code/core/Mage/Install/Model/Config.php
@@ -39,12 +39,6 @@ class Mage_Install_Model_Config extends Varien_Simplexml_Config
     const XML_PATH_CHECK_WRITEABLE  = 'check/filesystem/writeable';
     const XML_PATH_CHECK_EXTENSIONS = 'check/php/extensions';
 
-    protected $_optionsMapping = array(self::XML_PATH_CHECK_WRITEABLE => array(
-        'app_etc' => 'etc_dir',
-        'var'     => 'var_dir',
-        'media'   => 'media_dir',
-    ));
-
     public function __construct()
     {
         parent::__construct();
@@ -110,12 +104,7 @@ class Mage_Install_Model_Config extends Varien_Simplexml_Config
         $items = (array) $this->getNode(self::XML_PATH_CHECK_WRITEABLE);
         foreach ($items as $nodeKey => $item) {
             $value = (array)$item;
-            if (isset($this->_optionsMapping[self::XML_PATH_CHECK_WRITEABLE][$nodeKey])) {
-                $configKey = $this->_optionsMapping[self::XML_PATH_CHECK_WRITEABLE][$nodeKey];
-                $value['path'] = Mage::app()->getConfig()->getOptions()->getData($configKey);
-            } else {
-                $value['path'] = dirname(Mage::getRoot()) . $value['path'];
-            }
+            $value['path'] = Mage::getBaseDir($nodeKey);
             $paths[$nodeKey] = $value;
         }
 
diff --git a/app/code/core/Mage/Install/Model/Installer.php b/app/code/core/Mage/Install/Model/Installer.php
index 2e24f56799f..3a39c9e8eb8 100644
--- a/app/code/core/Mage/Install/Model/Installer.php
+++ b/app/code/core/Mage/Install/Model/Installer.php
@@ -35,12 +35,6 @@
 class Mage_Install_Model_Installer extends Varien_Object
 {
 
-    /**
-     * Installer host response used to check urls
-     *
-     */
-    const INSTALLER_HOST_RESPONSE   = 'MAGENTO';
-
     /**
      * Installer data model used to store data between installation steps
      *
@@ -61,7 +55,7 @@ class Mage_Install_Model_Installer extends Varien_Object
     /**
      * Get data model
      *
-     * @return Varien_Object
+     * @return Mage_Install_Model_Session
      */
     public function getDataModel()
     {
diff --git a/app/code/core/Mage/Install/Model/Installer/Config.php b/app/code/core/Mage/Install/Model/Installer/Config.php
index fabfa65fb3c..5287116ac35 100644
--- a/app/code/core/Mage/Install/Model/Installer/Config.php
+++ b/app/code/core/Mage/Install/Model/Installer/Config.php
@@ -42,20 +42,39 @@ class Mage_Install_Model_Installer_Config extends Mage_Install_Model_Installer_A
      */
     protected $_localConfigFile;
 
-    protected $_configData = array();
+    /**
+     * @var Mage_Core_Model_Config
+     */
+    protected $_config;
 
     /**
-     * @var Magento_Filesystem
+     * @var Mage_Core_Model_Dir
      */
+    protected $_dirs;
+
+    protected $_configData = array();
+
+    /**
+    * @var Magento_Filesystem
+    */
     protected $_filesystem;
 
     /**
+     * Inject dependencies on config and directories
+     *
+     * @param Mage_Core_Model_Config $config
+     * @param Mage_Core_Model_Dir $dirs
      * @param Magento_Filesystem $filesystem
      */
-    public function __construct(Magento_Filesystem $filesystem)
-    {
+    public function __construct(
+            Mage_Core_Model_Config $config,
+            Mage_Core_Model_Dir $dirs,
+            Magento_Filesystem $filesystem
+    ) {
+        $this->_localConfigFile = $dirs->getDir(Mage_Core_Model_Dir::CONFIG) . DIRECTORY_SEPARATOR . 'local.xml';
+        $this->_config = $config;
+        $this->_dirs = $dirs;
         $this->_filesystem = $filesystem;
-        $this->_localConfigFile = Mage::getBaseDir('etc') . DS . 'local.xml';
     }
 
     public function setConfigData($data)
@@ -71,10 +90,20 @@ class Mage_Install_Model_Installer_Config extends Mage_Install_Model_Installer_A
         return $this->_configData;
     }
 
+    /**
+     * Generate installation data and record them into local.xml using local.xml.template
+     */
     public function install()
     {
         $data = $this->getConfigData();
-        foreach (Mage::getModel('Mage_Core_Model_Config')->getDistroServerVars() as $index=>$value) {
+
+        $defaults = array(
+            'root_dir' => $this->_dirs->getDir(Mage_Core_Model_Dir::ROOT),
+            'app_dir'  => $this->_dirs->getDir(Mage_Core_Model_Dir::APP),
+            'var_dir'  => $this->_dirs->getDir(Mage_Core_Model_Dir::VAR_DIR),
+            'base_url' => $this->_config->getDistroBaseUrl(),
+        );
+        foreach ($defaults as $index => $value) {
             if (!isset($data[$index])) {
                 $data[$index] = $value;
             }
@@ -109,11 +138,13 @@ class Mage_Install_Model_Installer_Config extends Mage_Install_Model_Installer_A
 
         $this->_getInstaller()->getDataModel()->setConfigData($data);
 
-        $template = $this->_filesystem->read(Mage::getBaseDir('etc') . DS . 'local.xml.template');
+        $path = $this->_dirs->getDir(Mage_Core_Model_Dir::CONFIG) . DIRECTORY_SEPARATOR . 'local.xml.template';
+        $contents = $this->_filesystem->read($path);
         foreach ($data as $index => $value) {
-            $template = str_replace('{{' . $index . '}}', '<![CDATA[' . $value . ']]>', $template);
+            $contents = str_replace('{{' . $index . '}}', '<![CDATA[' . $value . ']]>', $contents);
         }
-        $this->_filesystem->write($this->_localConfigFile, $template);
+
+        $this->_filesystem->write($this->_localConfigFile, $contents);
         $this->_filesystem->changePermissions($this->_localConfigFile, 0777);
     }
 
@@ -129,7 +160,7 @@ class Mage_Install_Model_Installer_Config extends Mage_Install_Model_Installer_A
             $baseSecureUrl = $uri->getUri();
         }
 
-        $connectDefault = Mage::getConfig()
+        $connectDefault = $this->_config
                 ->getResourceConnectionConfig(Mage_Core_Model_Resource::DEFAULT_SETUP_RESOURCE);
 
         $data = new Varien_Object();
@@ -146,39 +177,65 @@ class Mage_Install_Model_Installer_Config extends Mage_Install_Model_Installer_A
         return $data;
     }
 
-    protected function _checkHostsInfo($data)
-    {
-        $url  = $data['protocol'] . '://' . $data['host'] . ':' . $data['port'] . $data['base_path'];
-        $surl = $data['secure_protocol'] . '://' . $data['secure_host'] . ':' . $data['secure_port']
-            . $data['secure_base_path'];
-
-        $this->_checkUrl($url);
-        $this->_checkUrl($surl, true);
-
-        return $this;
-    }
-
-    protected function _checkUrl($url, $secure = false)
+    /**
+     * Check validity of a base URL
+     *
+     * @param string $baseUrl
+     * @throws Exception
+     */
+    protected function _checkUrl($baseUrl)
     {
-        $prefix = $secure ? 'install/wizard/checkSecureHost/' : 'install/wizard/checkHost/';
         try {
-            $client = new Varien_Http_Client($url . 'index.php/' . $prefix);
+            $pubLibDir = $this->_dirs->getDir(Mage_Core_Model_Dir::PUB_LIB);
+            $staticFile = $this->_findFirstFileRelativePath($pubLibDir, '/.+\.(html?|js|css|gif|jpe?g|png)$/');
+            $staticUrl = $baseUrl . $this->_dirs->getUri(Mage_Core_Model_Dir::PUB_LIB) . '/' . $staticFile;
+            $client = new Varien_Http_Client($staticUrl);
             $response = $client->request('GET');
-            /* @var $responce Zend_Http_Response */
-            $body = $response->getBody();
         }
         catch (Exception $e){
-            $this->_getInstaller()->getDataModel()
-                ->addError(Mage::helper('Mage_Install_Helper_Data')->__('The URL "%s" is not accessible.', $url));
+            $this->_getInstaller()->getDataModel()->addError(
+                Mage::helper('Mage_Install_Helper_Data')->__('The URL "%s" is not accessible.', $baseUrl)
+            );
             throw $e;
         }
+        if ($response->getStatus() != 200) {
+            $this->_getInstaller()->getDataModel()->addError(
+                Mage::helper('Mage_Install_Helper_Data')->__('The URL "%s" is invalid.', $baseUrl)
+            );
+            Mage::throwException(Mage::helper('Mage_Install_Helper_Data')->__('Response from the server is invalid.'));
+        }
+    }
 
-        if ($body != Mage_Install_Model_Installer::INSTALLER_HOST_RESPONSE) {
-            $this->_getInstaller()->getDataModel()
-                ->addError(Mage::helper('Mage_Install_Helper_Data')->__('The URL "%s" is invalid.', $url));
-            Mage::throwException(Mage::helper('Mage_Install_Helper_Data')->__('Response from server isn\'t valid.'));
+    /**
+     * Find a relative path to a first file located in a directory or its descendants
+     *
+     * @param string $dir Directory to search for a file within
+     * @param string $pattern PCRE pattern a file name has to match
+     * @return string|null
+     */
+    protected function _findFirstFileRelativePath($dir, $pattern = '/.*/')
+    {
+        $childDirs = array();
+        foreach (scandir($dir) as $itemName) {
+            if ($itemName == '.' || $itemName == '..') {
+                continue;
+            }
+            $itemPath = $dir . DIRECTORY_SEPARATOR . $itemName;
+            if (is_file($itemPath)) {
+                if (preg_match($pattern, $itemName)) {
+                    return $itemName;
+                }
+            } else {
+                $childDirs[$itemName] = $itemPath;
+            }
         }
-        return $this;
+        foreach ($childDirs as $dirName => $dirPath) {
+            $filePath = $this->_findFirstFileRelativePath($dirPath, $pattern);
+            if ($filePath) {
+                return $dirName . '/' . $filePath;
+            }
+        }
+        return null;
     }
 
     public function replaceTmpInstallDate($date = null)
diff --git a/app/code/core/Mage/Install/Model/Installer/Console.php b/app/code/core/Mage/Install/Model/Installer/Console.php
index 914195803d1..d8de080187c 100644
--- a/app/code/core/Mage/Install/Model/Installer/Console.php
+++ b/app/code/core/Mage/Install/Model/Installer/Console.php
@@ -29,6 +29,13 @@
  */
 class Mage_Install_Model_Installer_Console extends Mage_Install_Model_Installer_Abstract
 {
+    /**#@+
+     * Installation options for application initialization
+     */
+    const OPTION_URIS = 'install_option_uris';
+    const OPTION_DIRS = 'install_option_dirs';
+    /**#@- */
+
     /**
      * Available installation options
      *
@@ -65,6 +72,11 @@ class Mage_Install_Model_Installer_Console extends Mage_Install_Model_Installer_
         'cleanup_database'           => array('required' => 0),
     );
 
+    /**
+     * @var Magento_Filesystem
+     */
+    protected $_filesystem;
+
     /**
      * Installer data model to store data between installations steps
      *
@@ -73,22 +85,37 @@ class Mage_Install_Model_Installer_Console extends Mage_Install_Model_Installer_
     protected $_dataModel;
 
     /**
-     * @var Magento_Filesystem
-     */
-    protected $_filesystem;
-
-    /**
-     * Constructor
+     * Initialize application and "data model"
      *
      * @param Magento_Filesystem $filesystem
+     * @param array $installArgs
      */
-    public function __construct(Magento_Filesystem $filesystem)
+    public function __construct(Magento_Filesystem $filesystem, array $installArgs)
     {
-        Mage::app();
         $this->_filesystem = $filesystem;
+        $params = $this->_buildInitParams($installArgs);
+        Mage::app($params);
         $this->_getInstaller()->setDataModel($this->_getDataModel());
     }
 
+    /**
+     * Customize application init parameters
+     *
+     * @param array $args
+     * @return array
+     */
+    protected function _buildInitParams(array $args)
+    {
+        $result = array();
+        if (!empty($args[self::OPTION_URIS])) {
+            $result[Mage_Core_Model_App::INIT_OPTION_URIS] = unserialize(base64_decode($args[self::OPTION_URIS]));
+        }
+        if (!empty($args[self::OPTION_DIRS])) {
+            $result[Mage_Core_Model_App::INIT_OPTION_DIRS] = unserialize(base64_decode($args[self::OPTION_DIRS]));
+        }
+        return $result;
+    }
+
     /**
      * Retrieve validated installation options
      *
@@ -388,21 +415,11 @@ class Mage_Install_Model_Installer_Console extends Mage_Install_Model_Installer_
 
         $this->_cleanUpDatabase();
 
-        /* Remove temporary directories */
-        $configOptions = Mage::app()->getConfig()->getOptions();
-        $dirsToRemove = array(
-            $configOptions->getCacheDir(),
-            $configOptions->getSessionDir(),
-            $configOptions->getExportDir(),
-            $configOptions->getLogDir(),
-            $configOptions->getVarDir() . '/report',
-        );
-        foreach ($dirsToRemove as $dir) {
+        /* Remove temporary directories and local.xml */
+        foreach (glob(Mage::getBaseDir(Mage_Core_Model_Dir::VAR_DIR) . '/*', GLOB_ONLYDIR) as $dir) {
             $this->_filesystem->delete($dir);
         }
-
-        /* Remove local configuration */
-        $this->_filesystem->delete($configOptions->getEtcDir() . '/local.xml');
+        $this->_filesystem->delete(Mage::getBaseDir(Mage_Core_Model_Dir::CONFIG) . DIRECTORY_SEPARATOR . '/local.xml');
         return true;
     }
 
diff --git a/app/code/core/Mage/Install/controllers/IndexController.php b/app/code/core/Mage/Install/controllers/IndexController.php
index 9d908286988..6ed3afd47d2 100644
--- a/app/code/core/Mage/Install/controllers/IndexController.php
+++ b/app/code/core/Mage/Install/controllers/IndexController.php
@@ -44,7 +44,9 @@ class Mage_Install_IndexController extends Mage_Install_Controller_Action
     {
         $this->setFlag('', self::FLAG_NO_CHECK_INSTALLATION, true);
         if (!Mage::isInstalled()) {
-            Mage::helper('Mage_Install_Helper_Data')->cleanVarFolder();
+            foreach (glob(Mage::getBaseDir(Mage_Core_Model_Dir::VAR_DIR) . '/*', GLOB_ONLYDIR) as $dir) {
+                Varien_Io_File::rmdirRecursive($dir);
+            }
         }
         return parent::preDispatch();
     }
diff --git a/app/code/core/Mage/Install/controllers/WizardController.php b/app/code/core/Mage/Install/controllers/WizardController.php
index c37edd15ce2..6b030c247e0 100644
--- a/app/code/core/Mage/Install/controllers/WizardController.php
+++ b/app/code/core/Mage/Install/controllers/WizardController.php
@@ -466,22 +466,4 @@ class Mage_Install_WizardController extends Mage_Install_Controller_Action
         $this->renderLayout();
         Mage::getSingleton('Mage_Install_Model_Session')->clear();
     }
-
-    /**
-     * Host validation response
-     */
-    public function checkHostAction()
-    {
-        $this->getResponse()->setHeader('Transfer-encoding', '', true);
-        $this->getResponse()->setBody(Mage_Install_Model_Installer::INSTALLER_HOST_RESPONSE);
-    }
-
-    /**
-     * Host validation response
-     */
-    public function checkSecureHostAction()
-    {
-        $this->getResponse()->setHeader('Transfer-encoding', '', true);
-        $this->getResponse()->setBody(Mage_Install_Model_Installer::INSTALLER_HOST_RESPONSE);
-    }
 }
diff --git a/app/code/core/Mage/Install/etc/install.xml b/app/code/core/Mage/Install/etc/install.xml
index d00dadf8abf..214572d9dcb 100644
--- a/app/code/core/Mage/Install/etc/install.xml
+++ b/app/code/core/Mage/Install/etc/install.xml
@@ -58,26 +58,18 @@
     <check>
         <filesystem>
             <writeable>
-                <app_etc>
-                    <path>/app/etc</path>
+                <etc>
                     <existence>1</existence>
                     <recursive>0</recursive>
-                </app_etc>
+                </etc>
                 <var>
-                    <path>/var</path>
                     <existence>1</existence>
                     <recursive>1</recursive>
                 </var>
                 <media>
-                    <path>/pub/media</path>
                     <existence>1</existence>
                     <recursive>1</recursive>
                 </media>
-                <theme>
-                    <path>/pub/media/theme</path>
-                    <existence>0</existence>
-                    <recursive>0</recursive>
-                </theme>
             </writeable>
         </filesystem>
         <php>
diff --git a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/Admin/TokenController.php b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/Admin/TokenController.php
index 4ed93a7bdbd..708c1d33b02 100644
--- a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/Admin/TokenController.php
+++ b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/Admin/TokenController.php
@@ -43,7 +43,7 @@ class Mage_Oauth_Adminhtml_Oauth_Admin_TokenController extends Mage_Adminhtml_Co
     protected function  _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('Mage_Oauth::system_api_oauth_admin_token');
+            ->_setActiveMenu('Mage_Oauth::system_legacy_api_oauth_admin_token');
         return $this;
     }
 
diff --git a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/AuthorizedTokensController.php b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/AuthorizedTokensController.php
index f3969e89c1a..695971337b8 100644
--- a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/AuthorizedTokensController.php
+++ b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/AuthorizedTokensController.php
@@ -52,7 +52,7 @@ class Mage_Oauth_Adminhtml_Oauth_AuthorizedTokensController extends Mage_Adminht
      */
     public function indexAction()
     {
-        $this->loadLayout()->_setActiveMenu('Mage_Oauth::system_api_oauth_authorized_tokens');
+        $this->loadLayout()->_setActiveMenu('Mage_Oauth::system_legacy_api_oauth_authorized_tokens');
         $this->renderLayout();
     }
 
diff --git a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/ConsumerController.php b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/ConsumerController.php
index 00dc3bf625e..05d5871fc53 100644
--- a/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/ConsumerController.php
+++ b/app/code/core/Mage/Oauth/controllers/Adminhtml/Oauth/ConsumerController.php
@@ -41,7 +41,7 @@ class Mage_Oauth_Adminhtml_Oauth_ConsumerController extends Mage_Adminhtml_Contr
     protected function  _initAction()
     {
         $this->loadLayout()
-            ->_setActiveMenu('Mage_Oauth::system_api_oauth_consumer');
+            ->_setActiveMenu('Mage_Oauth::system_legacy_api_oauth_consumer');
         return $this;
     }
     /**
diff --git a/app/code/core/Mage/Oauth/etc/adminhtml/menu.xml b/app/code/core/Mage/Oauth/etc/adminhtml/menu.xml
index 8e21aa0cda0..36e3543c40a 100644
--- a/app/code/core/Mage/Oauth/etc/adminhtml/menu.xml
+++ b/app/code/core/Mage/Oauth/etc/adminhtml/menu.xml
@@ -28,8 +28,14 @@
 <config>
     <menu>
         <!-- Menu elements has been disabled untill 3-legged oAuth functionality is needed. -->
-        <!--<add id="Mage_Oauth::system_api_oauth_consumer" title="REST - OAuth Consumers" module="Mage_Oauth" sortOrder="50" parent="Mage_Api::system_api" action="adminhtml/oauth_consumer" resource="Mage_Oauth::consumer"/>-->
-        <!--<add id="Mage_Oauth::system_api_oauth_authorized_tokens" title="REST - OAuth Authorized Tokens" module="Mage_Oauth" sortOrder="60" parent="Mage_Api::system_api" action="adminhtml/oauth_authorizedTokens" resource="Mage_Oauth::authorizedTokens"/>-->
-        <!--<add id="Mage_Oauth::system_api_oauth_admin_token" title="REST - My Apps" module="Mage_Oauth" sortOrder="70" parent="Mage_Api::system_api" action="adminhtml/oauth_admin_token" resource="Mage_Oauth::oauth_admin_token"/>-->
+        <!--<add id="Mage_Oauth::system_legacy_api_oauth_consumer" title="REST - OAuth Consumers"-->
+             <!--module="Mage_Oauth" sortOrder="50" parent="Mage_Api::system_legacy_api"-->
+             <!--action="adminhtml/oauth_consumer" resource="Mage_Oauth::consumer"/>-->
+        <!--<add id="Mage_Oauth::system_legacy_api_oauth_authorized_tokens" title="REST - OAuth Authorized Tokens"-->
+             <!--module="Mage_Oauth" sortOrder="60" parent="Mage_Api::system_legacy_api"-->
+             <!--action="adminhtml/oauth_authorizedTokens" resource="Mage_Oauth::authorizedTokens"/>-->
+        <!--<add id="Mage_Oauth::system_legacy_api_oauth_admin_token" title="REST - My Apps" module="Mage_Oauth"-->
+             <!--sortOrder="70" parent="Mage_Api::system_legacy_api" action="adminhtml/oauth_admin_token"-->
+             <!--resource="Mage_Oauth::oauth_admin_token"/>-->
     </menu>
 </config>
diff --git a/app/code/core/Mage/Page/Block/Html.php b/app/code/core/Mage/Page/Block/Html.php
index 169ab5552bb..a81d1ee4f89 100644
--- a/app/code/core/Mage/Page/Block/Html.php
+++ b/app/code/core/Mage/Page/Block/Html.php
@@ -72,7 +72,7 @@ class Mage_Page_Block_Html extends Mage_Core_Block_Template
     /**
      *  Print Logo URL (Conf -> Sales -> Invoice and Packing Slip Design)
      *
-     *  @return	  string
+     *  @return string
      */
     public function getPrintLogoUrl ()
     {
@@ -98,7 +98,7 @@ class Mage_Page_Block_Html extends Mage_Core_Block_Template
 
         // buld url
         if (!empty($logo)) {
-            $logo = $this->_storeConfig->getConfig('web/unsecure/base_media_url') . $logo;
+            $logo = $this->_urlBuilder->getBaseUrl(array('_type' => Mage_Core_Model_Store::URL_TYPE_MEDIA)) . $logo;
         }
         else {
             $logo = '';
diff --git a/app/code/core/Mage/Page/Block/Html/Header.php b/app/code/core/Mage/Page/Block/Html/Header.php
index a89d872ed6c..79da788a4f6 100644
--- a/app/code/core/Mage/Page/Block/Html/Header.php
+++ b/app/code/core/Mage/Page/Block/Html/Header.php
@@ -33,63 +33,6 @@
  */
 class Mage_Page_Block_Html_Header extends Mage_Core_Block_Template
 {
-    /**
-     * @var Mage_Core_Model_Config_Options
-     */
-    protected $_configOptions;
-
-    /**
-     * @param Mage_Core_Controller_Request_Http $request
-     * @param Mage_Core_Model_Layout $layout
-     * @param Mage_Core_Model_Event_Manager $eventManager
-     * @param Mage_Core_Model_Url $urlBuilder
-     * @param Mage_Core_Model_Translate $translator
-     * @param Mage_Core_Model_Cache $cache
-     * @param Mage_Core_Model_Design_Package $designPackage
-     * @param Mage_Core_Model_Session $session
-     * @param Mage_Core_Model_Store_Config $storeConfig
-     * @param Mage_Core_Controller_Varien_Front $frontController
-     * @param Mage_Core_Model_Factory_Helper $helperFactory
-     * @param Magento_Filesystem $filesystem
-     * @param Mage_Core_Model_Config_Options $configOptions
-     * @param array $data
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        Mage_Core_Controller_Request_Http $request,
-        Mage_Core_Model_Layout $layout,
-        Mage_Core_Model_Event_Manager $eventManager,
-        Mage_Core_Model_Url $urlBuilder,
-        Mage_Core_Model_Translate $translator,
-        Mage_Core_Model_Cache $cache,
-        Mage_Core_Model_Design_Package $designPackage,
-        Mage_Core_Model_Session $session,
-        Mage_Core_Model_Store_Config $storeConfig,
-        Mage_Core_Controller_Varien_Front $frontController,
-        Mage_Core_Model_Factory_Helper $helperFactory,
-        Magento_Filesystem $filesystem,
-        Mage_Core_Model_Config_Options $configOptions,
-        array $data = array()
-    ) {
-        parent::__construct(
-            $request,
-            $layout,
-            $eventManager,
-            $urlBuilder,
-            $translator,
-            $cache,
-            $designPackage,
-            $session,
-            $storeConfig,
-            $frontController,
-            $helperFactory,
-            $filesystem,
-            $data
-        );
-        $this->_configOptions = $configOptions;
-    }
-
     public function _construct()
     {
         $this->setTemplate('html/header.phtml');
@@ -157,7 +100,7 @@ class Mage_Page_Block_Html_Header extends Mage_Core_Block_Template
         $storeLogoPath = $this->_storeConfig->getConfig('design/header/logo_src');
         $logoUrl = $this->_urlBuilder->getBaseUrl(array('_type' => Mage_Core_Model_Store::URL_TYPE_MEDIA))
             . $folderName . '/' . $storeLogoPath;
-        $absolutePath = $this->_configOptions->getDir('media') . DIRECTORY_SEPARATOR
+        $absolutePath = $this->_dirs->getDir(Mage_Core_Model_Dir::MEDIA) . DIRECTORY_SEPARATOR
             . $folderName . DIRECTORY_SEPARATOR . $storeLogoPath;
 
         if (!is_null($storeLogoPath) && $this->_isFile($absolutePath)) {
diff --git a/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Global.php b/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Global.php
index 3e7bab145dd..f2ed6c4c2fb 100644
--- a/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Global.php
+++ b/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Global.php
@@ -29,7 +29,7 @@
  * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Mage_Paypal_Block_Adminhtml_System_Config_Fieldset_Global
-    extends Mage_Adminhtml_Block_Abstract
+    extends Mage_Core_Block_Template
     implements Varien_Data_Form_Element_Renderer_Interface
 {
     /**
diff --git a/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Hint.php b/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Hint.php
index d028b185ce0..ce0ab92157d 100644
--- a/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Hint.php
+++ b/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Hint.php
@@ -30,7 +30,7 @@
  * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Mage_Paypal_Block_Adminhtml_System_Config_Fieldset_Hint
-    extends Mage_Adminhtml_Block_Abstract
+    extends Mage_Core_Block_Template
     implements Varien_Data_Form_Element_Renderer_Interface
 {
     protected $_template = 'Mage_Paypal::system/config/fieldset/hint.phtml';
diff --git a/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Store.php b/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Store.php
index 78d86906d7e..f2b861e70e3 100644
--- a/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Store.php
+++ b/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Fieldset/Store.php
@@ -30,7 +30,7 @@
  * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Mage_Paypal_Block_Adminhtml_System_Config_Fieldset_Store
-    extends Mage_Adminhtml_Block_Abstract
+    extends Mage_Core_Block_Template
     implements Varien_Data_Form_Element_Renderer_Interface
 {
     /**
diff --git a/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Payflowlink/Info.php b/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Payflowlink/Info.php
index 9655fcfe5dc..4bc68dc0f74 100644
--- a/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Payflowlink/Info.php
+++ b/app/code/core/Mage/Paypal/Block/Adminhtml/System/Config/Payflowlink/Info.php
@@ -31,8 +31,8 @@
  * @package    Mage_Paypal
  * @author     Magento Core Team <core@magentocommerce.com>
  */
- class Mage_Paypal_Block_Adminhtml_System_Config_Payflowlink_Info
-    extends Mage_Adminhtml_Block_Abstract
+class Mage_Paypal_Block_Adminhtml_System_Config_Payflowlink_Info
+    extends Mage_Core_Block_Template
     implements Varien_Data_Form_Element_Renderer_Interface
 {
     /**
diff --git a/app/code/core/Mage/Paypal/Model/Observer.php b/app/code/core/Mage/Paypal/Model/Observer.php
index f0dff830307..1ba306ce5d3 100644
--- a/app/code/core/Mage/Paypal/Model/Observer.php
+++ b/app/code/core/Mage/Paypal/Model/Observer.php
@@ -44,7 +44,7 @@ class Mage_Paypal_Model_Observer
             $credentials = $reports->getSftpCredentials(true);
             foreach ($credentials as $config) {
                 try {
-                    $reports->fetchAndSave($config);
+                    $reports->fetchAndSave(Mage_Paypal_Model_Report_Settlement::createConnection($config));
                 } catch (Exception $e) {
                     Mage::logException($e);
                 }
diff --git a/app/code/core/Mage/Paypal/Model/Report/Settlement.php b/app/code/core/Mage/Paypal/Model/Report/Settlement.php
index 4a4fba8c499..37d94043d39 100644
--- a/app/code/core/Mage/Paypal/Model/Report/Settlement.php
+++ b/app/code/core/Mage/Paypal/Model/Report/Settlement.php
@@ -194,22 +194,15 @@ class Mage_Paypal_Model_Report_Settlement extends Mage_Core_Model_Abstract
      * Goes to specified host/path and fetches reports from there.
      * Save reports to database.
      *
-     * @param array $config SFTP credentials
+     * @param Varien_Io_Sftp $connection
      * @return int Number of report rows that were fetched and saved successfully
      */
-    public function fetchAndSave($config)
+    public function fetchAndSave(Varien_Io_Sftp $connection)
     {
-        $connection = new Varien_Io_Sftp();
-        $connection->open(array(
-            'host'     => $config['hostname'],
-            'username' => $config['username'],
-            'password' => $config['password']
-        ));
-        $connection->cd($config['path']);
         $fetched = 0;
         $listing = $this->_filterReportsList($connection->rawls());
         foreach ($listing as $filename => $attributes) {
-            $localCsv = tempnam(Mage::getConfig()->getOptions()->getTmpDir(), 'PayPal_STL');
+            $localCsv = tempnam(Mage::getBaseDir(Mage_Core_Model_Dir::TMP), 'PayPal_STL');
             if ($connection->read($filename, $localCsv)) {
                 if (!is_writable($localCsv)) {
                     Mage::throwException(Mage::helper('Mage_Paypal_Helper_Data')->__('Cannot create target file for reading reports.'));
@@ -248,6 +241,30 @@ class Mage_Paypal_Model_Report_Settlement extends Mage_Core_Model_Abstract
         return $fetched;
     }
 
+    /**
+     * Connect to an SFTP server using specified configuration
+     *
+     * @param array $config
+     * @return Varien_Io_Sftp
+     * @throws InvalidArgumentException
+     */
+    public static function createConnection(array $config)
+    {
+        if (!isset($config['hostname']) || !isset($config['username'])
+            || !isset($config['password']) || !isset($config['path'])
+        ) {
+            throw new InvalidArgumentException('Required config elements: hostname, username, password, path');
+        }
+        $connection = new Varien_Io_Sftp();
+        $connection->open(array(
+            'host'     => $config['hostname'],
+            'username' => $config['username'],
+            'password' => $config['password']
+        ));
+        $connection->cd($config['path']);
+        return $connection;
+    }
+
     /**
      * Parse CSV file and collect report rows
      *
diff --git a/app/code/core/Mage/Paypal/controllers/Adminhtml/Paypal/ReportsController.php b/app/code/core/Mage/Paypal/controllers/Adminhtml/Paypal/ReportsController.php
index 781eb544955..188f8eec750 100644
--- a/app/code/core/Mage/Paypal/controllers/Adminhtml/Paypal/ReportsController.php
+++ b/app/code/core/Mage/Paypal/controllers/Adminhtml/Paypal/ReportsController.php
@@ -88,7 +88,7 @@ class Mage_Paypal_Adminhtml_Paypal_ReportsController extends Mage_Adminhtml_Cont
             }
             foreach ($credentials as $config) {
                 try {
-                    $fetched = $reports->fetchAndSave($config);
+                    $fetched = $reports->fetchAndSave(Mage_Paypal_Model_Report_Settlement::createConnection($config));
                     $this->_getSession()->addSuccess(
                         Mage::helper('Mage_Paypal_Helper_Data')->__("Fetched %s report rows from '%s@%s'.", $fetched, $config['username'], $config['hostname'])
                     );
diff --git a/app/code/core/Mage/Sales/Block/Adminhtml/Billing/Agreement/View/Tab/Info.php b/app/code/core/Mage/Sales/Block/Adminhtml/Billing/Agreement/View/Tab/Info.php
index 3088de94da1..bb35772e503 100644
--- a/app/code/core/Mage/Sales/Block/Adminhtml/Billing/Agreement/View/Tab/Info.php
+++ b/app/code/core/Mage/Sales/Block/Adminhtml/Billing/Agreement/View/Tab/Info.php
@@ -29,7 +29,7 @@
  *
  * @author Magento Core Team <core@magentocommerce.com>
  */
-class Mage_Sales_Block_Adminhtml_Billing_Agreement_View_Tab_Info extends Mage_Backend_Block_Abstract
+class Mage_Sales_Block_Adminhtml_Billing_Agreement_View_Tab_Info extends Mage_Core_Block_Template
     implements Mage_Backend_Block_Widget_Tab_Interface
 {
     protected $_template = 'billing/agreement/view/tab/info.phtml';
diff --git a/app/code/core/Mage/Sales/Block/Adminhtml/Recurring/Profile/Edit/Form.php b/app/code/core/Mage/Sales/Block/Adminhtml/Recurring/Profile/Edit/Form.php
index 5c6bda09b29..9647d2b8a60 100644
--- a/app/code/core/Mage/Sales/Block/Adminhtml/Recurring/Profile/Edit/Form.php
+++ b/app/code/core/Mage/Sales/Block/Adminhtml/Recurring/Profile/Edit/Form.php
@@ -28,7 +28,7 @@
  * Recurring profile editing form
  * Can work in scope of product edit form
  */
-class Mage_Sales_Block_Adminhtml_Recurring_Profile_Edit_Form extends Mage_Adminhtml_Block_Abstract
+class Mage_Sales_Block_Adminhtml_Recurring_Profile_Edit_Form extends Mage_Core_Block_Template
 {
     /**
      * Reference to the parent element (optional)
diff --git a/app/code/core/Mage/Sales/Model/Api/Resource.php b/app/code/core/Mage/Sales/Model/Api/Resource.php
new file mode 100644
index 00000000000..179e32f8352
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Api/Resource.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.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Sale api resource abstract
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Api_Resource extends Mage_Api_Model_Resource_Abstract
+{
+    /**
+     * Default ignored attribute codes per entity type
+     *
+     * @var array
+     */
+    protected $_ignoredAttributeCodes = array(
+        'global'    =>  array('entity_id', 'attribute_set_id', 'entity_type_id')
+    );
+
+    /**
+     * Attributes map array per entity type
+     *
+     * @var google
+     */
+    protected $_attributesMap = array(
+        'global'    => array()
+    );
+
+    /** @var Mage_Api_Helper_Data */
+    protected $_apiHelper;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param Mage_Api_Helper_Data $apiHelper
+     */
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        $this->_apiHelper = $apiHelper;
+    }
+
+    /**
+     * Update attributes for entity
+     *
+     * @param array $data
+     * @param Mage_Core_Model_Abstract $object
+     * @param array $attributes
+     * @return Mage_Sales_Model_Api_Resource
+     */
+    protected function _updateAttributes($data, $object, $type,  array $attributes = null)
+    {
+
+        foreach ($data as $attribute=>$value) {
+            if ($this->_apiHelper->isAttributeAllowed($attribute, $type, $this->_ignoredAttributeCodes, $attributes)) {
+                $object->setData($attribute, $value);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Retrieve entity attributes values
+     *
+     * @param Mage_Core_Model_Abstract $object
+     * @param array $attributes
+     * @return Mage_Sales_Model_Api_Resource
+     */
+    protected function _getAttributes($object, $type, array $attributes = null)
+    {
+        $result = array();
+
+        if (!is_object($object)) {
+            return $result;
+        }
+
+        foreach ($object->getData() as $attribute=>$value) {
+            if ($this->_apiHelper->isAttributeAllowed($attribute, $type, $this->_ignoredAttributeCodes, $attributes)) {
+                $result[$attribute] = $value;
+            }
+        }
+
+        if (isset($this->_attributesMap['global'])) {
+            foreach ($this->_attributesMap['global'] as $alias=>$attributeCode) {
+                $result[$alias] = $object->getData($attributeCode);
+            }
+        }
+
+        if (isset($this->_attributesMap[$type])) {
+            foreach ($this->_attributesMap[$type] as $alias=>$attributeCode) {
+                $result[$alias] = $object->getData($attributeCode);
+            }
+        }
+
+        return $result;
+    }
+} // Class Mage_Sales_Model_Api_Resource End
diff --git a/app/code/core/Mage/Sales/Model/Order.php b/app/code/core/Mage/Sales/Model/Order.php
index 6867c42c4c5..a06cf603819 100644
--- a/app/code/core/Mage/Sales/Model/Order.php
+++ b/app/code/core/Mage/Sales/Model/Order.php
@@ -1833,7 +1833,7 @@ class Mage_Sales_Model_Order extends Mage_Sales_Model_Abstract
     /**
      * Retrieve order invoices collection
      *
-     * @return unknown
+     * @return Mage_Sales_Model_Resource_Order_Invoice_Collection
      */
     public function getInvoiceCollection()
     {
@@ -1850,10 +1850,10 @@ class Mage_Sales_Model_Order extends Mage_Sales_Model_Abstract
         return $this->_invoices;
     }
 
-     /**
+    /**
      * Retrieve order shipments collection
      *
-     * @return unknown
+     * @return Mage_Sales_Model_Resource_Order_Shipment_Collection|bool
      */
     public function getShipmentsCollection()
     {
@@ -1872,7 +1872,7 @@ class Mage_Sales_Model_Order extends Mage_Sales_Model_Abstract
     /**
      * Retrieve order creditmemos collection
      *
-     * @return unknown
+     * @return Mage_Sales_Model_Resource_Order_Creditmemo_Collection|bool
      */
     public function getCreditmemosCollection()
     {
@@ -1891,7 +1891,7 @@ class Mage_Sales_Model_Order extends Mage_Sales_Model_Abstract
     /**
      * Retrieve order tracking numbers collection
      *
-     * @return unknown
+     * @return Mage_Sales_Model_Resource_Order_Shipment_Track_Collection
      */
     public function getTracksCollection()
     {
diff --git a/app/code/core/Mage/Sales/Model/Order/Api.php b/app/code/core/Mage/Sales/Model/Order/Api.php
new file mode 100644
index 00000000000..318a0f94ce1
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Order/Api.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.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Order API
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Order_Api extends Mage_Sales_Model_Api_Resource
+{
+    /**
+     * Initialize attributes map
+     */
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        parent::__construct($apiHelper);
+        $this->_attributesMap = array(
+            'order' => array('order_id' => 'entity_id'),
+            'order_address' => array('address_id' => 'entity_id'),
+            'order_payment' => array('payment_id' => 'entity_id')
+        );
+    }
+
+    /**
+     * Initialize basic order model
+     *
+     * @param mixed $orderIncrementId
+     * @return Mage_Sales_Model_Order
+     */
+    protected function _initOrder($orderIncrementId)
+    {
+        $order = Mage::getModel('Mage_Sales_Model_Order');
+
+        /* @var $order Mage_Sales_Model_Order */
+
+        $order->loadByIncrementId($orderIncrementId);
+
+        if (!$order->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        return $order;
+    }
+
+    /**
+     * Retrieve list of orders. Filtration could be applied
+     *
+     * @param null|object|array $filters
+     * @return array
+     */
+    public function items($filters = null)
+    {
+        $orders = array();
+
+        //TODO: add full name logic
+        $billingAliasName = 'billing_o_a';
+        $shippingAliasName = 'shipping_o_a';
+
+        /** @var $orderCollection Mage_Sales_Model_Resource_Order_Collection */
+        $orderCollection = Mage::getModel('Mage_Sales_Model_Order')->getCollection();
+        $billingFirstnameField = "$billingAliasName.firstname";
+        $billingLastnameField = "$billingAliasName.lastname";
+        $shippingFirstnameField = "$shippingAliasName.firstname";
+        $shippingLastnameField = "$shippingAliasName.lastname";
+        $billingNameExpr = "CONCAT({{billing_firstname}}, CONCAT(' ', {{billing_lastname}}))";
+        $shippingNameExpr = "CONCAT({{shipping_firstname}}, CONCAT(' ', {{shipping_lastname}}))";
+        $orderCollection->addAttributeToSelect('*')
+            ->addAddressFields()
+            ->addExpressionFieldToSelect('billing_firstname', "{{billing_firstname}}",
+                array('billing_firstname' => $billingFirstnameField))
+            ->addExpressionFieldToSelect('billing_lastname', "{{billing_lastname}}",
+                array('billing_lastname' => $billingLastnameField))
+            ->addExpressionFieldToSelect('shipping_firstname', "{{shipping_firstname}}",
+                array('shipping_firstname' => $shippingFirstnameField))
+            ->addExpressionFieldToSelect('shipping_lastname', "{{shipping_lastname}}",
+                array('shipping_lastname' => $shippingLastnameField))
+            ->addExpressionFieldToSelect('billing_name', $billingNameExpr,
+                array('billing_firstname' => $billingFirstnameField, 'billing_lastname' => $billingLastnameField))
+            ->addExpressionFieldToSelect('shipping_name', $shippingNameExpr,
+                array('shipping_firstname' => $shippingFirstnameField, 'shipping_lastname' => $shippingLastnameField)
+        );
+
+        /** @var $apiHelper Mage_Api_Helper_Data */
+        $apiHelper = Mage::helper('Mage_Api_Helper_Data');
+        $filters = $apiHelper->parseFilters($filters, $this->_attributesMap['order']);
+        try {
+            foreach ($filters as $field => $value) {
+                $orderCollection->addFieldToFilter($field, $value);
+            }
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('filters_invalid', $e->getMessage());
+        }
+        foreach ($orderCollection as $order) {
+            $orders[] = $this->_getAttributes($order, 'order');
+        }
+        return $orders;
+    }
+
+    /**
+     * Retrieve full order information
+     *
+     * @param string $orderIncrementId
+     * @return array
+     */
+    public function info($orderIncrementId)
+    {
+        $order = $this->_initOrder($orderIncrementId);
+
+        if ($order->getGiftMessageId() > 0) {
+            $order->setGiftMessage(
+                Mage::getSingleton('Mage_GiftMessage_Model_Message')->load($order->getGiftMessageId())->getMessage()
+            );
+        }
+
+        $result = $this->_getAttributes($order, 'order');
+
+        $result['shipping_address'] = $this->_getAttributes($order->getShippingAddress(), 'order_address');
+        $result['billing_address']  = $this->_getAttributes($order->getBillingAddress(), 'order_address');
+        $result['items'] = array();
+
+        foreach ($order->getAllItems() as $item) {
+            if ($item->getGiftMessageId() > 0) {
+                $item->setGiftMessage(
+                    Mage::getSingleton('Mage_GiftMessage_Model_Message')->load($item->getGiftMessageId())->getMessage()
+                );
+            }
+
+            $result['items'][] = $this->_getAttributes($item, 'order_item');
+        }
+
+        $result['payment'] = $this->_getAttributes($order->getPayment(), 'order_payment');
+
+        $result['status_history'] = array();
+
+        foreach ($order->getAllStatusHistory() as $history) {
+            $result['status_history'][] = $this->_getAttributes($history, 'order_status_history');
+        }
+
+        return $result;
+    }
+
+    /**
+     * Change order status and optionally log status change with comment.
+     *
+     * @param string $orderIncrementId
+     * @param string $status New order status
+     * @param string $comment Comment to order status change
+     * @param boolean $notify Should customer be notified about status change
+     * @return boolean Is method executed successfully
+     */
+    public function addComment($orderIncrementId, $status, $comment = null, $notify = false)
+    {
+        $order = $this->_initOrder($orderIncrementId);
+
+        $order->addStatusToHistory($status, $comment, $notify);
+
+
+        try {
+            if ($notify && $comment) {
+                $oldArea = Mage::getDesign()->getArea();
+                Mage::getDesign()->setArea('frontend');
+            }
+
+            $order->save();
+            $order->sendOrderUpdateEmail($notify, $comment);
+            if ($notify && $comment) {
+                Mage::getDesign()->setArea($oldArea);
+            }
+
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('status_not_changed', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Hold order
+     *
+     * @param string $orderIncrementId
+     * @return boolean
+     */
+    public function hold($orderIncrementId)
+    {
+        $order = $this->_initOrder($orderIncrementId);
+
+        try {
+            $order->hold();
+            $order->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('status_not_changed', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Unhold order
+     *
+     * @param string $orderIncrementId
+     * @return boolean
+     */
+    public function unhold($orderIncrementId)
+    {
+        $order = $this->_initOrder($orderIncrementId);
+
+        try {
+            $order->unhold();
+            $order->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('status_not_changed', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Cancel order
+     *
+     * @param string $orderIncrementId
+     * @return boolean
+     */
+    public function cancel($orderIncrementId)
+    {
+        $order = $this->_initOrder($orderIncrementId);
+
+        if (Mage_Sales_Model_Order::STATE_CANCELED == $order->getState()) {
+            $this->_fault('status_not_changed');
+        }
+        try {
+            $order->cancel();
+            $order->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('status_not_changed', $e->getMessage());
+        }
+        if (Mage_Sales_Model_Order::STATE_CANCELED != $order->getState()) {
+            $this->_fault('status_not_changed');
+        }
+        return true;
+    }
+
+} // Class Mage_Sales_Model_Order_Api End
diff --git a/app/code/core/Mage/Sales/Model/Order/Api/V2.php b/app/code/core/Mage/Sales/Model/Order/Api/V2.php
new file mode 100644
index 00000000000..d3d84294cb4
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Order/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Order API V2
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Order_Api_V2 extends Mage_Sales_Model_Order_Api
+{
+}
diff --git a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Api.php b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Api.php
new file mode 100644
index 00000000000..f79941ae388
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Api.php
@@ -0,0 +1,258 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Credit memo API
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Order_Creditmemo_Api extends Mage_Sales_Model_Api_Resource
+{
+
+    /**
+     * Initialize attributes mapping
+     */
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        parent::__construct($apiHelper);
+        $this->_attributesMap = array(
+            'creditmemo' => array('creditmemo_id' => 'entity_id'),
+            'creditmemo_item' => array('item_id' => 'entity_id'),
+            'creditmemo_comment' => array('comment_id' => 'entity_id')
+        );
+    }
+
+    /**
+     * Retrieve credit memos list. Filtration could be applied
+     *
+     * @param null|object|array $filters
+     * @return array
+     */
+    public function items($filters = null)
+    {
+        $creditmemos = array();
+        /** @var $apiHelper Mage_Api_Helper_Data */
+        $apiHelper = Mage::helper('Mage_Api_Helper_Data');
+        $filters = $apiHelper->parseFilters($filters, $this->_attributesMap['creditmemo']);
+        /** @var $creditmemoModel Mage_Sales_Model_Order_Creditmemo */
+        $creditmemoModel = Mage::getModel('Mage_Sales_Model_Order_Creditmemo');
+        try {
+            $creditMemoCollection = $creditmemoModel->getFilteredCollectionItems($filters);
+            foreach ($creditMemoCollection as $creditmemo) {
+                $creditmemos[] = $this->_getAttributes($creditmemo, 'creditmemo');
+            }
+        } catch (Exception $e) {
+            $this->_fault('invalid_filter', $e->getMessage());
+        }
+        return $creditmemos;
+    }
+
+    /**
+     * Retrieve credit memo information
+     *
+     * @param string $creditmemoIncrementId
+     * @return array
+     */
+    public function info($creditmemoIncrementId)
+    {
+        $creditmemo = $this->_getCreditmemo($creditmemoIncrementId);
+        // get credit memo attributes with entity_id' => 'creditmemo_id' mapping
+        $result = $this->_getAttributes($creditmemo, 'creditmemo');
+        $result['order_increment_id'] = $creditmemo->getOrder()->load($creditmemo->getOrderId())->getIncrementId();
+        // items refunded
+        $result['items'] = array();
+        foreach ($creditmemo->getAllItems() as $item) {
+            $result['items'][] = $this->_getAttributes($item, 'creditmemo_item');
+        }
+        // credit memo comments
+        $result['comments'] = array();
+        foreach ($creditmemo->getCommentsCollection() as $comment) {
+            $result['comments'][] = $this->_getAttributes($comment, 'creditmemo_comment');
+        }
+
+        return $result;
+    }
+
+    /**
+     * Create new credit memo for order
+     *
+     * @param string $orderIncrementId
+     * @param array $creditmemoData array('qtys' => array('sku1' => qty1, ... , 'skuN' => qtyN),
+     *      'shipping_amount' => value, 'adjustment_positive' => value, 'adjustment_negative' => value)
+     * @param string|null $comment
+     * @param bool $notifyCustomer
+     * @param bool $includeComment
+     * @param string $refundToStoreCreditAmount
+     * @return string $creditmemoIncrementId
+     */
+    public function create($orderIncrementId, $creditmemoData = null, $comment = null, $notifyCustomer = false,
+        $includeComment = false, $refundToStoreCreditAmount = null)
+    {
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::getModel('Mage_Sales_Model_Order')->load($orderIncrementId, 'increment_id');
+        if (!$order->getId()) {
+            $this->_fault('order_not_exists');
+        }
+        if (!$order->canCreditmemo()) {
+            $this->_fault('cannot_create_creditmemo');
+        }
+        $creditmemoData = $this->_prepareCreateData($creditmemoData);
+
+        /** @var $service Mage_Sales_Model_Service_Order */
+        $service = Mage::getModel('Mage_Sales_Model_Service_Order', $order);
+        /** @var $creditmemo Mage_Sales_Model_Order_Creditmemo */
+        $creditmemo = $service->prepareCreditmemo($creditmemoData);
+
+        // refund to Store Credit
+        if ($refundToStoreCreditAmount) {
+            // check if refund to Store Credit is available
+            if ($order->getCustomerIsGuest()) {
+                $this->_fault('cannot_refund_to_storecredit');
+            }
+            $refundToStoreCreditAmount = max(
+                0,
+                min($creditmemo->getBaseCustomerBalanceReturnMax(), $refundToStoreCreditAmount)
+            );
+            if ($refundToStoreCreditAmount) {
+                $refundToStoreCreditAmount = $creditmemo->getStore()->roundPrice($refundToStoreCreditAmount);
+                $creditmemo->setBaseCustomerBalanceTotalRefunded($refundToStoreCreditAmount);
+                $refundToStoreCreditAmount = $creditmemo->getStore()->roundPrice(
+                    $refundToStoreCreditAmount*$order->getBaseToOrderRate()
+                );
+                // this field can be used by customer balance observer
+                $creditmemo->setBsCustomerBalTotalRefunded($refundToStoreCreditAmount);
+                // setting flag to make actual refund to customer balance after credit memo save
+                $creditmemo->setCustomerBalanceRefundFlag(true);
+            }
+        }
+        $creditmemo->setPaymentRefundDisallowed(true)->register();
+        // add comment to creditmemo
+        if (!empty($comment)) {
+            $creditmemo->addComment($comment, $notifyCustomer);
+        }
+        try {
+            Mage::getModel('Mage_Core_Model_Resource_Transaction')
+                ->addObject($creditmemo)
+                ->addObject($order)
+                ->save();
+            // send email notification
+            $creditmemo->sendEmail($notifyCustomer, ($includeComment ? $comment : ''));
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+        return $creditmemo->getIncrementId();
+    }
+
+    /**
+     * Add comment to credit memo
+     *
+     * @param string $creditmemoIncrementId
+     * @param string $comment
+     * @param boolean $notifyCustomer
+     * @param boolean $includeComment
+     * @return boolean
+     */
+    public function addComment($creditmemoIncrementId, $comment, $notifyCustomer = false, $includeComment = false)
+    {
+        $creditmemo = $this->_getCreditmemo($creditmemoIncrementId);
+        try {
+            $creditmemo->addComment($comment, $notifyCustomer)->save();
+            $creditmemo->sendUpdateEmail($notifyCustomer, ($includeComment ? $comment : ''));
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Cancel credit memo
+     *
+     * @param string $creditmemoIncrementId
+     * @return boolean
+     */
+    public function cancel($creditmemoIncrementId)
+    {
+        $creditmemo = $this->_getCreditmemo($creditmemoIncrementId);
+
+        if (!$creditmemo->canCancel()) {
+            $this->_fault('status_not_changed', Mage::helper('Mage_Sales_Helper_Data')->__('Credit memo cannot be canceled.'));
+        }
+        try {
+            $creditmemo->cancel()->save();
+        } catch (Exception $e) {
+            $this->_fault('status_not_changed', Mage::helper('Mage_Sales_Helper_Data')->__('Credit memo canceling problem.'));
+        }
+
+        return true;
+    }
+
+    /**
+     * Hook method, could be replaced in derived classes
+     *
+     * @param  array $data
+     * @return array
+     */
+    protected function _prepareCreateData($data)
+    {
+        $data = isset($data) ? $data : array();
+
+        if (isset($data['qtys']) && count($data['qtys'])) {
+            $qtysArray = array();
+            foreach ($data['qtys'] as $qKey => $qVal) {
+                // Save backward compatibility
+                if (is_array($qVal)) {
+                    if (isset($qVal['order_item_id']) && isset($qVal['qty'])) {
+                        $qtysArray[$qVal['order_item_id']] = $qVal['qty'];
+                    }
+                } else {
+                    $qtysArray[$qKey] = $qVal;
+                }
+            }
+            $data['qtys'] = $qtysArray;
+        }
+        return $data;
+    }
+
+    /**
+     * Load CreditMemo by IncrementId
+     *
+     * @param mixed $incrementId
+     * @return Mage_Core_Model_Abstract|Mage_Sales_Model_Order_Creditmemo
+     */
+    protected function _getCreditmemo($incrementId)
+    {
+        /** @var $creditmemo Mage_Sales_Model_Order_Creditmemo */
+        $creditmemo = Mage::getModel('Mage_Sales_Model_Order_Creditmemo')->load($incrementId, 'increment_id');
+        if (!$creditmemo->getId()) {
+            $this->_fault('not_exists');
+        }
+        return $creditmemo;
+    }
+
+}
diff --git a/app/code/core/Mage/Sales/Model/Order/Creditmemo/Api/V2.php b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Api/V2.php
new file mode 100644
index 00000000000..c8fc4fc6df3
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Order/Creditmemo/Api/V2.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Credit memo API
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Order_Creditmemo_Api_V2 extends Mage_Sales_Model_Order_Creditmemo_Api
+{
+    /**
+     * Prepare data
+     *
+     * @param null|object $data
+     * @return array
+     */
+    protected function _prepareCreateData($data)
+    {
+        // convert data object to array, if it's null turn it into empty array
+        $data = (isset($data) and is_object($data)) ? get_object_vars($data) : array();
+        // convert qtys object to array
+        if (isset($data['qtys']) && count($data['qtys'])) {
+            $qtysArray = array();
+            foreach ($data['qtys'] as &$item) {
+                if (isset($item->order_item_id) && isset($item->qty)) {
+                    $qtysArray[$item->order_item_id] = $item->qty;
+                }
+            }
+            $data['qtys'] = $qtysArray;
+        }
+        return $data;
+    }
+}
diff --git a/app/code/core/Mage/Sales/Model/Order/Invoice/Api.php b/app/code/core/Mage/Sales/Model/Order/Invoice/Api.php
new file mode 100644
index 00000000000..8f2a97d5722
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Order/Invoice/Api.php
@@ -0,0 +1,326 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Invoice API
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Order_Invoice_Api extends Mage_Sales_Model_Api_Resource
+{
+    /**
+     * Initialize attributes map
+     */
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        parent::__construct($apiHelper);
+        $this->_attributesMap = array(
+            'invoice' => array('invoice_id' => 'entity_id'),
+            'invoice_item' => array('item_id' => 'entity_id'),
+            'invoice_comment' => array('comment_id' => 'entity_id')
+        );
+    }
+
+    /**
+     * Retrive invoices list. Filtration could be applied
+     *
+     * @param null|object|array $filters
+     * @return array
+     */
+    public function items($filters = null)
+    {
+        $invoices = array();
+        /** @var $invoiceCollection Mage_Sales_Model_Resource_Order_Invoice_Collection */
+        $invoiceCollection = Mage::getResourceModel('Mage_Sales_Model_Resource_Order_Invoice_Collection');
+        $invoiceCollection->addAttributeToSelect('entity_id')
+            ->addAttributeToSelect('order_id')
+            ->addAttributeToSelect('increment_id')
+            ->addAttributeToSelect('created_at')
+            ->addAttributeToSelect('state')
+            ->addAttributeToSelect('grand_total')
+            ->addAttributeToSelect('order_currency_code');
+
+        /** @var $apiHelper Mage_Api_Helper_Data */
+        $apiHelper = Mage::helper('Mage_Api_Helper_Data');
+        try {
+            $filters = $apiHelper->parseFilters($filters, $this->_attributesMap['invoice']);
+            foreach ($filters as $field => $value) {
+                $invoiceCollection->addFieldToFilter($field, $value);
+            }
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('filters_invalid', $e->getMessage());
+        }
+        foreach ($invoiceCollection as $invoice) {
+            $invoices[] = $this->_getAttributes($invoice, 'invoice');
+        }
+        return $invoices;
+    }
+
+    /**
+     * Retrieve invoice information
+     *
+     * @param string $invoiceIncrementId
+     * @return array
+     */
+    public function info($invoiceIncrementId)
+    {
+        $invoice = Mage::getModel('Mage_Sales_Model_Order_Invoice')->loadByIncrementId($invoiceIncrementId);
+
+        /* @var Mage_Sales_Model_Order_Invoice $invoice */
+
+        if (!$invoice->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        $result = $this->_getAttributes($invoice, 'invoice');
+        $result['order_increment_id'] = $invoice->getOrderIncrementId();
+
+        $result['items'] = array();
+        foreach ($invoice->getAllItems() as $item) {
+            $result['items'][] = $this->_getAttributes($item, 'invoice_item');
+        }
+
+        $result['comments'] = array();
+        foreach ($invoice->getCommentsCollection() as $comment) {
+            $result['comments'][] = $this->_getAttributes($comment, 'invoice_comment');
+        }
+
+        return $result;
+    }
+
+    /**
+     * Create new invoice for order
+     *
+     * @param string $orderIncrementId
+     * @param array $itemsQty
+     * @param string $comment
+     * @param boolean $email
+     * @param boolean $includeComment
+     * @return string
+     */
+    public function create($orderIncrementId, $itemsQty, $comment = null, $email = false, $includeComment = false)
+    {
+        $order = Mage::getModel('Mage_Sales_Model_Order')->loadByIncrementId($orderIncrementId);
+
+        /* @var $order Mage_Sales_Model_Order */
+        /**
+         * Check order existing
+         */
+        if (!$order->getId()) {
+            $this->_fault('order_not_exists');
+        }
+
+        /**
+         * Check invoice create availability
+         */
+        if (!$order->canInvoice()) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Sales_Helper_Data')->__('Cannot do invoice for order.'));
+        }
+
+        $invoice = $order->prepareInvoice($itemsQty);
+
+        $invoice->register();
+
+        if ($comment !== null) {
+            $invoice->addComment($comment, $email);
+        }
+
+        if ($email) {
+            $invoice->setEmailSent(true);
+        }
+
+        $invoice->getOrder()->setIsInProcess(true);
+
+        try {
+            $transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction')
+                ->addObject($invoice)
+                ->addObject($invoice->getOrder())
+                ->save();
+
+            $invoice->sendEmail($email, ($includeComment ? $comment : ''));
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return $invoice->getIncrementId();
+    }
+
+    /**
+     * Add comment to invoice
+     *
+     * @param string $invoiceIncrementId
+     * @param string $comment
+     * @param boolean $email
+     * @param boolean $includeComment
+     * @return boolean
+     */
+    public function addComment($invoiceIncrementId, $comment, $email = false, $includeComment = false)
+    {
+        $invoice = Mage::getModel('Mage_Sales_Model_Order_Invoice')->loadByIncrementId($invoiceIncrementId);
+
+        /* @var $invoice Mage_Sales_Model_Order_Invoice */
+
+        if (!$invoice->getId()) {
+            $this->_fault('not_exists');
+        }
+
+
+        try {
+            $invoice->addComment($comment, $email);
+            $invoice->sendUpdateEmail($email, ($includeComment ? $comment : ''));
+            $invoice->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Capture invoice
+     *
+     * @param string $invoiceIncrementId
+     * @return boolean
+     */
+    public function capture($invoiceIncrementId)
+    {
+        $invoice = Mage::getModel('Mage_Sales_Model_Order_Invoice')->loadByIncrementId($invoiceIncrementId);
+
+        /* @var $invoice Mage_Sales_Model_Order_Invoice */
+
+        if (!$invoice->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        if (!$invoice->canCapture()) {
+            $this->_fault(
+                'status_not_changed',
+                Mage::helper('Mage_Sales_Helper_Data')->__('Invoice cannot be captured.')
+            );
+        }
+
+        try {
+            $invoice->capture();
+            $invoice->getOrder()->setIsInProcess(true);
+            $transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction')
+                ->addObject($invoice)
+                ->addObject($invoice->getOrder())
+                ->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('status_not_changed', $e->getMessage());
+        } catch (Exception $e) {
+            $this->_fault(
+                'status_not_changed',
+                Mage::helper('Mage_Sales_Helper_Data')->__('Invoice capturing problem.')
+            );
+        }
+
+        return true;
+    }
+
+    /**
+     * Void invoice
+     *
+     * @param unknown_type $invoiceIncrementId
+     * @return unknown
+     */
+    public function void($invoiceIncrementId)
+    {
+        $invoice = Mage::getModel('Mage_Sales_Model_Order_Invoice')->loadByIncrementId($invoiceIncrementId);
+
+        /* @var $invoice Mage_Sales_Model_Order_Invoice */
+
+        if (!$invoice->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        if (!$invoice->canVoid()) {
+            $this->_fault(
+                'status_not_changed',
+                Mage::helper('Mage_Sales_Helper_Data')->__('Invoice cannot be voided.')
+            );
+        }
+
+        try {
+            $invoice->void();
+            $invoice->getOrder()->setIsInProcess(true);
+            $transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction')
+                ->addObject($invoice)
+                ->addObject($invoice->getOrder())
+                ->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('status_not_changed', $e->getMessage());
+        } catch (Exception $e) {
+            $this->_fault('status_not_changed', Mage::helper('Mage_Sales_Helper_Data')->__('Invoice void problem'));
+        }
+
+        return true;
+    }
+
+    /**
+     * Cancel invoice
+     *
+     * @param string $invoiceIncrementId
+     * @return boolean
+     */
+    public function cancel($invoiceIncrementId)
+    {
+        $invoice = Mage::getModel('Mage_Sales_Model_Order_Invoice')->loadByIncrementId($invoiceIncrementId);
+
+        /* @var $invoice Mage_Sales_Model_Order_Invoice */
+
+        if (!$invoice->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        if (!$invoice->canCancel()) {
+            $this->_fault(
+                'status_not_changed',
+                Mage::helper('Mage_Sales_Helper_Data')->__('Invoice cannot be canceled.')
+            );
+        }
+
+        try {
+            $invoice->cancel();
+            $invoice->getOrder()->setIsInProcess(true);
+            $transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction')
+                ->addObject($invoice)
+                ->addObject($invoice->getOrder())
+                ->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('status_not_changed', $e->getMessage());
+        } catch (Exception $e) {
+            $this->_fault(
+                'status_not_changed',
+                Mage::helper('Mage_Sales_Helper_Data')->__('Invoice canceling problem.')
+            );
+        }
+
+        return true;
+    }
+}
diff --git a/app/code/core/Mage/Sales/Model/Order/Invoice/Api/V2.php b/app/code/core/Mage/Sales/Model/Order/Invoice/Api/V2.php
new file mode 100644
index 00000000000..3694674b661
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Order/Invoice/Api/V2.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Invoice API V2
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Order_Invoice_Api_V2 extends Mage_Sales_Model_Order_Invoice_Api
+{
+    /**
+     * Create new invoice for order
+     *
+     * @param string $orderIncrementId
+     * @param array $itemsQty
+     * @param string $comment
+     * @param bool $email
+     * @param bool $includeComment
+     * @return string
+     */
+    public function create($orderIncrementId, $itemsQty, $comment = null, $email = false, $includeComment = false)
+    {
+        $order = Mage::getModel('Mage_Sales_Model_Order')->loadByIncrementId($orderIncrementId);
+        $itemsQty = $this->_prepareItemQtyData($itemsQty);
+        /* @var $order Mage_Sales_Model_Order */
+        /**
+         * Check order existing
+         */
+        if (!$order->getId()) {
+            $this->_fault('order_not_exists');
+        }
+
+        /**
+         * Check invoice create availability
+         */
+        if (!$order->canInvoice()) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Sales_Helper_Data')->__('Cannot do invoice for order.'));
+        }
+
+        $invoice = $order->prepareInvoice($itemsQty);
+
+        $invoice->register();
+
+        if ($comment !== null) {
+            $invoice->addComment($comment, $email);
+        }
+
+        if ($email) {
+            $invoice->setEmailSent(true);
+        }
+
+        $invoice->getOrder()->setIsInProcess(true);
+
+        try {
+            Mage::getModel('Mage_Core_Model_Resource_Transaction')->addObject($invoice)->addObject($invoice->getOrder())
+                ->save();
+            $invoice->sendEmail($email, ($includeComment ? $comment : ''));
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return $invoice->getIncrementId();
+    }
+
+    /**
+     * Prepare items quantity data
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function _prepareItemQtyData($data)
+    {
+        $quantity = array();
+        foreach ($data as $item) {
+            if (isset($item->order_item_id) && isset($item->qty)) {
+                $quantity[$item->order_item_id] = $item->qty;
+            }
+        }
+        return $quantity;
+    }
+}
diff --git a/app/code/core/Mage/Sales/Model/Order/Shipment.php b/app/code/core/Mage/Sales/Model/Order/Shipment.php
index a7a0aaa8d10..46e8b5bbb8f 100644
--- a/app/code/core/Mage/Sales/Model/Order/Shipment.php
+++ b/app/code/core/Mage/Sales/Model/Order/Shipment.php
@@ -259,6 +259,11 @@ class Mage_Sales_Model_Order_Shipment extends Mage_Sales_Model_Abstract
     }
 
 
+    /**
+     * Retrieve tracks collection.
+     *
+     * @return Mage_Sales_Model_Resource_Order_Shipment_Track_Collection
+     */
     public function getTracksCollection()
     {
         if (empty($this->_tracks)) {
@@ -341,6 +346,12 @@ class Mage_Sales_Model_Order_Shipment extends Mage_Sales_Model_Abstract
         return $this;
     }
 
+    /**
+     * Retrieve comments collection.
+     *
+     * @param bool $reload
+     * @return Mage_Sales_Model_Resource_Order_Shipment_Comment_Collection
+     */
     public function getCommentsCollection($reload=false)
     {
         if (is_null($this->_comments) || $reload) {
diff --git a/app/code/core/Mage/Sales/Model/Order/Shipment/Api.php b/app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
new file mode 100644
index 00000000000..a7598a7de65
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Order/Shipment/Api.php
@@ -0,0 +1,352 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Sales order shippment API
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Order_Shipment_Api extends Mage_Sales_Model_Api_Resource
+{
+    public function __construct(Mage_Api_Helper_Data $apiHelper)
+    {
+        parent::__construct($apiHelper);
+        $this->_attributesMap['shipment'] = array('shipment_id' => 'entity_id');
+
+        $this->_attributesMap['shipment_item'] = array('item_id'    => 'entity_id');
+
+        $this->_attributesMap['shipment_comment'] = array('comment_id' => 'entity_id');
+
+        $this->_attributesMap['shipment_track'] = array('track_id'   => 'entity_id');
+    }
+
+    /**
+     * Retrieve shipments by filters
+     *
+     * @param null|object|array $filters
+     * @return array
+     */
+    public function items($filters = null)
+    {
+        $shipments = array();
+        //TODO: add full name logic
+        $shipmentCollection = Mage::getResourceModel('Mage_Sales_Model_Resource_Order_Shipment_Collection')
+            ->addAttributeToSelect('increment_id')
+            ->addAttributeToSelect('created_at')
+            ->addAttributeToSelect('total_qty')
+            ->addAttributeToSelect('entity_id')
+            ->joinAttribute('shipping_firstname', 'order_address/firstname', 'shipping_address_id', null, 'left')
+            ->joinAttribute('shipping_lastname', 'order_address/lastname', 'shipping_address_id', null, 'left')
+            ->joinAttribute('order_increment_id', 'order/increment_id', 'order_id', null, 'left')
+            ->joinAttribute('order_created_at', 'order/created_at', 'order_id', null, 'left');
+
+        /** @var $apiHelper Mage_Api_Helper_Data */
+        $apiHelper = Mage::helper('Mage_Api_Helper_Data');
+        try {
+            $filters = $apiHelper->parseFilters($filters, $this->_attributesMap['shipment']);
+            foreach ($filters as $field => $value) {
+                $shipmentCollection->addFieldToFilter($field, $value);
+            }
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('filters_invalid', $e->getMessage());
+        }
+        foreach ($shipmentCollection as $shipment) {
+            $shipments[] = $this->_getAttributes($shipment, 'shipment');
+        }
+
+        return $shipments;
+    }
+
+    /**
+     * Retrieve shipment information
+     *
+     * @param string $shipmentIncrementId
+     * @return array
+     */
+    public function info($shipmentIncrementId)
+    {
+        $shipment = Mage::getModel('Mage_Sales_Model_Order_Shipment')->loadByIncrementId($shipmentIncrementId);
+
+        /* @var $shipment Mage_Sales_Model_Order_Shipment */
+
+        if (!$shipment->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        $result = $this->_getAttributes($shipment, 'shipment');
+
+        $result['items'] = array();
+        foreach ($shipment->getAllItems() as $item) {
+            $result['items'][] = $this->_getAttributes($item, 'shipment_item');
+        }
+
+        $result['tracks'] = array();
+        foreach ($shipment->getAllTracks() as $track) {
+            $result['tracks'][] = $this->_getAttributes($track, 'shipment_track');
+        }
+
+        $result['comments'] = array();
+        foreach ($shipment->getCommentsCollection() as $comment) {
+            $result['comments'][] = $this->_getAttributes($comment, 'shipment_comment');
+        }
+
+        return $result;
+    }
+
+    /**
+     * Create new shipment for order
+     *
+     * @param string $orderIncrementId
+     * @param array $itemsQty
+     * @param string $comment
+     * @param booleam $email
+     * @param boolean $includeComment
+     * @return string
+     */
+    public function create($orderIncrementId, $itemsQty = array(), $comment = null, $email = false,
+        $includeComment = false
+    ) {
+        $order = Mage::getModel('Mage_Sales_Model_Order')->loadByIncrementId($orderIncrementId);
+
+        /**
+          * Check order existing
+          */
+        if (!$order->getId()) {
+             $this->_fault('order_not_exists');
+        }
+
+        /**
+         * Check shipment create availability
+         */
+        if (!$order->canShip()) {
+             $this->_fault('data_invalid', Mage::helper('Mage_Sales_Helper_Data')->__('Cannot do shipment for order.'));
+        }
+
+         /* @var $shipment Mage_Sales_Model_Order_Shipment */
+        $shipment = $order->prepareShipment($itemsQty);
+        if ($shipment) {
+            $shipment->register();
+            $shipment->addComment($comment, $email && $includeComment);
+            if ($email) {
+                $shipment->setEmailSent(true);
+            }
+            $shipment->getOrder()->setIsInProcess(true);
+            try {
+                $transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction')
+                    ->addObject($shipment)
+                    ->addObject($shipment->getOrder())
+                    ->save();
+                $shipment->sendEmail($email, ($includeComment ? $comment : ''));
+            } catch (Mage_Core_Exception $e) {
+                $this->_fault('data_invalid', $e->getMessage());
+            }
+            return $shipment->getIncrementId();
+        }
+        return null;
+    }
+
+    /**
+     * Add tracking number to order
+     *
+     * @param string $shipmentIncrementId
+     * @param string $carrier
+     * @param string $title
+     * @param string $trackNumber
+     * @return int
+     */
+    public function addTrack($shipmentIncrementId, $carrier, $title, $trackNumber)
+    {
+        $shipment = Mage::getModel('Mage_Sales_Model_Order_Shipment')->loadByIncrementId($shipmentIncrementId);
+
+        /* @var $shipment Mage_Sales_Model_Order_Shipment */
+
+        if (!$shipment->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        $carriers = $this->_getCarriers($shipment);
+
+        if (!isset($carriers[$carrier])) {
+            $this->_fault('data_invalid', Mage::helper('Mage_Sales_Helper_Data')->__('Invalid carrier specified.'));
+        }
+
+        $track = Mage::getModel('Mage_Sales_Model_Order_Shipment_Track')
+                    ->setNumber($trackNumber)
+                    ->setCarrierCode($carrier)
+                    ->setTitle($title);
+
+        $shipment->addTrack($track);
+
+        try {
+            $shipment->save();
+            $track->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return $track->getId();
+    }
+
+    /**
+     * Remove tracking number
+     *
+     * @param string $shipmentIncrementId
+     * @param int $trackId
+     * @return boolean
+     */
+    public function removeTrack($shipmentIncrementId, $trackId)
+    {
+        $shipment = Mage::getModel('Mage_Sales_Model_Order_Shipment')->loadByIncrementId($shipmentIncrementId);
+
+        /* @var $shipment Mage_Sales_Model_Order_Shipment */
+
+        if (!$shipment->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        if(!$track = $shipment->getTrackById($trackId)) {
+            $this->_fault('track_not_exists');
+        }
+
+        try {
+            $track->delete();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('track_not_deleted', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Send email with shipment data to customer
+     *
+     * @param string $shipmentIncrementId
+     * @param string $comment
+     * @return bool
+     */
+    public function sendInfo($shipmentIncrementId, $comment = '')
+    {
+        /* @var $shipment Mage_Sales_Model_Order_Shipment */
+        $shipment = Mage::getModel('Mage_Sales_Model_Order_Shipment')->loadByIncrementId($shipmentIncrementId);
+
+        if (!$shipment->getId()) {
+            $this->_fault('not_exists');
+        }
+
+        try {
+            $shipment->sendEmail(true, $comment)
+                ->setEmailSent(true)
+                ->save();
+            $historyItem = Mage::getResourceModel('Mage_Sales_Model_Resource_Order_Status_History_Collection')
+                ->getUnnotifiedForInstance($shipment, Mage_Sales_Model_Order_Shipment::HISTORY_ENTITY_NAME);
+            if ($historyItem) {
+                $historyItem->setIsCustomerNotified(1);
+                $historyItem->save();
+            }
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Add comment to shipment
+     *
+     * @param string $shipmentIncrementId
+     * @param string $comment
+     * @param boolean $email
+     * @param boolean $includeInEmail
+     * @return boolean
+     */
+    public function addComment($shipmentIncrementId, $comment, $email = false, $includeInEmail = false)
+    {
+        $shipment = Mage::getModel('Mage_Sales_Model_Order_Shipment')->loadByIncrementId($shipmentIncrementId);
+
+        /* @var $shipment Mage_Sales_Model_Order_Shipment */
+
+        if (!$shipment->getId()) {
+            $this->_fault('not_exists');
+        }
+
+
+        try {
+            $shipment->addComment($comment, $email);
+            $shipment->sendUpdateEmail($email, ($includeInEmail ? $comment : ''));
+            $shipment->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('data_invalid', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Retrieve allowed shipping carriers for specified order
+     *
+     * @param string $orderIncrementId
+     * @return array
+     */
+    public function getCarriers($orderIncrementId)
+    {
+        $order = Mage::getModel('Mage_Sales_Model_Order')->loadByIncrementId($orderIncrementId);
+
+        /**
+          * Check order existing
+          */
+        if (!$order->getId()) {
+            $this->_fault('order_not_exists');
+        }
+
+        return $this->_getCarriers($order);
+    }
+
+    /**
+     * Retrieve shipping carriers for specified order
+     *
+     * @param Mage_Eav_Model_Entity_Abstract $object
+     * @return array
+     */
+    protected function _getCarriers($object)
+    {
+        $carriers = array();
+        $carrierInstances = Mage::getSingleton('Mage_Shipping_Model_Config')->getAllCarriers(
+            $object->getStoreId()
+        );
+
+        $carriers['custom'] = Mage::helper('Mage_Sales_Helper_Data')->__('Custom Value');
+        foreach ($carrierInstances as $code => $carrier) {
+            if ($carrier->isTrackingAvailable()) {
+                $carriers[$code] = $carrier->getConfigData('title');
+            }
+        }
+
+        return $carriers;
+    }
+
+} // Class Mage_Sales_Model_Order_Shipment_Api End
diff --git a/app/code/core/Mage/Sales/Model/Order/Shipment/Api/V2.php b/app/code/core/Mage/Sales/Model/Order/Shipment/Api/V2.php
new file mode 100644
index 00000000000..dc6767e50a6
--- /dev/null
+++ b/app/code/core/Mage/Sales/Model/Order/Shipment/Api/V2.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.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Sales order shippment API V2
+ *
+ * @category   Mage
+ * @package    Mage_Sales
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Sales_Model_Order_Shipment_Api_V2 extends Mage_Sales_Model_Order_Shipment_Api
+{
+    protected function _prepareItemQtyData($data)
+    {
+        $_data = array();
+        foreach ($data as $item) {
+            if (isset($item->order_item_id) && isset($item->qty)) {
+                $_data[$item->order_item_id] = $item->qty;
+            }
+        }
+        return $_data;
+    }
+
+    /**
+     * Create new shipment for order
+     *
+     * @param string $orderIncrementId
+     * @param array $itemsQty
+     * @param string $comment
+     * @param boolean $email
+     * @param boolean $includeComment
+     * @return string
+     */
+    public function create($orderIncrementId, $itemsQty = array(), $comment = null, $email = false,
+        $includeComment = false
+    ) {
+        $order = Mage::getModel('Mage_Sales_Model_Order')->loadByIncrementId($orderIncrementId);
+        $itemsQty = $this->_prepareItemQtyData($itemsQty);
+        /**
+          * Check order existing
+          */
+        if (!$order->getId()) {
+             $this->_fault('order_not_exists');
+        }
+
+        /**
+         * Check shipment create availability
+         */
+        if (!$order->canShip()) {
+             $this->_fault('data_invalid', Mage::helper('Mage_Sales_Helper_Data')->__('Cannot do shipment for order.'));
+        }
+
+         /* @var $shipment Mage_Sales_Model_Order_Shipment */
+        $shipment = $order->prepareShipment($itemsQty);
+        if ($shipment) {
+            $shipment->register();
+            $shipment->addComment($comment, $email && $includeComment);
+            if ($email) {
+                $shipment->setEmailSent(true);
+            }
+            $shipment->getOrder()->setIsInProcess(true);
+            try {
+                $transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction')
+                    ->addObject($shipment)
+                    ->addObject($shipment->getOrder())
+                    ->save();
+                $shipment->sendEmail($email, ($includeComment ? $comment : ''));
+            } catch (Mage_Core_Exception $e) {
+                $this->_fault('data_invalid', $e->getMessage());
+            }
+            return $shipment->getIncrementId();
+        }
+        return null;
+    }
+
+    /**
+     * Retrieve allowed shipping carriers for specified order
+     *
+     * @param string $orderIncrementId
+     * @return array
+     */
+    public function getCarriers($orderIncrementId)
+    {
+        $order = Mage::getModel('Mage_Sales_Model_Order')->loadByIncrementId($orderIncrementId);
+
+        /**
+          * Check order existing
+          */
+        if (!$order->getId()) {
+            $this->_fault('order_not_exists');
+        }
+        $carriers = array();
+        foreach ($this->_getCarriers($order) as $key => $value) {
+            $carriers[] = array('key' => $key, 'value' => $value);
+        }
+
+        return $carriers;
+    }
+}
diff --git a/app/code/core/Mage/Sales/etc/api.xml b/app/code/core/Mage/Sales/etc/api.xml
new file mode 100644
index 00000000000..24686784941
--- /dev/null
+++ b/app/code/core/Mage/Sales/etc/api.xml
@@ -0,0 +1,375 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Sales
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <sales_order translate="title" module="Mage_Sales">
+                <model>Mage_Sales_Model_Order_Api</model>
+                <title>Order API</title>
+                <acl>sales/order</acl>
+                <methods>
+                    <list translate="title" module="Mage_Sales">
+                        <title>Retrieve list of orders by filters</title>
+                        <method>items</method>
+                        <acl>sales/order/info</acl>
+                    </list>
+                    <info translate="title" module="Mage_Sales">
+                        <title>Retrieve order information</title>
+                        <acl>sales/order/info</acl>
+                    </info>
+                    <addComment translate="title" module="Mage_Sales">
+                        <title>Add comment to order</title>
+                        <acl>sales/order/change</acl>
+                    </addComment>
+                    <hold translate="title" module="Mage_Sales">
+                        <title>Hold order</title>
+                        <acl>sales/order/change</acl>
+                    </hold>
+                    <unhold translate="title" module="Mage_Sales">
+                        <title>Unhold order</title>
+                        <acl>sales/order/change</acl>
+                    </unhold>
+                    <cancel translate="title" module="Mage_Sales">
+                        <title>Cancel order</title>
+                        <acl>sales/order/change</acl>
+                    </cancel>
+                </methods>
+                <faults module="Mage_Sales">
+                    <not_exists>
+                        <code>100</code>
+                        <message>Requested order does not exist.</message>
+                    </not_exists>
+                    <filters_invalid>
+                        <code>101</code>
+                        <message>Provided filters are invalid. Details are in error message.</message>
+                    </filters_invalid>
+                    <data_invalid>
+                        <code>102</code>
+                        <message>Provided data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <status_not_changed>
+                        <code>103</code>
+                        <message>Order status is not changed. Details are in error message.</message>
+                    </status_not_changed>
+                </faults>
+            </sales_order>
+            <sales_order_shipment>
+                <title>Shipment API</title>
+                <model>Mage_Sales_Model_Order_Shipment_Api</model>
+                <acl>sales/order/shipment</acl>
+                <methods>
+                    <list translate="title" module="Mage_Sales">
+                        <title>Retrieve list of shipments by filters</title>
+                        <method>items</method>
+                        <acl>sales/order/shipment/info</acl>
+                    </list>
+                    <info translate="title" module="Mage_Sales">
+                        <title>Retrieve shipment information</title>
+                        <acl>sales/order/shipment/info</acl>
+                    </info>
+                    <sendInfo translate="title" module="Mage_Sales">
+                        <title>Send shipment info</title>
+                        <acl>sales/order/shipment/send</acl>
+                    </sendInfo>
+                    <create translate="title" module="Mage_Sales">
+                        <title>Create new shipment for order</title>
+                        <acl>sales/order/shipment/create</acl>
+                    </create>
+                    <addComment translate="title" module="Mage_Sales">
+                        <title>Add new comment to shipment</title>
+                        <acl>sales/order/shipment/comment</acl>
+                    </addComment>
+                    <addTrack translate="title" module="Mage_Sales">
+                        <title>Add new tracking number</title>
+                        <acl>sales/order/shipment/track</acl>
+                    </addTrack>
+                    <removeTrack translate="title" module="Mage_Sales">
+                        <title>Remove tracking number</title>
+                        <acl>sales/order/shipment/track</acl>
+                    </removeTrack>
+                    <getCarriers>
+                        <title>Retrieve list of allowed carriers for order</title>
+                    </getCarriers>
+                </methods>
+                <faults module="Mage_Sales">
+                    <not_exists>
+                        <code>100</code>
+                        <message>Requested shipment does not exist.</message>
+                    </not_exists>
+                    <filters_invalid>
+                        <code>101</code>
+                        <message>Provided filters are invalid. Details are in error message.</message>
+                    </filters_invalid>
+                    <data_invalid>
+                        <code>102</code>
+                        <message>Provided data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <order_not_exists>
+                        <code>103</code>
+                        <message>Requested order does not exist.</message>
+                    </order_not_exists>
+                    <track_not_exists>
+                        <code>104</code>
+                        <message>Requested tracking does not exist.</message>
+                    </track_not_exists>
+                    <track_not_deleted>
+                        <code>105</code>
+                        <message>Tracking is not deleted. Details are in error message.</message>
+                    </track_not_deleted>
+                </faults>
+            </sales_order_shipment>
+            <sales_order_invoice>
+                <title>Invoice API</title>
+                <model>Mage_Sales_Model_Order_Invoice_Api</model>
+                <acl>sales/order/invoice</acl>
+                <methods>
+                    <list translate="title" module="Mage_Sales">
+                        <title>Retrieve list of invoices by filters</title>
+                        <method>items</method>
+                        <acl>sales/order/invoice/info</acl>
+                    </list>
+                    <info translate="title" module="Mage_Sales">
+                        <title>Retrieve invoice information</title>
+                        <acl>sales/order/invoice/info</acl>
+                    </info>
+                    <create translate="title" module="Mage_Sales">
+                        <title>Create new invoice for order</title>
+                        <acl>sales/order/invoice/create</acl>
+                    </create>
+                    <addComment translate="title" module="Mage_Sales">
+                        <title>Add new comment to shipment</title>
+                        <acl>sales/order/invoice/comment</acl>
+                    </addComment>
+                    <capture translate="title" module="Mage_Sales">
+                        <title>Capture invoice</title>
+                        <acl>sales/order/invoice/capture</acl>
+                    </capture>
+                    <void translate="title" module="Mage_Sales">
+                        <title>Void invoice</title>
+                        <acl>sales/order/invoice/void</acl>
+                    </void>
+                    <cancel translate="title" module="Mage_Sales">
+                        <title>Cancel invoice</title>
+                        <acl>sales/order/invoice/cancel</acl>
+                    </cancel>
+                </methods>
+                <faults module="Mage_Sales">
+                    <not_exists>
+                        <code>100</code>
+                        <message>Requested invoice does not exist.</message>
+                    </not_exists>
+                    <invalid_filter>
+                        <code>101</code>
+                        <message>Provided filter is invalid. Details are in error message.</message>
+                    </invalid_filter>
+                    <data_invalid>
+                        <code>102</code>
+                        <message>Provided data is invalid. Details are in error message.</message>
+                    </data_invalid>
+                    <order_not_exists>
+                        <code>103</code>
+                        <message>Requested order does not exist.</message>
+                    </order_not_exists>
+                    <status_not_changed>
+                        <code>104</code>
+                        <message>Invoice status is not changed</message>
+                    </status_not_changed>
+                </faults>
+           </sales_order_invoice>
+            <sales_order_creditmemo>
+                <title>Credit memo API</title>
+                <model>Mage_Sales_Model_Order_Creditmemo_Api</model>
+                <acl>sales/order/creditmemo</acl>
+                <methods>
+                    <list translate="title" module="Mage_Sales">
+                        <title>Retrieve list of credit memos by filters</title>
+                        <method>items</method>
+                        <acl>sales/order/creditmemo/list</acl>
+                    </list>
+                    <info translate="title" module="Mage_Sales">
+                        <title>Retrieve credit memo information</title>
+                        <acl>sales/order/creditmemo/info</acl>
+                    </info>
+                    <create translate="title" module="Mage_Sales">
+                        <title>Create new credit memo for order</title>
+                        <acl>sales/order/creditmemo/create</acl>
+                    </create>
+                    <addComment translate="title" module="Mage_Sales">
+                        <title>Add new comment to credit memo</title>
+                        <acl>sales/order/creditmemo/comment</acl>
+                    </addComment>
+                    <cancel translate="title" module="Mage_Sales">
+                        <title>Cancel credit memo</title>
+                        <acl>sales/order/creditmemo/cancel</acl>
+                    </cancel>
+                </methods>
+                <faults module="Mage_Sales">
+                    <not_exists>
+                        <code>100</code>
+                        <message>Requested credit memo does not exist.</message>
+                    </not_exists>
+                    <invalid_filter>
+                        <code>101</code>
+                        <message>Provided filter is invalid. Details are in error message</message>
+                    </invalid_filter>
+                    <data_invalid>
+                        <code>102</code>
+                        <message>Provided data is invalid. Details are in error message</message>
+                    </data_invalid>
+                    <order_not_exists>
+                        <code>103</code>
+                        <message>Requested order does not exist.</message>
+                    </order_not_exists>
+                    <status_not_changed>
+                        <code>104</code>
+                        <message>Credit memo status is not changed.</message>
+                    </status_not_changed>
+                    <cannot_refund_to_storecredit>
+                        <code>105</code>
+                        <message>Money cannot be refunded to the store credit account as order was created by guest.</message>
+                    </cannot_refund_to_storecredit>
+                    <cannot_create_creditmemo>
+                        <code>106</code>
+                        <message>Credit memo for requested order cannot be created.</message>
+                    </cannot_create_creditmemo>
+                </faults>
+            </sales_order_creditmemo>
+        </resources>
+        <resources_alias>
+            <order>sales_order</order>
+            <order_shipment>sales_order_shipment</order_shipment>
+            <order_invoice>sales_order_invoice</order_invoice>
+            <order_creditmemo>sales_order_creditmemo</order_creditmemo>
+        </resources_alias>
+        <v2>
+            <resources_function_prefix>
+                <order>salesOrder</order>
+                <order_shipment>salesOrderShipment</order_shipment>
+                <order_invoice>salesOrderInvoice</order_invoice>
+                <order_creditmemo>salesOrderCreditmemo</order_creditmemo>
+            </resources_function_prefix>
+        </v2>
+        <rest>
+            <mapping>
+                <sales_order>
+                    <delete>
+                        <method>cancel</method>
+                    </delete>
+                    <post>
+                        <resource>cart</resource>
+                        <method>order</method>
+                    </post>
+                </sales_order>
+               <sales_order_invoice>
+                   <delete>
+                       <method>cancel</method>
+                   </delete>
+               </sales_order_invoice>
+                <sales_order_creditmemo>
+                    <delete>
+                        <method>cancel</method>
+                    </delete>
+                </sales_order_creditmemo>
+            </mapping>
+        </rest>
+        <acl>
+            <resources>
+                <sales translate="title" module="Mage_Sales">
+                    <title>Sales</title>
+                    <sort_order>2</sort_order>
+                    <order translate="title" module="Mage_Sales">
+                        <title>Order</title>
+                        <change translate="title" module="Mage_Sales">
+                            <title>Change status, add comments</title>
+                        </change>
+                        <info translate="title" module="Mage_Sales">
+                            <title>Retrieve orders info</title>
+                        </info>
+                        <shipment translate="title" module="Mage_Sales">
+                            <title>Order shipments</title>
+                            <create translate="title" module="Mage_Sales">
+                                <title>Create</title>
+                            </create>
+                            <comment translate="title" module="Mage_Sales">
+                                <title>Comments</title>
+                            </comment>
+                            <track translate="title" module="Mage_Sales">
+                                <title>Tracking</title>
+                            </track>
+                            <info translate="title" module="Mage_Sales">
+                                <title>Retrieve shipment info</title>
+                            </info>
+                            <send translate="title" module="Mage_Sales">
+                                <title>Send shipment info</title>
+                            </send>
+                        </shipment>
+                        <invoice translate="title" module="Mage_Sales">
+                            <title>Order invoice</title>
+                            <create translate="title" module="Mage_Sales">
+                                <title>Create</title>
+                            </create>
+                            <comment translate="title" module="Mage_Sales">
+                                <title>Comments</title>
+                            </comment>
+                            <capture translate="title" module="Mage_Sales">
+                                <title>Capture</title>
+                            </capture>
+                            <void translate="title" module="Mage_Sales">
+                                <title>Void</title>
+                            </void>
+                            <cancel translate="title" module="Mage_Sales">
+                                <title>Cancel</title>
+                            </cancel>
+                            <info translate="title" module="Mage_Sales">
+                                <title>Retrieve invoice info</title>
+                            </info>
+                        </invoice>
+                        <creditmemo translate="title" module="Mage_Sales">
+                            <title>Order credit memo</title>
+                            <create translate="title" module="Mage_Sales">
+                                <title>Create</title>
+                            </create>
+                            <comment translate="title" module="Mage_Sales">
+                                <title>Comments</title>
+                            </comment>
+                            <cancel translate="title" module="Mage_Sales">
+                                <title>Cancel</title>
+                            </cancel>
+                            <info translate="title" module="Mage_Sales">
+                                <title>Retrieve credit memo info</title>
+                            </info>
+                            <list translate="title" module="Mage_Sales">
+                                <title>Retrieve credit memo list</title>
+                            </list>
+                        </creditmemo>
+                    </order>
+                </sales>
+            </resources>
+        </acl>
+    </api>
+</config>
diff --git a/app/code/core/Mage/Sales/etc/wsdl.xml b/app/code/core/Mage/Sales/etc/wsdl.xml
new file mode 100644
index 00000000000..343e3330dd7
--- /dev/null
+++ b/app/code/core/Mage/Sales/etc/wsdl.xml
@@ -0,0 +1,1346 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
+    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
+            <complexType name="salesOrderEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="store_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="customer_id" type="xsd:string" minOccurs="0" />
+                    <element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal" type="xsd:string" minOccurs="0" />
+                    <element name="grand_total" type="xsd:string" minOccurs="0" />
+                    <element name="total_paid" type="xsd:string" minOccurs="0" />
+                    <element name="total_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="total_qty_ordered" type="xsd:string" minOccurs="0" />
+                    <element name="total_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="total_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="total_online_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="total_offline_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal" type="xsd:string" minOccurs="0" />
+                    <element name="base_grand_total" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_paid" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_qty_ordered" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_online_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_offline_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="billing_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="billing_firstname" type="xsd:string" minOccurs="0" />
+                    <element name="billing_lastname" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_firstname" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_lastname" type="xsd:string" minOccurs="0" />
+                    <element name="billing_name" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_name" type="xsd:string" minOccurs="0" />
+                    <element name="store_to_base_rate" type="xsd:string" minOccurs="0" />
+                    <element name="store_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <element name="base_to_global_rate" type="xsd:string" minOccurs="0" />
+                    <element name="base_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <element name="weight" type="xsd:string" minOccurs="0" />
+                    <element name="store_name" type="xsd:string" minOccurs="0" />
+                    <element name="remote_ip" type="xsd:string" minOccurs="0" />
+                    <element name="status" type="xsd:string" minOccurs="0" />
+                    <element name="state" type="xsd:string" minOccurs="0" />
+                    <element name="applied_rule_ids" type="xsd:string" minOccurs="0" />
+                    <element name="global_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="base_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="store_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="order_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_method" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_description" type="xsd:string" minOccurs="0" />
+                    <element name="customer_email" type="xsd:string" minOccurs="0" />
+                    <element name="customer_firstname" type="xsd:string" minOccurs="0" />
+                    <element name="customer_lastname" type="xsd:string" minOccurs="0" />
+                    <element name="quote_id" type="xsd:string" minOccurs="0" />
+                    <element name="is_virtual" type="xsd:string" minOccurs="0" />
+                    <element name="customer_group_id" type="xsd:string" minOccurs="0" />
+                    <element name="customer_note_notify" type="xsd:string" minOccurs="0" />
+                    <element name="customer_is_guest" type="xsd:string" minOccurs="0" />
+                    <element name="email_sent" type="xsd:string" minOccurs="0" />
+                    <element name="order_id" type="xsd:string" minOccurs="0" />
+                    <element name="gift_message_id" type="xsd:string" minOccurs="0" />
+                    <element name="gift_message" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_address" type="typens:salesOrderAddressEntity" minOccurs="0" />
+                    <element name="billing_address" type="typens:salesOrderAddressEntity" minOccurs="0" />
+                    <element name="items" type="typens:salesOrderItemEntityArray" minOccurs="0" />
+                    <element name="payment" type="typens:salesOrderPaymentEntity" minOccurs="0" />
+                    <element name="status_history" type="typens:salesOrderStatusHistoryEntityArray" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderListEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="store_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="customer_id" type="xsd:string" minOccurs="0" />
+                    <element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal" type="xsd:string" minOccurs="0" />
+                    <element name="grand_total" type="xsd:string" minOccurs="0" />
+                    <element name="total_paid" type="xsd:string" minOccurs="0" />
+                    <element name="total_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="total_qty_ordered" type="xsd:string" minOccurs="0" />
+                    <element name="total_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="total_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="total_online_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="total_offline_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal" type="xsd:string" minOccurs="0" />
+                    <element name="base_grand_total" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_paid" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_qty_ordered" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_online_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_offline_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="billing_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="billing_firstname" type="xsd:string" minOccurs="0" />
+                    <element name="billing_lastname" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_firstname" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_lastname" type="xsd:string" minOccurs="0" />
+                    <element name="billing_name" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_name" type="xsd:string" minOccurs="0" />
+                    <element name="store_to_base_rate" type="xsd:string" minOccurs="0" />
+                    <element name="store_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <element name="base_to_global_rate" type="xsd:string" minOccurs="0" />
+                    <element name="base_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <element name="weight" type="xsd:string" minOccurs="0" />
+                    <element name="store_name" type="xsd:string" minOccurs="0" />
+                    <element name="remote_ip" type="xsd:string" minOccurs="0" />
+                    <element name="status" type="xsd:string" minOccurs="0" />
+                    <element name="state" type="xsd:string" minOccurs="0" />
+                    <element name="applied_rule_ids" type="xsd:string" minOccurs="0" />
+                    <element name="global_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="base_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="store_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="order_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_method" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_description" type="xsd:string" minOccurs="0" />
+                    <element name="customer_email" type="xsd:string" minOccurs="0" />
+                    <element name="customer_firstname" type="xsd:string" minOccurs="0" />
+                    <element name="customer_lastname" type="xsd:string" minOccurs="0" />
+                    <element name="quote_id" type="xsd:string" minOccurs="0" />
+                    <element name="is_virtual" type="xsd:string" minOccurs="0" />
+                    <element name="customer_group_id" type="xsd:string" minOccurs="0" />
+                    <element name="customer_note_notify" type="xsd:string" minOccurs="0" />
+                    <element name="customer_is_guest" type="xsd:string" minOccurs="0" />
+                    <element name="email_sent" type="xsd:string" minOccurs="0" />
+                    <element name="order_id" type="xsd:string" minOccurs="0" />
+                    <element name="gift_message_id" type="xsd:string" minOccurs="0" />
+                    <element name="coupon_code" type="xsd:string" minOccurs="0" />
+                    <element name="protect_code" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_invoiced_cost" type="xsd:string" minOccurs="0" />
+                    <element name="discount_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="discount_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="discount_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="tax_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="tax_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="can_ship_partially" type="xsd:string" minOccurs="0" />
+                    <element name="can_ship_partially_item" type="xsd:string" minOccurs="0" />
+                    <element name="edit_increment" type="xsd:string" minOccurs="0" />
+                    <element name="forced_do_shipment_with_invoice" type="xsd:string" minOccurs="0" />
+                    <element name="payment_authorization_expiration" type="xsd:string" minOccurs="0" />
+                    <element name="paypal_ipn_customer_notified" type="xsd:string" minOccurs="0" />
+                    <element name="quote_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="adjustment_negative" type="xsd:string" minOccurs="0" />
+                    <element name="adjustment_positive" type="xsd:string" minOccurs="0" />
+                    <element name="base_adjustment_negative" type="xsd:string" minOccurs="0" />
+                    <element name="base_adjustment_positive" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="base_total_due" type="xsd:string" minOccurs="0" />
+                    <element name="payment_authorization_amount" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="total_due" type="xsd:string" minOccurs="0" />
+                    <element name="customer_dob" type="xsd:string" minOccurs="0" />
+                    <element name="customer_middlename" type="xsd:string" minOccurs="0" />
+                    <element name="customer_prefix" type="xsd:string" minOccurs="0" />
+                    <element name="customer_suffix" type="xsd:string" minOccurs="0" />
+                    <element name="customer_taxvat" type="xsd:string" minOccurs="0" />
+                    <element name="discount_description" type="xsd:string" minOccurs="0" />
+                    <element name="ext_customer_id" type="xsd:string" minOccurs="0" />
+                    <element name="ext_order_id" type="xsd:string" minOccurs="0" />
+                    <element name="hold_before_state" type="xsd:string" minOccurs="0" />
+                    <element name="hold_before_status" type="xsd:string" minOccurs="0" />
+                    <element name="original_increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="relation_child_id" type="xsd:string" minOccurs="0" />
+                    <element name="relation_child_real_id" type="xsd:string" minOccurs="0" />
+                    <element name="relation_parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="relation_parent_real_id" type="xsd:string" minOccurs="0" />
+                    <element name="x_forwarded_for" type="xsd:string" minOccurs="0" />
+                    <element name="customer_note" type="xsd:string" minOccurs="0" />
+                    <element name="total_item_count" type="xsd:string" minOccurs="0" />
+                    <element name="customer_gender" type="xsd:string" minOccurs="0" />
+                    <element name="hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="hidden_tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_hidden_tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="hidden_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_hidden_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="base_customer_balance_amount" type="xsd:string" minOccurs="0" />
+                    <element name="customer_balance_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_customer_balance_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="customer_balance_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_customer_balance_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="customer_balance_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="bs_customer_bal_total_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="customer_bal_total_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="gift_cards" type="xsd:string" minOccurs="0" />
+                    <element name="base_gift_cards_amount" type="xsd:string" minOccurs="0" />
+                    <element name="gift_cards_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_gift_cards_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="gift_cards_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_gift_cards_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="gift_cards_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="reward_points_balance" type="xsd:string" minOccurs="0" />
+                    <element name="base_reward_currency_amount" type="xsd:string" minOccurs="0" />
+                    <element name="reward_currency_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_rwrd_crrncy_amt_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="rwrd_currency_amount_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_rwrd_crrncy_amnt_refnded" type="xsd:string" minOccurs="0" />
+                    <element name="rwrd_crrncy_amnt_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="reward_points_balance_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="reward_points_balance_refund" type="xsd:string" minOccurs="0" />
+                    <element name="reward_salesrule_points" type="xsd:string" minOccurs="0" />
+                    <element name="firstname" type="xsd:string" minOccurs="0" />
+                    <element name="lastname" type="xsd:string" minOccurs="0" />
+                    <element name="telephone" type="xsd:string" minOccurs="0" />
+                    <element name="postcode" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderListEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderListEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderAddressEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="address_type" type="xsd:string" minOccurs="0" />
+                    <element name="firstname" type="xsd:string" minOccurs="0" />
+                    <element name="lastname" type="xsd:string" minOccurs="0" />
+                    <element name="company" type="xsd:string" minOccurs="0" />
+                    <element name="street" type="xsd:string" minOccurs="0" />
+                    <element name="city" type="xsd:string" minOccurs="0" />
+                    <element name="region" type="xsd:string" minOccurs="0" />
+                    <element name="postcode" type="xsd:string" minOccurs="0" />
+                    <element name="country_id" type="xsd:string" minOccurs="0" />
+                    <element name="telephone" type="xsd:string" minOccurs="0" />
+                    <element name="fax" type="xsd:string" minOccurs="0" />
+                    <element name="region_id" type="xsd:string" minOccurs="0" />
+                    <element name="address_id" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderItemEntity">
+                <all>
+                    <element name="item_id" type="xsd:string" minOccurs="0" />
+                    <element name="order_id" type="xsd:string" minOccurs="0" />
+                    <element name="quote_item_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="product_id" type="xsd:string" minOccurs="0" />
+                    <element name="product_type" type="xsd:string" minOccurs="0" />
+                    <element name="product_options" type="xsd:string" minOccurs="0" />
+                    <element name="weight" type="xsd:string" minOccurs="0" />
+                    <element name="is_virtual" type="xsd:string" minOccurs="0" />
+                    <element name="sku" type="xsd:string" minOccurs="0" />
+                    <element name="name" type="xsd:string" minOccurs="0" />
+                    <element name="applied_rule_ids" type="xsd:string" minOccurs="0" />
+                    <element name="free_shipping" type="xsd:string" minOccurs="0" />
+                    <element name="is_qty_decimal" type="xsd:string" minOccurs="0" />
+                    <element name="no_discount" type="xsd:string" minOccurs="0" />
+                    <element name="qty_canceled" type="xsd:string" minOccurs="0" />
+                    <element name="qty_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="qty_ordered" type="xsd:string" minOccurs="0" />
+                    <element name="qty_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="qty_shipped" type="xsd:string" minOccurs="0" />
+                    <element name="cost" type="xsd:string" minOccurs="0" />
+                    <element name="price" type="xsd:string" minOccurs="0" />
+                    <element name="base_price" type="xsd:string" minOccurs="0" />
+                    <element name="original_price" type="xsd:string" minOccurs="0" />
+                    <element name="base_original_price" type="xsd:string" minOccurs="0" />
+                    <element name="tax_percent" type="xsd:string" minOccurs="0" />
+                    <element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="discount_percent" type="xsd:string" minOccurs="0" />
+                    <element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="discount_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="amount_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_amount_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="row_total" type="xsd:string" minOccurs="0" />
+                    <element name="base_row_total" type="xsd:string" minOccurs="0" />
+                    <element name="row_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="base_row_invoiced" type="xsd:string" minOccurs="0" />
+                    <element name="row_weight" type="xsd:string" minOccurs="0" />
+                    <element name="gift_message_id" type="xsd:string" minOccurs="0" />
+                    <element name="gift_message" type="xsd:string" minOccurs="0" />
+                    <element name="gift_message_available" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_before_discount" type="xsd:string" minOccurs="0" />
+                    <element name="tax_before_discount" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_applied_row_amnt" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderItemEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderItemEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="orderItemIdQty">
+                <all>
+                    <element name="order_item_id" type="xsd:int" />
+                    <element name="qty" type="xsd:double" />
+                </all>
+            </complexType>
+            <complexType name="orderItemIdQtyArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:orderItemIdQty[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderPaymentEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="amount_ordered" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_amount_ordered" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="method" type="xsd:string" minOccurs="0" />
+                    <element name="po_number" type="xsd:string" minOccurs="0" />
+                    <element name="cc_type" type="xsd:string" minOccurs="0" />
+                    <element name="cc_number_enc" type="xsd:string" minOccurs="0" />
+                    <element name="cc_last4" type="xsd:string" minOccurs="0" />
+                    <element name="cc_owner" type="xsd:string" minOccurs="0" />
+                    <element name="cc_exp_month" type="xsd:string" minOccurs="0" />
+                    <element name="cc_exp_year" type="xsd:string" minOccurs="0" />
+                    <element name="cc_ss_start_month" type="xsd:string" minOccurs="0" />
+                    <element name="cc_ss_start_year" type="xsd:string" minOccurs="0" />
+                    <element name="payment_id" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderStatusHistoryEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="is_customer_notified" type="xsd:string" minOccurs="0" />
+                    <element name="status" type="xsd:string" minOccurs="0" />
+                    <element name="comment" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderStatusHistoryEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderStatusHistoryEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderShipmentEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="store_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_firstname" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_lastname" type="xsd:string" minOccurs="0" />
+                    <element name="order_id" type="xsd:string" minOccurs="0" />
+                    <element name="order_increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="order_created_at" type="xsd:string" minOccurs="0" />
+                    <element name="total_qty" type="xsd:string" minOccurs="0" />
+                    <element name="shipment_id" type="xsd:string" minOccurs="0" />
+                    <element name="items" type="typens:salesOrderShipmentItemEntityArray" minOccurs="0" />
+                    <element name="tracks" type="typens:salesOrderShipmentTrackEntityArray" minOccurs="0" />
+                    <element name="comments" type="typens:salesOrderShipmentCommentEntityArray" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderShipmentEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderShipmentEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderShipmentCommentEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="comment" type="xsd:string" minOccurs="0" />
+                    <element name="is_customer_notified" type="xsd:string" minOccurs="0" />
+                    <element name="comment_id" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderShipmentCommentEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderShipmentCommentEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderShipmentTrackEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="carrier_code" type="xsd:string" minOccurs="0" />
+                    <element name="title" type="xsd:string" minOccurs="0" />
+                    <element name="number" type="xsd:string" minOccurs="0" />
+                    <element name="order_id" type="xsd:string" minOccurs="0" />
+                    <element name="track_id" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderShipmentTrackEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderShipmentTrackEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderShipmentItemEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="sku" type="xsd:string" minOccurs="0" />
+                    <element name="name" type="xsd:string" minOccurs="0" />
+                    <element name="order_item_id" type="xsd:string" minOccurs="0" />
+                    <element name="product_id" type="xsd:string" minOccurs="0" />
+                    <element name="weight" type="xsd:string" minOccurs="0" />
+                    <element name="price" type="xsd:string" minOccurs="0" />
+                    <element name="qty" type="xsd:string" minOccurs="0" />
+                    <element name="item_id" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderShipmentItemEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderShipmentItemEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderInvoiceEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="store_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="global_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="base_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="store_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="order_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="store_to_base_rate" type="xsd:string" minOccurs="0" />
+                    <element name="store_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <element name="base_to_global_rate" type="xsd:string" minOccurs="0" />
+                    <element name="base_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal" type="xsd:string" minOccurs="0" />
+                    <element name="base_grand_total" type="xsd:string" minOccurs="0" />
+                    <element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="billing_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="billing_firstname" type="xsd:string" minOccurs="0" />
+                    <element name="billing_lastname" type="xsd:string" minOccurs="0" />
+                    <element name="order_id" type="xsd:string" minOccurs="0" />
+                    <element name="order_increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="order_created_at" type="xsd:string" minOccurs="0" />
+                    <element name="state" type="xsd:string" minOccurs="0" />
+                    <element name="grand_total" type="xsd:string" minOccurs="0" />
+                    <element name="invoice_id" type="xsd:string" minOccurs="0" />
+                    <element name="items" type="typens:salesOrderInvoiceItemEntityArray" minOccurs="0" />
+                    <element name="comments" type="typens:salesOrderInvoiceCommentEntityArray" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderInvoiceEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderInvoiceEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderInvoiceItemEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied" type="xsd:string" minOccurs="0" />
+                    <element name="qty" type="xsd:string" minOccurs="0" />
+                    <element name="cost" type="xsd:string" minOccurs="0" />
+                    <element name="price" type="xsd:string" minOccurs="0" />
+                    <element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="row_total" type="xsd:string" minOccurs="0" />
+                    <element name="base_price" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_row_total" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_applied_row_amnt" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="sku" type="xsd:string" minOccurs="0" />
+                    <element name="name" type="xsd:string" minOccurs="0" />
+                    <element name="order_item_id" type="xsd:string" minOccurs="0" />
+                    <element name="product_id" type="xsd:string" minOccurs="0" />
+                    <element name="item_id" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderInvoiceItemEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderInvoiceItemEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderInvoiceCommentEntity">
+                <all>
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="is_active" type="xsd:string" minOccurs="0" />
+                    <element name="comment" type="xsd:string" minOccurs="0" />
+                    <element name="is_customer_notified" type="xsd:string" minOccurs="0" />
+                    <element name="comment_id" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderInvoiceCommentEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderInvoiceCommentEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderCreditmemoEntity">
+                <all>
+                    <element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <element name="transaction_id" type="xsd:string" minOccurs="0" />
+                    <element name="global_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="base_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="order_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="store_currency_code" type="xsd:string" minOccurs="0" />
+                    <element name="cybersource_token" type="xsd:string" minOccurs="0" />
+                    <element name="invoice_id" type="xsd:string" minOccurs="0" />
+                    <element name="billing_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_address_id" type="xsd:string" minOccurs="0" />
+                    <element name="state" type="xsd:string" minOccurs="0" />
+                    <element name="creditmemo_status" type="xsd:string" minOccurs="0" />
+                    <element name="email_sent" type="xsd:string" minOccurs="0" />
+                    <element name="order_id" type="xsd:string" minOccurs="0" />
+                    <element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_adjustment_positive" type="xsd:string" minOccurs="0" />
+                    <element name="base_grand_total" type="xsd:string" minOccurs="0" />
+                    <element name="adjustment" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal" type="xsd:string" minOccurs="0" />
+                    <element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal" type="xsd:string" minOccurs="0" />
+                    <element name="base_adjustment" type="xsd:string" minOccurs="0" />
+                    <element name="base_to_global_rate" type="xsd:string" minOccurs="0" />
+                    <element name="store_to_base_rate" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="adjustment_negative" type="xsd:string" minOccurs="0" />
+                    <element name="subtotal_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_subtotal_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="base_adjustment_negative" type="xsd:string" minOccurs="0" />
+                    <element name="grand_total" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <element name="store_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="adjustment_positive" type="xsd:string" minOccurs="0" />
+                    <element name="store_id" type="xsd:string" minOccurs="0" />
+                    <element name="hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_hidden_tax_amnt" type="xsd:string" minOccurs="0" />
+                    <element name="shipping_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="base_shipping_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="base_customer_balance_amount" type="xsd:string" minOccurs="0" />
+                    <element name="customer_balance_amount" type="xsd:string" minOccurs="0" />
+                    <element name="bs_customer_bal_total_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="customer_bal_total_refunded" type="xsd:string" minOccurs="0" />
+                    <element name="base_gift_cards_amount" type="xsd:string" minOccurs="0" />
+                    <element name="gift_cards_amount" type="xsd:string" minOccurs="0" />
+                    <element name="gw_base_price" type="xsd:string" minOccurs="0" />
+                    <element name="gw_price" type="xsd:string" minOccurs="0" />
+                    <element name="gw_items_base_price" type="xsd:string" minOccurs="0" />
+                    <element name="gw_items_price" type="xsd:string" minOccurs="0" />
+                    <element name="gw_card_base_price" type="xsd:string" minOccurs="0" />
+                    <element name="gw_card_price" type="xsd:string" minOccurs="0" />
+                    <element name="gw_base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="gw_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="gw_items_base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="gw_items_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="gw_card_base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="gw_card_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_reward_currency_amount" type="xsd:string" minOccurs="0" />
+                    <element name="reward_currency_amount" type="xsd:string" minOccurs="0" />
+                    <element name="reward_points_balance" type="xsd:string" minOccurs="0" />
+                    <element name="reward_points_balance_refund" type="xsd:string" minOccurs="0" />
+                    <element name="creditmemo_id" type="xsd:string" minOccurs="0" />
+                    <element name="items" type="typens:salesOrderCreditmemoItemEntityArray" minOccurs="0" />
+                    <element name="comments" type="typens:salesOrderCreditmemoCommentEntityArray" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="salesOrderCreditmemoEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderCreditmemoEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderCreditmemoItemEntity">
+                <all>
+                    <element name="item_id" type="xsd:string" minOccurs="0" />
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_price" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="base_row_total" type="xsd:string" minOccurs="0" />
+                    <element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="row_total" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="price_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <element name="base_price_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="qty" type="xsd:string" minOccurs="0" />
+                    <element name="base_cost" type="xsd:string" minOccurs="0" />
+                    <element name="base_weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" />
+                    <element name="price" type="xsd:string" minOccurs="0" />
+                    <element name="base_row_total_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="row_total_incl_tax" type="xsd:string" minOccurs="0" />
+                    <element name="product_id" type="xsd:string" minOccurs="0" />
+                    <element name="order_item_id" type="xsd:string" minOccurs="0" />
+                    <element name="additional_data" type="xsd:string" minOccurs="0" />
+                    <element name="description" type="xsd:string" minOccurs="0" />
+                    <element name="weee_tax_applied" type="xsd:string" minOccurs="0" />
+                    <element name="sku" type="xsd:string" minOccurs="0" />
+                    <element name="name" type="xsd:string" minOccurs="0" />
+                    <element name="hidden_tax_amount" type="xsd:string" minOccurs="0"/>
+                    <element name="base_hidden_tax_amount" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="salesOrderCreditmemoItemEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderCreditmemoItemEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderCreditmemoCommentEntity">
+                <all>
+                    <element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <element name="created_at" type="xsd:string" minOccurs="0" />
+                    <element name="comment" type="xsd:string" minOccurs="0" />
+                    <element name="is_customer_notified" type="xsd:string" minOccurs="0" />
+                    <element name="comment_id" type="xsd:string" minOccurs="0" />
+                    <element name="is_visible_on_front" type="xsd:string" minOccurs="0"/>
+                </all>
+            </complexType>
+            <complexType name="salesOrderCreditmemoCommentEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:salesOrderCreditmemoCommentEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="salesOrderCreditmemoData">
+                <all>
+                    <element name="qtys" type="typens:orderItemIdQtyArray" minOccurs="0"/>
+                    <element name="shipping_amount" type="xsd:double" minOccurs="0"/>
+                    <element name="adjustment_positive" type="xsd:double" minOccurs="0"/>
+                    <element name="adjustment_negative" type="xsd:double" minOccurs="0"/>
+                </all>
+            </complexType>
+        </schema>
+    </types>
+    <message name="salesOrderListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="filters" type="typens:filters" />
+    </message>
+    <message name="salesOrderListResponse">
+        <part name="result" type="typens:salesOrderListEntityArray" />
+    </message>
+    <message name="salesOrderInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="orderIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderInfoResponse">
+        <part name="result" type="typens:salesOrderEntity" />
+    </message>
+    <message name="salesOrderAddCommentRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="orderIncrementId" type="xsd:string" />
+        <part name="status" type="xsd:string" />
+        <part name="comment" type="xsd:string" />
+        <part name="notify" type="xsd:string" />
+    </message>
+    <message name="salesOrderAddCommentResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderHoldRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="orderIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderHoldResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderUnholdRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="orderIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderUnholdResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderCancelRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="orderIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderCancelResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderShipmentListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="filters" type="typens:filters" />
+    </message>
+    <message name="salesOrderShipmentListResponse">
+        <part name="result" type="typens:salesOrderShipmentEntityArray" />
+    </message>
+    <message name="salesOrderShipmentInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="shipmentIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderShipmentInfoResponse">
+        <part name="result" type="typens:salesOrderShipmentEntity" />
+    </message>
+    <message name="salesOrderShipmentCreateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="orderIncrementId" type="xsd:string" />
+        <part name="itemsQty" type="typens:orderItemIdQtyArray" />
+        <part name="comment" type="xsd:string" />
+        <part name="email" type="xsd:int" />
+        <part name="includeComment" type="xsd:int" />
+    </message>
+    <message name="salesOrderShipmentCreateResponse">
+        <part name="shipmentIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderShipmentAddCommentRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="shipmentIncrementId" type="xsd:string" />
+        <part name="comment" type="xsd:string" />
+        <part name="email" type="xsd:string" />
+        <part name="includeInEmail" type="xsd:string" />
+    </message>
+    <message name="salesOrderShipmentAddCommentResponse">
+        <part name="shipmentIncrementId" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderShipmentAddTrackRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="shipmentIncrementId" type="xsd:string" />
+        <part name="carrier" type="xsd:string" />
+        <part name="title" type="xsd:string" />
+        <part name="trackNumber" type="xsd:string" />
+    </message>
+    <message name="salesOrderShipmentAddTrackResponse">
+        <part name="result" type="xsd:int" />
+    </message>
+    <message name="salesOrderShipmentSendInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="shipmentIncrementId" type="xsd:string" />
+        <part name="comment" type="xsd:string" />
+    </message>
+    <message name="salesOrderShipmentSendInfoResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderShipmentRemoveTrackRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="shipmentIncrementId" type="xsd:string" />
+        <part name="trackId" type="xsd:string" />
+    </message>
+    <message name="salesOrderShipmentRemoveTrackResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderShipmentGetCarriersRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="orderIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderShipmentGetCarriersResponse">
+        <part name="result" type="typens:associativeArray" />
+    </message>
+    <message name="salesOrderInvoiceListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="filters" type="typens:filters" />
+    </message>
+    <message name="salesOrderInvoiceListResponse">
+        <part name="result" type="typens:salesOrderInvoiceEntityArray" />
+    </message>
+    <message name="salesOrderInvoiceInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="invoiceIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderInvoiceInfoResponse">
+        <part name="result" type="typens:salesOrderInvoiceEntity" />
+    </message>
+    <message name="salesOrderInvoiceCreateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="orderIncrementId" type="xsd:string" />
+        <part name="itemsQty" type="typens:orderItemIdQtyArray" />
+        <part name="comment" type="xsd:string" />
+        <part name="email" type="xsd:string" />
+        <part name="includeComment" type="xsd:string" />
+    </message>
+    <message name="salesOrderInvoiceCreateResponse">
+        <part name="result" type="xsd:string" />
+    </message>
+    <message name="salesOrderInvoiceAddCommentRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="invoiceIncrementId" type="xsd:string" />
+        <part name="comment" type="xsd:string" />
+        <part name="email" type="xsd:string" />
+        <part name="includeComment" type="xsd:string" />
+    </message>
+    <message name="salesOrderInvoiceAddCommentResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderCreditmemoListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="filters" type="typens:filters" />
+    </message>
+    <message name="salesOrderCreditmemoListResponse">
+        <part name="result" type="typens:salesOrderCreditmemoEntityArray" />
+    </message>
+    <message name="salesOrderCreditmemoInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="creditmemoIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderCreditmemoInfoResponse">
+        <part name="result" type="typens:salesOrderCreditmemoEntity" />
+    </message>
+    <message name="salesOrderCreditmemoCreateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="creditmemoIncrementId" type="xsd:string" />
+        <part name="creditmemoData" type="typens:salesOrderCreditmemoData" />
+        <part name="comment" type="xsd:string" />
+        <part name="notifyCustomer" type="xsd:int" />
+        <part name="includeComment" type="xsd:int" />
+        <part name="refundToStoreCreditAmount" type="xsd:string" />
+    </message>
+    <message name="salesOrderCreditmemoCreateResponse">
+        <part name="result" type="xsd:string" />
+    </message>
+    <message name="salesOrderCreditmemoAddCommentRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="creditmemoIncrementId" type="xsd:string" />
+        <part name="comment" type="xsd:string" />
+        <part name="notifyCustomer" type="xsd:int" />
+        <part name="includeComment" type="xsd:int" />
+    </message>
+    <message name="salesOrderCreditmemoAddCommentResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderCreditmemoCancelRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="creditmemoIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderCreditmemoCancelResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderInvoiceCaptureRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="invoiceIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderInvoiceCaptureResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderInvoiceVoidRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="invoiceIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderInvoiceVoidResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="salesOrderInvoiceCancelRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="invoiceIncrementId" type="xsd:string" />
+    </message>
+    <message name="salesOrderInvoiceCancelResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="salesOrderList">
+            <documentation>Retrieve list of orders by filters</documentation>
+            <input message="typens:salesOrderListRequest" />
+            <output message="typens:salesOrderListResponse" />
+        </operation>
+        <operation name="salesOrderInfo">
+            <documentation>Retrieve order information</documentation>
+            <input message="typens:salesOrderInfoRequest" />
+            <output message="typens:salesOrderInfoResponse" />
+        </operation>
+        <operation name="salesOrderAddComment">
+            <documentation>Add comment to order</documentation>
+            <input message="typens:salesOrderAddCommentRequest" />
+            <output message="typens:salesOrderAddCommentResponse" />
+        </operation>
+        <operation name="salesOrderHold">
+            <documentation>Hold order</documentation>
+            <input message="typens:salesOrderHoldRequest" />
+            <output message="typens:salesOrderHoldResponse" />
+        </operation>
+        <operation name="salesOrderUnhold">
+            <documentation>Unhold order</documentation>
+            <input message="typens:salesOrderUnholdRequest" />
+            <output message="typens:salesOrderUnholdResponse" />
+        </operation>
+        <operation name="salesOrderCancel">
+            <documentation>Cancel order</documentation>
+            <input message="typens:salesOrderCancelRequest" />
+            <output message="typens:salesOrderCancelResponse" />
+        </operation>
+        <operation name="salesOrderShipmentList">
+            <documentation>Retrieve list of shipments by filters</documentation>
+            <input message="typens:salesOrderShipmentListRequest" />
+            <output message="typens:salesOrderShipmentListResponse" />
+        </operation>
+        <operation name="salesOrderShipmentInfo">
+            <documentation>Retrieve shipment information</documentation>
+            <input message="typens:salesOrderShipmentInfoRequest" />
+            <output message="typens:salesOrderShipmentInfoResponse" />
+        </operation>
+        <operation name="salesOrderShipmentCreate">
+            <documentation>Create new shipment for order</documentation>
+            <input message="typens:salesOrderShipmentCreateRequest" />
+            <output message="typens:salesOrderShipmentCreateResponse" />
+        </operation>
+        <operation name="salesOrderShipmentAddComment">
+            <documentation>Add new comment to shipment</documentation>
+            <input message="typens:salesOrderShipmentAddCommentRequest" />
+            <output message="typens:salesOrderShipmentAddCommentResponse" />
+        </operation>
+        <operation name="salesOrderShipmentAddTrack">
+            <documentation>Add new tracking number</documentation>
+            <input message="typens:salesOrderShipmentAddTrackRequest" />
+            <output message="typens:salesOrderShipmentAddTrackResponse" />
+        </operation>
+        <operation name="salesOrderShipmentSendInfo">
+            <documentation>Send shipment info</documentation>
+            <input message="typens:salesOrderShipmentSendInfoRequest" />
+            <output message="typens:salesOrderShipmentSendInfoResponse" />
+        </operation>
+        <operation name="salesOrderShipmentRemoveTrack">
+            <documentation>Remove tracking number</documentation>
+            <input message="typens:salesOrderShipmentRemoveTrackRequest" />
+            <output message="typens:salesOrderShipmentRemoveTrackResponse" />
+        </operation>
+        <operation name="salesOrderShipmentGetCarriers">
+            <documentation>Retrieve list of allowed carriers for order</documentation>
+            <input message="typens:salesOrderShipmentGetCarriersRequest" />
+            <output message="typens:salesOrderShipmentGetCarriersResponse" />
+        </operation>
+        <operation name="salesOrderInvoiceList">
+            <documentation>Retrieve list of invoices by filters</documentation>
+            <input message="typens:salesOrderInvoiceListRequest" />
+            <output message="typens:salesOrderInvoiceListResponse" />
+        </operation>
+        <operation name="salesOrderInvoiceInfo">
+            <documentation>Retrieve invoice information</documentation>
+            <input message="typens:salesOrderInvoiceInfoRequest" />
+            <output message="typens:salesOrderInvoiceInfoResponse" />
+        </operation>
+        <operation name="salesOrderInvoiceCreate">
+            <documentation>Create new invoice for order</documentation>
+            <input message="typens:salesOrderInvoiceCreateRequest" />
+            <output message="typens:salesOrderInvoiceCreateResponse" />
+        </operation>
+        <operation name="salesOrderInvoiceAddComment">
+            <documentation>Add new comment to shipment</documentation>
+            <input message="typens:salesOrderInvoiceAddCommentRequest" />
+            <output message="typens:salesOrderInvoiceAddCommentResponse" />
+        </operation>
+        <operation name="salesOrderInvoiceCapture">
+            <documentation>Capture invoice</documentation>
+            <input message="typens:salesOrderInvoiceCaptureRequest" />
+            <output message="typens:salesOrderInvoiceCaptureResponse" />
+        </operation>
+        <operation name="salesOrderInvoiceVoid">
+            <documentation>Void invoice</documentation>
+            <input message="typens:salesOrderInvoiceVoidRequest" />
+            <output message="typens:salesOrderInvoiceVoidResponse" />
+        </operation>
+        <operation name="salesOrderInvoiceCancel">
+            <documentation>Cancel invoice</documentation>
+            <input message="typens:salesOrderInvoiceCancelRequest" />
+            <output message="typens:salesOrderInvoiceCancelResponse" />
+        </operation>
+        <operation name="salesOrderCreditmemoList">
+            <documentation>Retrieve list of creditmemos by filters</documentation>
+            <input message="typens:salesOrderCreditmemoListRequest" />
+            <output message="typens:salesOrderCreditmemoListResponse" />
+        </operation>
+        <operation name="salesOrderCreditmemoInfo">
+            <documentation>Retrieve creditmemo information</documentation>
+            <input message="typens:salesOrderCreditmemoInfoRequest" />
+            <output message="typens:salesOrderCreditmemoInfoResponse" />
+        </operation>
+        <operation name="salesOrderCreditmemoCreate">
+            <documentation>Create new creditmemo for order</documentation>
+            <input message="typens:salesOrderCreditmemoCreateRequest" />
+            <output message="typens:salesOrderCreditmemoCreateResponse" />
+        </operation>
+        <operation name="salesOrderCreditmemoAddComment">
+            <documentation>Add new comment to shipment</documentation>
+            <input message="typens:salesOrderCreditmemoAddCommentRequest" />
+            <output message="typens:salesOrderCreditmemoAddCommentResponse" />
+        </operation>
+        <operation name="salesOrderCreditmemoCancel">
+            <documentation>Cancel creditmemo</documentation>
+            <input message="typens:salesOrderCreditmemoCancelRequest" />
+            <output message="typens:salesOrderCreditmemoCancelResponse" />
+        </operation>
+    </portType>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="salesOrderList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderAddComment">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderHold">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderUnhold">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderCancel">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderShipmentList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderShipmentInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderShipmentCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderShipmentAddComment">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderShipmentAddTrack">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderShipmentSendInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderShipmentRemoveTrack">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderShipmentGetCarriers">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderInvoiceList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderInvoiceInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderInvoiceCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderInvoiceAddComment">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderInvoiceCapture">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderInvoiceVoid">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderInvoiceCancel">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderCreditmemoList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderCreditmemoInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderCreditmemoCreate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderCreditmemoAddComment">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+        <operation name="salesOrderCreditmemoCancel">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/Sales/etc/wsi.xml b/app/code/core/Mage/Sales/etc/wsi.xml
new file mode 100644
index 00000000000..0d697c86ce8
--- /dev/null
+++ b/app/code/core/Mage/Sales/etc/wsi.xml
@@ -0,0 +1,1686 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="salesOrderEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="subtotal" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="grand_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_paid" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_qty_ordered" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_online_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_offline_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_subtotal" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_grand_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_paid" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_qty_ordered" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_online_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_offline_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_address_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_address_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_to_base_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_to_global_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weight" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="remote_ip" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="status" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="state" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="applied_rule_ids" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="global_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_method" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_email" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="quote_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_virtual" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_group_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_note_notify" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_is_guest" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="email_sent" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_message_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_message" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_address" type="typens:salesOrderAddressEntity" minOccurs="0" />
+                    <xsd:element name="billing_address" type="typens:salesOrderAddressEntity" minOccurs="0" />
+                    <xsd:element name="items" type="typens:salesOrderItemEntityArray" minOccurs="0" />
+                    <xsd:element name="payment" type="typens:salesOrderPaymentEntity" minOccurs="0" />
+                    <xsd:element name="status_history" type="typens:salesOrderStatusHistoryEntityArray" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderListEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="subtotal" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="grand_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_paid" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_qty_ordered" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_online_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_offline_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_subtotal" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_grand_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_paid" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_qty_ordered" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_online_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_offline_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_address_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_address_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_to_base_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_to_global_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weight" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="remote_ip" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="status" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="state" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="applied_rule_ids" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="global_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_method" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_email" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="quote_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_virtual" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_group_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_note_notify" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_is_guest" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="email_sent" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_message_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="coupon_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="protect_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_discount_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_discount_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_discount_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_subtotal_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_subtotal_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_subtotal_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_invoiced_cost" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="subtotal_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="subtotal_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="subtotal_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="can_ship_partially" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="can_ship_partially_item" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="edit_increment" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="forced_do_shipment_with_invoice" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="payment_authorization_expiration" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="paypal_ipn_customer_notified" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="quote_address_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="adjustment_negative" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="adjustment_positive" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_adjustment_negative" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_adjustment_positive" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_subtotal_incl_tax" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_total_due" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="payment_authorization_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="subtotal_incl_tax" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_due" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_dob" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_middlename" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_prefix" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_suffix" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_taxvat" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_description" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="ext_customer_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="ext_order_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="hold_before_state" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="hold_before_status" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="original_increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="relation_child_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="relation_child_real_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="relation_parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="relation_parent_real_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="x_forwarded_for" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_note" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_item_count" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_gender" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_hidden_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="hidden_tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_hidden_tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="hidden_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_hidden_tax_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_incl_tax" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_incl_tax" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_customer_balance_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_balance_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_customer_balance_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_balance_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_customer_balance_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_balance_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="bs_customer_bal_total_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="customer_bal_total_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_cards" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_gift_cards_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_cards_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_gift_cards_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_cards_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_gift_cards_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_cards_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="reward_points_balance" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_reward_currency_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="reward_currency_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_rwrd_crrncy_amt_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="rwrd_currency_amount_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_rwrd_crrncy_amnt_refnded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="rwrd_crrncy_amnt_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="reward_points_balance_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="reward_points_balance_refund" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="reward_salesrule_points" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="telephone" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="postcode" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderListEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderListEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderAddressEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="address_type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="company" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="street" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="city" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="region" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="postcode" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="country_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="telephone" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="fax" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="region_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="address_id" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderItemEntity">
+                <xsd:sequence>
+                    <xsd:element name="item_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="quote_item_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="product_type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="product_options" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weight" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_virtual" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="applied_rule_ids" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="free_shipping" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_qty_decimal" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="no_discount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty_canceled" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty_ordered" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty_shipped" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cost" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="original_price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_original_price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_percent" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_percent" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_discount_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="amount_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_amount_refunded" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="row_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_row_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="row_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_row_invoiced" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="row_weight" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_message_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_message" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="gift_message_available" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_before_discount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_before_discount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_applied" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_weee_tax_applied_row_amnt" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderItemEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderItemEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="orderItemIdQty">
+                <xsd:sequence>
+                    <xsd:element name="order_item_id" type="xsd:int" />
+                    <xsd:element name="qty" type="xsd:double" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="orderItemIdQtyArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:orderItemIdQty" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderPaymentEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="amount_ordered" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_amount_ordered" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="method" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="po_number" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cc_type" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cc_number_enc" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cc_last4" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cc_owner" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cc_exp_month" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cc_exp_year" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cc_ss_start_month" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cc_ss_start_year" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="payment_id" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderStatusHistoryEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_customer_notified" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="status" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="comment" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderStatusHistoryEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderStatusHistoryEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderShipmentEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_address_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="total_qty" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="items" type="typens:salesOrderShipmentItemEntityArray" minOccurs="0" />
+                    <xsd:element name="tracks" type="typens:salesOrderShipmentTrackEntityArray" minOccurs="0" />
+                    <xsd:element name="comments" type="typens:salesOrderShipmentCommentEntityArray" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderShipmentEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderShipmentEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderShipmentCommentEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="comment" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_customer_notified" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="comment_id" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderShipmentCommentEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderShipmentCommentEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderShipmentTrackEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="carrier_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="title" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="number" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="track_id" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderShipmentTrackEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderShipmentTrackEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderShipmentItemEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_item_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weight" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="item_id" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderShipmentItemEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderShipmentItemEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderInvoiceEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="global_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_currency_code" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_to_base_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="store_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_to_global_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_to_order_rate" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="subtotal" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_subtotal" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_grand_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_discount_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="shipping_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_shipping_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_address_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_firstname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="billing_lastname" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="state" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="grand_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="invoice_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="items" type="typens:salesOrderInvoiceItemEntityArray" minOccurs="0" />
+                    <xsd:element name="comments" type="typens:salesOrderInvoiceCommentEntityArray" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderInvoiceEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderInvoiceEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderInvoiceItemEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_applied" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="qty" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="cost" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="row_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_price" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_tax_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_row_total" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_weee_tax_applied_row_amnt" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_applied_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_weee_tax_disposition" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="base_weee_tax_row_disposition" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="order_item_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="item_id" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderInvoiceItemEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderInvoiceItemEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderInvoiceCommentEntity">
+                <xsd:sequence>
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_active" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="comment" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="is_customer_notified" type="xsd:string" minOccurs="0" />
+                    <xsd:element name="comment_id" type="xsd:string" minOccurs="0" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderInvoiceCommentEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderInvoiceCommentEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderCreditmemoEntity">
+                <xsd:sequence>
+                    <xsd:element name="updated_at" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="increment_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="transaction_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="global_currency_code" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_currency_code" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="order_currency_code" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="store_currency_code" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="cybersource_token" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="invoice_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="billing_address_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="shipping_address_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="state" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="creditmemo_status" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="email_sent" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="order_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="shipping_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_adjustment_positive" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_grand_total" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="adjustment" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="subtotal" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="discount_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_subtotal" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_adjustment" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_to_global_rate" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="store_to_base_rate" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_shipping_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="adjustment_negative" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="subtotal_incl_tax" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="shipping_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_subtotal_incl_tax" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_adjustment_negative" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="grand_total" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_discount_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_to_order_rate" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="store_to_order_rate" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_shipping_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="adjustment_positive" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="store_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="hidden_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_hidden_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="shipping_hidden_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_shipping_hidden_tax_amnt" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="shipping_incl_tax" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_shipping_incl_tax" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_customer_balance_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="customer_balance_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="bs_customer_bal_total_refunded" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="customer_bal_total_refunded" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_gift_cards_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gift_cards_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_base_price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_items_base_price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_items_price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_card_base_price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_card_price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_base_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_items_base_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_items_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_card_base_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="gw_card_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_reward_currency_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="reward_currency_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="reward_points_balance" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="reward_points_balance_refund" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="creditmemo_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="items" type="typens:salesOrderCreditmemoItemEntityArray" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="comments" type="typens:salesOrderCreditmemoCommentEntityArray" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderCreditmemoEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderCreditmemoEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderCreditmemoItemEntity">
+                <xsd:sequence>
+                    <xsd:element name="item_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_weee_tax_row_disposition" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_weee_tax_applied_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="weee_tax_row_disposition" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_row_total" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="discount_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="row_total" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="weee_tax_applied_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_discount_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_weee_tax_disposition" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="price_incl_tax" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="weee_tax_disposition" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_price_incl_tax" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="qty" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_cost" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_weee_tax_applied_row_amount" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="price" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_row_total_incl_tax" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="row_total_incl_tax" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="order_item_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="additional_data" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="description" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="weee_tax_applied" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="sku" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="hidden_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+                    <xsd:element name="base_hidden_tax_amount" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderCreditmemoItemEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderCreditmemoItemEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderCreditmemoCommentEntity">
+                <xsd:sequence>
+                    <xsd:element name="parent_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="created_at" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="comment" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_customer_notified" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="comment_id" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="is_visible_on_front" type="xsd:string" minOccurs="0" maxOccurs="1"/>
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderCreditmemoCommentEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:salesOrderCreditmemoCommentEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="salesOrderCreditmemoData">
+                <xsd:sequence>
+                    <xsd:element name="qtys" type="typens:orderItemIdQtyArray" minOccurs="0" maxOccurs="1"/>
+                    <xsd:element name="shipping_amount" type="xsd:double" minOccurs="0" maxOccurs="1"/>
+                    <xsd:element name="adjustment_positive" type="xsd:double" minOccurs="0" maxOccurs="1"/>
+                    <xsd:element name="adjustment_negative" type="xsd:double" minOccurs="0" maxOccurs="1"/>
+                </xsd:sequence>
+            </xsd:complexType>
+
+            <xsd:element name="salesOrderListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="filters" type="typens:filters" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:salesOrderListEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="orderIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:salesOrderEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderAddCommentRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="orderIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="status" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="comment" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="notify" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderAddCommentResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderHoldRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="orderIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderHoldResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderUnholdRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="orderIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderUnholdResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCancelRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="orderIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCancelResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="filters" type="typens:filters" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:salesOrderShipmentEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="shipmentIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:salesOrderShipmentEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="orderIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="itemsQty" type="typens:orderItemIdQtyArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="comment" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="email" type="xsd:int" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="includeComment" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentAddTrackRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="shipmentIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="carrier" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="title" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="trackNumber" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentAddTrackResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentRemoveTrackRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="shipmentIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="trackId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentRemoveTrackResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentSendInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="shipmentIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="comment" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentSendInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentAddCommentRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="shipmentIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="comment" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="email" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="includeInEmail" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentAddCommentResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentGetCarriersRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="orderIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderShipmentGetCarriersResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:associativeArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="filters" type="typens:filters" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:salesOrderInvoiceEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="invoiceIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:salesOrderInvoiceEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="orderIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="itemsQty" type="typens:orderItemIdQtyArray" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="comment" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="email" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="includeComment" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceAddCommentRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="invoiceIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="comment" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="email" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="includeComment" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceAddCommentResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceCaptureRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="invoiceIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceCaptureResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceVoidRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="invoiceIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceVoidResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceCancelRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="invoiceIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderInvoiceCancelResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="filters" type="typens:filters" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:salesOrderCreditmemoEntityArray" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="creditmemoIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:salesOrderCreditmemoEntity" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoCreateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="creditmemoIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="creditmemoData" type="typens:salesOrderCreditmemoData" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="comment" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="notifyCustomer" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="includeComment" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="refundToStoreCreditAmount" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoCreateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoAddCommentRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="creditmemoIncrementId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="comment" type="xsd:string" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="notifyCustomer" type="xsd:int" />
+                        <xsd:element minOccurs="0" maxOccurs="1" name="includeComment" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoAddCommentResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoCancelRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
+                        <xsd:element minOccurs="1" maxOccurs="1" name="creditmemoIncrementId" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="salesOrderCreditmemoCancelResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+    <wsdl:message name="salesOrderListRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderListResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInfoRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInfoResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderAddCommentRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderAddCommentRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderAddCommentResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderAddCommentResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderHoldRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderHoldRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderHoldResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderHoldResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderUnholdRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderUnholdRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderUnholdResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderUnholdResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCancelRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderCancelRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCancelResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderCancelResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentListRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentListResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentInfoRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentInfoResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentCreateRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentCreateResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentAddCommentRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentAddCommentRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentAddCommentResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentAddCommentResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentAddTrackRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentAddTrackRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentAddTrackResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentAddTrackResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentRemoveTrackRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentRemoveTrackRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentRemoveTrackResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentRemoveTrackResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentSendInfoRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentSendInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentSendInfoResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentSendInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentGetCarriersRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentGetCarriersRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderShipmentGetCarriersResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderShipmentGetCarriersResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceListRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceListResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceInfoRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceInfoResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceCreateRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceCreateResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceAddCommentRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceAddCommentRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceAddCommentResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceAddCommentResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceCaptureRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceCaptureRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceCaptureResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceCaptureResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceVoidRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceVoidRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceVoidResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceVoidResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceCancelRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceCancelRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderInvoiceCancelResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderInvoiceCancelResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoListRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoListResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoInfoRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoInfoResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoCreateRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoCreateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoCreateResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoCreateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoAddCommentRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoAddCommentRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoAddCommentResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoAddCommentResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoCancelRequest">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoCancelRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="salesOrderCreditmemoCancelResponse">
+        <wsdl:part name="parameters" element="typens:salesOrderCreditmemoCancelResponseParam" />
+    </wsdl:message>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="salesOrderList">
+            <wsdl:documentation>Retrieve list of orders by filters</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderListRequest" />
+            <wsdl:output message="typens:salesOrderListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInfo">
+            <wsdl:documentation>Retrieve order information</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderInfoRequest" />
+            <wsdl:output message="typens:salesOrderInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderAddComment">
+            <wsdl:documentation>Add comment to order</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderAddCommentRequest" />
+            <wsdl:output message="typens:salesOrderAddCommentResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderHold">
+            <wsdl:documentation>Hold order</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderHoldRequest" />
+            <wsdl:output message="typens:salesOrderHoldResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderUnhold">
+            <wsdl:documentation>Unhold order</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderUnholdRequest" />
+            <wsdl:output message="typens:salesOrderUnholdResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCancel">
+            <wsdl:documentation>Cancel order</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderCancelRequest" />
+            <wsdl:output message="typens:salesOrderCancelResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentList">
+            <wsdl:documentation>Retrieve list of shipments by filters</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderShipmentListRequest" />
+            <wsdl:output message="typens:salesOrderShipmentListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentInfo">
+            <wsdl:documentation>Retrieve shipment information</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderShipmentInfoRequest" />
+            <wsdl:output message="typens:salesOrderShipmentInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentCreate">
+            <wsdl:documentation>Create new shipment for order</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderShipmentCreateRequest" />
+            <wsdl:output message="typens:salesOrderShipmentCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentAddComment">
+            <wsdl:documentation>Add new comment to shipment</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderShipmentAddCommentRequest" />
+            <wsdl:output message="typens:salesOrderShipmentAddCommentResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentAddTrack">
+            <wsdl:documentation>Add new tracking number</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderShipmentAddTrackRequest" />
+            <wsdl:output message="typens:salesOrderShipmentAddTrackResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentRemoveTrack">
+            <wsdl:documentation>Remove tracking number</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderShipmentRemoveTrackRequest" />
+            <wsdl:output message="typens:salesOrderShipmentRemoveTrackResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentSendInfo">
+            <wsdl:documentation>Send shipment info</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderShipmentSendInfoRequest" />
+            <wsdl:output message="typens:salesOrderShipmentSendInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentGetCarriers">
+            <wsdl:documentation>Retrieve list of allowed carriers for order</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderShipmentGetCarriersRequest" />
+            <wsdl:output message="typens:salesOrderShipmentGetCarriersResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceList">
+            <wsdl:documentation>Retrieve list of invoices by filters</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderInvoiceListRequest" />
+            <wsdl:output message="typens:salesOrderInvoiceListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceInfo">
+            <wsdl:documentation>Retrieve invoice information</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderInvoiceInfoRequest" />
+            <wsdl:output message="typens:salesOrderInvoiceInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceCreate">
+            <wsdl:documentation>Create new invoice for order</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderInvoiceCreateRequest" />
+            <wsdl:output message="typens:salesOrderInvoiceCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceAddComment">
+            <wsdl:documentation>Add new comment to shipment</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderInvoiceAddCommentRequest" />
+            <wsdl:output message="typens:salesOrderInvoiceAddCommentResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceCapture">
+            <wsdl:documentation>Capture invoice</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderInvoiceCaptureRequest" />
+            <wsdl:output message="typens:salesOrderInvoiceCaptureResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceVoid">
+            <wsdl:documentation>Void invoice</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderInvoiceVoidRequest" />
+            <wsdl:output message="typens:salesOrderInvoiceVoidResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceCancel">
+            <wsdl:documentation>Cancel invoice</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderInvoiceCancelRequest" />
+            <wsdl:output message="typens:salesOrderInvoiceCancelResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoList">
+            <wsdl:documentation>Retrieve list of creditmemos by filters</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderCreditmemoListRequest" />
+            <wsdl:output message="typens:salesOrderCreditmemoListResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoInfo">
+            <wsdl:documentation>Retrieve creditmemo information</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderCreditmemoInfoRequest" />
+            <wsdl:output message="typens:salesOrderCreditmemoInfoResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoCreate">
+            <wsdl:documentation>Create new creditmemo for order</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderCreditmemoCreateRequest" />
+            <wsdl:output message="typens:salesOrderCreditmemoCreateResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoAddComment">
+            <wsdl:documentation>Add new comment to creditmemo</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderCreditmemoAddCommentRequest" />
+            <wsdl:output message="typens:salesOrderCreditmemoAddCommentResponse" />
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoCancel">
+            <wsdl:documentation>Cancel creditmemo</wsdl:documentation>
+            <wsdl:input message="typens:salesOrderCreditmemoCancelRequest" />
+            <wsdl:output message="typens:salesOrderCreditmemoCancelResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="salesOrderList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderAddComment">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderHold">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderUnhold">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCancel">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentAddComment">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentAddTrack">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentRemoveTrack">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentSendInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderShipmentGetCarriers">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceAddComment">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceCapture">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceVoid">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderInvoiceCancel">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoCreate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoAddComment">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+        <wsdl:operation name="salesOrderCreditmemoCancel">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:service name="{{var wsdl.name}}Service">
+        <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/Tag/Block/Adminhtml/Catalog/Product/Edit/Tab/Tag.php b/app/code/core/Mage/Tag/Block/Adminhtml/Catalog/Product/Edit/Tab/Tag.php
index c9a841d36f9..85dff9eccc9 100644
--- a/app/code/core/Mage/Tag/Block/Adminhtml/Catalog/Product/Edit/Tab/Tag.php
+++ b/app/code/core/Mage/Tag/Block/Adminhtml/Catalog/Product/Edit/Tab/Tag.php
@@ -72,6 +72,8 @@ class Mage_Tag_Block_Adminhtml_Catalog_Product_Edit_Tab_Tag
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_Authorization $authSession
      * @param array $data
@@ -89,12 +91,14 @@ class Mage_Tag_Block_Adminhtml_Catalog_Product_Edit_Tab_Tag
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_Authorization $authSession,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
 
         if (isset($data['helpers'])) {
diff --git a/app/code/core/Mage/Tag/Block/Adminhtml/Catalog/Product/Edit/Tab/Tag/Customer.php b/app/code/core/Mage/Tag/Block/Adminhtml/Catalog/Product/Edit/Tab/Tag/Customer.php
index 857a7fa2702..b8e88378574 100644
--- a/app/code/core/Mage/Tag/Block/Adminhtml/Catalog/Product/Edit/Tab/Tag/Customer.php
+++ b/app/code/core/Mage/Tag/Block/Adminhtml/Catalog/Product/Edit/Tab/Tag/Customer.php
@@ -71,7 +71,9 @@ class Mage_Tag_Block_Adminhtml_Catalog_Product_Edit_Tab_Tag_Customer
      * @param Mage_Core_Model_Session $session
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
-     * @param Mage_Core_Model_Factory_Helper $helperFactory,
+     * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem,
      * @param Mage_Core_Model_Authorization $authSession
      * @param array $data
@@ -90,12 +92,15 @@ class Mage_Tag_Block_Adminhtml_Catalog_Product_Edit_Tab_Tag_Customer
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_Authorization $authSession,
         array $data = array()
     ) {
-        parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage, $session,
-            $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+        parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
+        );
 
         if (isset($data['helpers'])) {
             $this->_helpers = $data['helpers'];
diff --git a/app/code/core/Mage/Tag/Block/Adminhtml/Customer/Edit/Tab/Tag.php b/app/code/core/Mage/Tag/Block/Adminhtml/Customer/Edit/Tab/Tag.php
index 9b131ff2b87..355bb0961b4 100644
--- a/app/code/core/Mage/Tag/Block/Adminhtml/Customer/Edit/Tab/Tag.php
+++ b/app/code/core/Mage/Tag/Block/Adminhtml/Customer/Edit/Tab/Tag.php
@@ -53,7 +53,7 @@ class Mage_Tag_Block_Adminhtml_Customer_Edit_Tab_Tag extends Mage_Backend_Block_
     protected $_authSession;
 
     /**
-     * Class constructor
+     * Constructor
      *
      * @param Mage_Core_Controller_Request_Http $request
      * @param Mage_Core_Model_Layout $layout
@@ -66,6 +66,8 @@ class Mage_Tag_Block_Adminhtml_Customer_Edit_Tab_Tag extends Mage_Backend_Block_
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Core_Model_Authorization $authSession
      * @param array $data
@@ -83,12 +85,15 @@ class Mage_Tag_Block_Adminhtml_Customer_Edit_Tab_Tag extends Mage_Backend_Block_
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Core_Model_Authorization $authSession,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data);
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
+        );
 
         $this->_authSession = $authSession;
         if (isset($data['helpers'])) {
diff --git a/app/code/core/Mage/Tag/Model/Api.php b/app/code/core/Mage/Tag/Model/Api.php
new file mode 100644
index 00000000000..b3d8d716ec0
--- /dev/null
+++ b/app/code/core/Mage/Tag/Model/Api.php
@@ -0,0 +1,245 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Tag
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Product Tag API
+ *
+ * @category   Mage
+ * @package    Mage_Tag
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Tag_Model_Api extends Mage_Catalog_Model_Api_Resource
+{
+    /**
+     * Retrieve list of tags for specified product
+     *
+     * @param int $productId
+     * @param string|int $store
+     * @return array
+     */
+    public function items($productId, $store = null)
+    {
+        $result = array();
+        // fields list to return
+        $fieldsForResult = array('tag_id', 'name');
+
+        /** @var $product Mage_Catalog_Model_Product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product')->load($productId);
+        if (!$product->getId()) {
+            $this->_fault('product_not_exists');
+        }
+
+        /** @var $tags Mage_Tag_Model_Resource_Tag_Collection */
+        $tags = Mage::getModel('Mage_Tag_Model_Tag')->getCollection()->joinRel()->addProductFilter($productId);
+        if ($store) {
+            $tags->addStoreFilter($this->_getStoreId($store));
+        }
+
+        /** @var $tag Mage_Tag_Model_Tag */
+        foreach ($tags as $tag) {
+            $result[$tag->getId()] = $tag->toArray($fieldsForResult);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve tag info as array('name'-> .., 'status' => ..,
+     * 'base_popularity' => .., 'products' => array($productId => $popularity, ...))
+     *
+     * @param int $tagId
+     * @param string|int $store
+     * @return array
+     */
+    public function info($tagId, $store)
+    {
+        $result = array();
+        $storeId = $this->_getStoreId($store);
+        /** @var $tag Mage_Tag_Model_Tag */
+        $tag = Mage::getModel('Mage_Tag_Model_Tag')->setStoreId($storeId)->setAddBasePopularity()->load($tagId);
+        if (!$tag->getId()) {
+            $this->_fault('tag_not_exists');
+        }
+        $result['status'] = $tag->getStatus();
+        $result['name'] = $tag->getName();
+        $result['base_popularity'] = (is_numeric($tag->getBasePopularity())) ? $tag->getBasePopularity() : 0;
+        // retrieve array($productId => $popularity, ...)
+        $result['products'] = array();
+        $relatedProductsCollection = $tag->getEntityCollection()->addTagFilter($tagId)
+            ->addStoreFilter($storeId)->addPopularity($tagId);
+        foreach ($relatedProductsCollection as $product) {
+            $result['products'][$product->getId()] = $product->getPopularity();
+        }
+
+        return $result;
+    }
+
+    /**
+     * Add tag(s) to product.
+     * Return array of added/updated tags as array($tagName => $tagId, ...)
+     *
+     * @param array $data
+     * @return array
+     */
+    public function add($data)
+    {
+        $data = $this->_prepareDataForAdd($data);
+        /** @var $product Mage_Catalog_Model_Product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product')->load($data['product_id']);
+        if (!$product->getId()) {
+            $this->_fault('product_not_exists');
+        }
+        /** @var $customer Mage_Customer_Model_Customer */
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')->load($data['customer_id']);
+        if (!$customer->getId()) {
+            $this->_fault('customer_not_exists');
+        }
+        $storeId = $this->_getStoreId($data['store']);
+
+        try {
+            /** @var $tag Mage_Tag_Model_Tag */
+            $tag = Mage::getModel('Mage_Tag_Model_Tag');
+            $tagHelper = Mage::helper('Mage_Tag_Helper_Data');
+            $tagNamesArr = $tagHelper->cleanTags($tagHelper->extractTags($data['tag']));
+            foreach ($tagNamesArr as $tagName) {
+                // unset previously added tag data
+                $tag->unsetData();
+                $tag->loadByName($tagName);
+                if (!$tag->getId()) {
+                    $tag->setName($tagName)
+                        ->setFirstCustomerId($customer->getId())
+                        ->setFirstStoreId($storeId)
+                        ->setStatus($tag->getPendingStatus())
+                        ->save();
+                }
+                $tag->saveRelation($product->getId(), $customer->getId(), $storeId);
+                $result[$tagName] = $tag->getId();
+            }
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('save_error', $e->getMessage());
+        }
+
+        return $result;
+    }
+
+    /**
+     * Change existing tag information
+     *
+     * @param int $tagId
+     * @param array $data
+     * @param string|int $store
+     * @return bool
+     */
+    public function update($tagId, $data, $store)
+    {
+        $data = $this->_prepareDataForUpdate($data);
+        $storeId = $this->_getStoreId($store);
+        /** @var $tag Mage_Tag_Model_Tag */
+        $tag = Mage::getModel('Mage_Tag_Model_Tag')->setStoreId($storeId)->setAddBasePopularity()->load($tagId);
+        if (!$tag->getId()) {
+            $this->_fault('tag_not_exists');
+        }
+
+        // store should be set for 'base_popularity' to be saved in Mage_Tag_Model_Resource_Tag::_afterSave()
+        $tag->setStore($storeId);
+        if (isset($data['base_popularity'])) {
+            $tag->setBasePopularity($data['base_popularity']);
+        }
+        if (isset($data['name'])) {
+            $tag->setName(trim($data['name']));
+        }
+        if (isset($data['status'])) {
+            // validate tag status
+            if (!in_array($data['status'], array(
+                $tag->getApprovedStatus(), $tag->getPendingStatus(), $tag->getDisabledStatus()))) {
+                $this->_fault('invalid_data');
+            }
+            $tag->setStatus($data['status']);
+        }
+
+        try {
+            $tag->save();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('save_error', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Remove existing tag
+     *
+     * @param int $tagId
+     * @return bool
+     */
+    public function remove($tagId)
+    {
+        /** @var $tag Mage_Tag_Model_Tag */
+        $tag = Mage::getModel('Mage_Tag_Model_Tag')->load($tagId);
+        if (!$tag->getId()) {
+            $this->_fault('tag_not_exists');
+        }
+        try {
+            $tag->delete();
+        } catch (Mage_Core_Exception $e) {
+            $this->_fault('remove_error', $e->getMessage());
+        }
+
+        return true;
+    }
+
+    /**
+     * Check data before add
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function _prepareDataForAdd($data)
+    {
+        if (!isset($data['product_id']) or !isset($data['tag'])
+            or !isset($data['customer_id']) or !isset($data['store'])) {
+            $this->_fault('invalid_data');
+        }
+
+        return $data;
+    }
+
+    /**
+     * Check data before update
+     *
+     * @param $data
+     * @return
+     */
+    protected function _prepareDataForUpdate($data)
+    {
+        // $data should contain at least one field to change
+        if ( !(isset($data['name']) or isset($data['status']) or isset($data['base_popularity']))) {
+            $this->_fault('invalid_data');
+        }
+
+        return $data;
+    }
+}
diff --git a/app/code/core/Mage/Tag/Model/Api/V2.php b/app/code/core/Mage/Tag/Model/Api/V2.php
new file mode 100644
index 00000000000..75650247993
--- /dev/null
+++ b/app/code/core/Mage/Tag/Model/Api/V2.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Tag
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Product Tag API
+ *
+ * @category   Mage
+ * @package    Mage_Tag
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Mage_Tag_Model_Api_V2 extends Mage_Tag_Model_Api
+{
+    /**
+     * Retrieve list of tags for specified product as array of objects
+     *
+     * @param int $productId
+     * @param string|int $store
+     * @return array
+     */
+    public function items($productId, $store = null)
+    {
+        $result = parent::items($productId, $store);
+        foreach ($result as $key => $tag) {
+            $result[$key] = Mage::helper('Mage_Api_Helper_Data')->wsiArrayPacker($tag);
+        }
+        return array_values($result);
+    }
+
+    /**
+     * Add tag(s) to product.
+     * Return array of objects
+     *
+     * @param array $data
+     * @return array
+     */
+    public function add($data)
+    {
+        $result = array();
+        foreach (parent::add($data) as $key => $value) {
+            $result[] = array('key' => $key, 'value' => $value);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieve tag info as object
+     *
+     * @param int $tagId
+     * @param string|int $store
+     * @return object
+     */
+    public function info($tagId, $store)
+    {
+        $result = parent::info($tagId, $store);
+        $result = Mage::helper('Mage_Api_Helper_Data')->wsiArrayPacker($result);
+        foreach ($result->products as $key => $value) {
+            $result->products[$key] = array('key' => $key, 'value' => $value);
+        }
+        return $result;
+    }
+
+    /**
+     * Convert data from object to array before add
+     *
+     * @param object $data
+     * @return array
+     */
+    protected function _prepareDataForAdd($data)
+    {
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::_prepareDataForAdd($data);
+    }
+
+    /**
+     * Convert data from object to array before update
+     *
+     * @param object $data
+     * @return array
+     */
+    protected function _prepareDataForUpdate($data)
+    {
+        Mage::helper('Mage_Api_Helper_Data')->toArray($data);
+        return parent::_prepareDataForUpdate($data);
+    }
+}
diff --git a/app/code/core/Mage/Tag/etc/api.xml b/app/code/core/Mage/Tag/etc/api.xml
new file mode 100644
index 00000000000..f8ca46a630d
--- /dev/null
+++ b/app/code/core/Mage/Tag/etc/api.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Mage
+ * @package     Mage_Tag
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config>
+    <api>
+        <resources>
+            <catalog_product_tag translate="title" module="Mage_Tag">
+                <title>Product Tag API</title>
+                <model>Mage_Tag_Model_Api</model>
+                <acl>catalog/product/tag</acl>
+                <methods>
+                    <list translate="title" module="Mage_Tag">
+                        <title>Retrieve list of tags by product</title>
+                        <method>items</method>
+                        <acl>catalog/product/tag/list</acl>
+                    </list>
+                    <info translate="title" module="Mage_Tag">
+                        <title>Retrieve product tag info</title>
+                        <acl>catalog/product/tag/info</acl>
+                    </info>
+                    <add translate="title" module="Mage_Tag">
+                        <title>Add tag(s) to product</title>
+                        <acl>catalog/product/tag/add</acl>
+                    </add>
+                    <update translate="title" module="Mage_Tag">
+                        <title>Update product tag</title>
+                        <acl>catalog/product/tag/update</acl>
+                    </update>
+                    <remove translate="title" module="Mage_Tag">
+                        <title>Remove product tag</title>
+                        <acl>catalog/product/tag/remove</acl>
+                    </remove>
+                </methods>
+                <faults module="Mage_Tag">
+                    <store_not_exists>
+                        <code>101</code>
+                        <message>Requested store does not exist.</message>
+                    </store_not_exists>
+                    <product_not_exists>
+                        <code>102</code>
+                        <message>Requested product does not exist.</message>
+                    </product_not_exists>
+                    <customer_not_exists>
+                        <code>103</code>
+                        <message>Requested customer does not exist.</message>
+                    </customer_not_exists>
+                    <tag_not_exists>
+                        <code>104</code>
+                        <message>Requested tag does not exist.</message>
+                    </tag_not_exists>
+                    <invalid_data>
+                        <code>105</code>
+                        <message>Provided data is invalid.</message>
+                    </invalid_data>
+                    <save_error>
+                        <code>106</code>
+                        <message>Error occurred while saving tag. Details are in error message.</message>
+                    </save_error>
+                    <remove_error>
+                        <code>107</code>
+                        <message>Error occurred while removing tag. Details are in error message.</message>
+                    </remove_error>
+                </faults>
+            </catalog_product_tag>
+        </resources>
+        <resources_alias>
+            <product_tag>catalog_product_tag</product_tag>
+        </resources_alias>
+        <v2>
+            <resources_function_prefix>
+                <product_tag>catalogProductTag</product_tag>
+            </resources_function_prefix>
+        </v2>
+        <rest>
+            <mapping>
+                <product_tag>
+                    <post>
+                        <method>add</method>
+                    </post>
+                    <delete>
+                        <method>remove</method>
+                    </delete>
+                </product_tag>
+            </mapping>
+        </rest>
+        <acl>
+            <resources>
+                <catalog>
+                    <product>
+                        <tag translate="title" module="Mage_Tag">
+                            <title>Tag</title>
+                            <sort_order>103</sort_order>
+                            <list translate="title" module="Mage_Tag">
+                                <title>List</title>
+                            </list>
+                            <info translate="title" module="Mage_Tag">
+                                <title>Info</title>
+                            </info>
+                            <add translate="title" module="Mage_Tag">
+                                <title>Add</title>
+                            </add>
+                            <update translate="title" module="Mage_Tag">
+                                <title>Update</title>
+                            </update>
+                            <remove translate="title" module="Mage_Tag">
+                                <title>Remove</title>
+                            </remove>
+                        </tag>
+                    </product>
+                </catalog>
+            </resources>
+        </acl>
+    </api>
+</config>
diff --git a/app/code/core/Mage/Tag/etc/wsdl.xml b/app/code/core/Mage/Tag/etc/wsdl.xml
new file mode 100644
index 00000000000..c7d114736c7
--- /dev/null
+++ b/app/code/core/Mage/Tag/etc/wsdl.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
+    name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
+    <types>
+        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
+            <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
+            <complexType name="catalogProductTagListEntity">
+                <all>
+                    <element name="tag_id" type="xsd:string" minOccurs="1" />
+                    <element name="name" type="xsd:string" minOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductTagListEntityArray">
+                <complexContent>
+                    <restriction base="soapenc:Array">
+                        <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogProductTagListEntity[]" />
+                    </restriction>
+                </complexContent>
+            </complexType>
+            <complexType name="catalogProductTagAddEntity">
+                <all>
+                    <element name="tag" type="xsd:string" minOccurs="1" />
+                    <element name="product_id" type="xsd:string" minOccurs="1" />
+                    <element name="customer_id" type="xsd:string" minOccurs="1" />
+                    <element name="store" type="xsd:string" minOccurs="1" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductTagUpdateEntity">
+                <all>
+                    <element name="name" type="xsd:string" minOccurs="0" />
+                    <element name="status" type="xsd:string" minOccurs="0" />
+                    <element name="base_popularity" type="xsd:string" minOccurs="0" />
+                </all>
+            </complexType>
+            <complexType name="catalogProductTagInfoEntity">
+                <all>
+                    <element name="name" type="xsd:string" minOccurs="1" />
+                    <element name="status" type="xsd:string" minOccurs="1" />
+                    <element name="base_popularity" type="xsd:string" minOccurs="1" />
+                    <element name="products" type="typens:associativeArray" minOccurs="1" />
+                </all>
+            </complexType>
+        </schema>
+    </types>
+
+    <message name="catalogProductTagListRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="productId" type="xsd:string" />
+        <part name="store" type="xsd:string" />
+    </message>
+    <message name="catalogProductTagListResponse">
+        <part name="result" type="typens:catalogProductTagListEntityArray" />
+    </message>
+    <message name="catalogProductTagInfoRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="tagId" type="xsd:string" />
+        <part name="store" type="xsd:string" />
+    </message>
+    <message name="catalogProductTagInfoResponse">
+        <part name="result" type="typens:catalogProductTagInfoEntity" />
+    </message>
+    <message name="catalogProductTagAddRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="data" type="typens:catalogProductTagAddEntity" />
+    </message>
+    <message name="catalogProductTagAddResponse">
+        <part name="result" type="typens:associativeArray" />
+    </message>
+    <message name="catalogProductTagUpdateRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="tagId" type="xsd:string" />
+        <part name="data" type="typens:catalogProductTagUpdateEntity" />
+        <part name="store" type="xsd:string" />
+    </message>
+    <message name="catalogProductTagUpdateResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+    <message name="catalogProductTagRemoveRequest">
+        <part name="sessionId" type="xsd:string" />
+        <part name="tagId" type="xsd:string" />
+    </message>
+    <message name="catalogProductTagRemoveResponse">
+        <part name="result" type="xsd:boolean" />
+    </message>
+
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="catalogProductTagList">
+            <documentation>Retrieve list of tags by product</documentation>
+            <input message="typens:catalogProductTagListRequest" />
+            <output message="typens:catalogProductTagListResponse" />
+        </operation>
+    </portType>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="catalogProductTagInfo">
+            <documentation>Retrieve product tag info</documentation>
+            <input message="typens:catalogProductTagInfoRequest" />
+            <output message="typens:catalogProductTagInfoResponse" />
+        </operation>
+    </portType>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="catalogProductTagAdd">
+            <documentation>Add tag(s) to product</documentation>
+            <input message="typens:catalogProductTagAddRequest" />
+            <output message="typens:catalogProductTagAddResponse" />
+        </operation>
+    </portType>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="catalogProductTagUpdate">
+            <documentation>Update product tag</documentation>
+            <input message="typens:catalogProductTagUpdateRequest" />
+            <output message="typens:catalogProductTagUpdateResponse" />
+        </operation>
+    </portType>
+    <portType name="{{var wsdl.handler}}PortType">
+        <operation name="catalogProductTagRemove">
+            <documentation>Remove product tag</documentation>
+            <input message="typens:catalogProductTagRemoveRequest" />
+            <output message="typens:catalogProductTagRemoveResponse" />
+        </operation>
+    </portType>
+
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="catalogProductTagList">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="catalogProductTagInfo">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="catalogProductTagAdd">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="catalogProductTagUpdate">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+    <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
+        <operation name="catalogProductTagRemove">
+            <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
+            <input>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </input>
+            <output>
+                <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
+            </output>
+        </operation>
+    </binding>
+
+    <service name="{{var wsdl.name}}Service">
+        <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </port>
+    </service>
+</definitions>
diff --git a/app/code/core/Mage/Tag/etc/wsi.xml b/app/code/core/Mage/Tag/etc/wsi.xml
new file mode 100644
index 00000000000..615e2a44583
--- /dev/null
+++ b/app/code/core/Mage/Tag/etc/wsi.xml
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+             xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+             name="{{var wsdl.name}}"
+             targetNamespace="urn:{{var wsdl.name}}">
+
+    <wsdl:types>
+        <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
+            <xsd:complexType name="catalogProductTagListEntity">
+                <xsd:sequence>
+                    <xsd:element name="tag_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductTagListEntityArray">
+                <xsd:sequence>
+                    <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:catalogProductTagListEntity" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductTagAddEntity">
+                <xsd:sequence>
+                    <xsd:element name="tag" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="product_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="customer_id" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="store" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductTagUpdateEntity">
+                <xsd:sequence>
+                    <xsd:element name="name" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="status" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                    <xsd:element name="base_popularity" type="xsd:string" minOccurs="0" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+            <xsd:complexType name="catalogProductTagInfoEntity">
+                <xsd:sequence>
+                    <xsd:element name="name" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="status" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="base_popularity" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    <xsd:element name="products" type="typens:associativeArray" minOccurs="1" maxOccurs="1" />
+                </xsd:sequence>
+            </xsd:complexType>
+
+            <xsd:element name="catalogProductTagListRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="sessionId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="productId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="store" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagListResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="result" type="typens:catalogProductTagListEntityArray" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagInfoRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="sessionId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="tagId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="store" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagInfoResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="result" type="typens:catalogProductTagInfoEntity" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagAddRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="sessionId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="data" type="typens:catalogProductTagAddEntity" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagAddResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="result" type="typens:associativeArray" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagUpdateRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="sessionId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="tagId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="data" type="typens:catalogProductTagUpdateEntity" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="store" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagUpdateResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="result" type="xsd:int" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagRemoveRequestParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="sessionId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                        <xsd:element name="tagId" type="xsd:string" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="catalogProductTagRemoveResponseParam">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="result" type="xsd:int" minOccurs="1" maxOccurs="1" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:schema>
+    </wsdl:types>
+
+    <wsdl:message name="catalogProductTagListRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductTagListRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagListResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductTagListResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagInfoRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductTagInfoRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagInfoResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductTagInfoResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagAddRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductTagAddRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagAddResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductTagAddResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagUpdateRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductTagUpdateRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagUpdateResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductTagUpdateResponseParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagRemoveRequest">
+        <wsdl:part name="parameters" element="typens:catalogProductTagRemoveRequestParam" />
+    </wsdl:message>
+    <wsdl:message name="catalogProductTagRemoveResponse">
+        <wsdl:part name="parameters" element="typens:catalogProductTagRemoveResponseParam" />
+    </wsdl:message>
+
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="catalogProductTagList">
+            <wsdl:documentation>Retrieve list of tags by product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductTagListRequest" />
+            <wsdl:output message="typens:catalogProductTagListResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="catalogProductTagInfo">
+            <wsdl:documentation>Retrieve product tag info</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductTagInfoRequest" />
+            <wsdl:output message="typens:catalogProductTagInfoResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="catalogProductTagAdd">
+            <wsdl:documentation>Add tag(s) to product</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductTagAddRequest" />
+            <wsdl:output message="typens:catalogProductTagAddResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="catalogProductTagUpdate">
+            <wsdl:documentation>Update product tag</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductTagUpdateRequest" />
+            <wsdl:output message="typens:catalogProductTagUpdateResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+    <wsdl:portType name="{{var wsdl.handler}}PortType">
+        <wsdl:operation name="catalogProductTagRemove">
+            <wsdl:documentation>Remove product tag</wsdl:documentation>
+            <wsdl:input message="typens:catalogProductTagRemoveRequest" />
+            <wsdl:output message="typens:catalogProductTagRemoveResponse" />
+        </wsdl:operation>
+    </wsdl:portType>
+
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="catalogProductTagList">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="catalogProductTagInfo">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="catalogProductTagAdd">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="catalogProductTagUpdate">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+    <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
+        <wsdl:operation name="catalogProductTagRemove">
+            <soap:operation soapAction="" />
+            <wsdl:input>
+                <soap:body use="literal" />
+            </wsdl:input>
+            <wsdl:output>
+                <soap:body use="literal" />
+            </wsdl:output>
+        </wsdl:operation>
+    </wsdl:binding>
+
+    <wsdl:service name="{{var wsdl.name}}Service">
+        <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
+            <soap:address location="{{var wsdl.url}}" />
+        </wsdl:port>
+    </wsdl:service>
+</wsdl:definitions>
diff --git a/app/code/core/Mage/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/Css.php b/app/code/core/Mage/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/Css.php
index 9d695ad4fa6..e316a844e11 100644
--- a/app/code/core/Mage/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/Css.php
+++ b/app/code/core/Mage/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/Css.php
@@ -60,9 +60,11 @@ class Mage_Theme_Block_Adminhtml_System_Design_Theme_Edit_Tab_Css
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
+     * @param Magento_Filesystem $filesystem
      * @param Magento_ObjectManager $objectManager
      * @param Mage_Theme_Model_Uploader_Service $uploaderService
-     * @param Magento_Filesystem $filesystem
      * @param array $data
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -79,13 +81,15 @@ class Mage_Theme_Block_Adminhtml_System_Design_Theme_Edit_Tab_Css
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
+        Magento_Filesystem $filesystem,
         Magento_ObjectManager $objectManager,
         Mage_Theme_Model_Uploader_Service $uploaderService,
-        Magento_Filesystem $filesystem,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
         $this->_objectManager = $objectManager;
         $this->_uploaderService = $uploaderService;
@@ -225,9 +229,8 @@ class Mage_Theme_Block_Adminhtml_System_Design_Theme_Edit_Tab_Css
      */
     protected function _getGroupedFiles()
     {
-        $options = Mage::getConfig()->getOptions();
-        $jsDir = $options->getJsDir();
-        $codeDir = $options->getCodeDir();
+        $jsDir = $this->_dirs->getDir(Mage_Core_Model_Dir::PUB_LIB);
+        $codeDir = $this->_dirs->getDir(Mage_Core_Model_Dir::MODULES);
 
         $groups = array();
         $themes = array();
@@ -297,10 +300,9 @@ class Mage_Theme_Block_Adminhtml_System_Design_Theme_Edit_Tab_Css
      */
     protected function _getGroup($filename)
     {
-        $options = Mage::getConfig()->getOptions();
-        $designDir = $options->getDesignDir();
-        $jsDir = $options->getJsDir();
-        $codeDir = $options->getCodeDir();
+        $designDir = $this->_dirs->getDir(Mage_Core_Model_Dir::THEMES);
+        $jsDir = $this->_dirs->getDir(Mage_Core_Model_Dir::PUB_LIB);
+        $codeDir = $this->_dirs->getDir(Mage_Core_Model_Dir::MODULES);
 
         $group = null;
         $theme = null;
@@ -348,7 +350,7 @@ class Mage_Theme_Block_Adminhtml_System_Design_Theme_Edit_Tab_Css
      */
     protected function _getThemeByFilename($filename)
     {
-        $designDir = Mage::getConfig()->getOptions()->getDesignDir();
+        $designDir = $this->_dirs->getDir(Mage_Core_Model_Dir::THEMES);
         list(, $area, $package, $theme,) = explode('/', substr($filename, strlen($designDir)), 5);
         /** @var $collection Mage_Core_Model_Resource_Theme_Collection */
         $collection = Mage::getModel('Mage_Core_Model_Resource_Theme_Collection');
@@ -364,8 +366,8 @@ class Mage_Theme_Block_Adminhtml_System_Design_Theme_Edit_Tab_Css
     protected function _getGroupLabels($themes)
     {
         $labels = array(
-            Mage::getConfig()->getOptions()->getJsDir()   => $this->__('Library files'),
-            Mage::getConfig()->getOptions()->getCodeDir() => $this->__('Framework files')
+            $this->_dirs->getDir(Mage_Core_Model_Dir::PUB_LIB)   => $this->__('Library files'),
+            $this->_dirs->getDir(Mage_Core_Model_Dir::MODULES)   => $this->__('Framework files')
         );
         foreach ($themes as $theme) {
             /** @var $theme Mage_Core_Model_Theme */
diff --git a/app/code/core/Mage/Usa/Block/Adminhtml/Dhl/Unitofmeasure.php b/app/code/core/Mage/Usa/Block/Adminhtml/Dhl/Unitofmeasure.php
index af765b4529a..fe1b3ff9af1 100644
--- a/app/code/core/Mage/Usa/Block/Adminhtml/Dhl/Unitofmeasure.php
+++ b/app/code/core/Mage/Usa/Block/Adminhtml/Dhl/Unitofmeasure.php
@@ -77,6 +77,6 @@ class Mage_Usa_Block_Adminhtml_Dhl_Unitofmeasure extends Mage_Backend_Block_Syst
      */
     protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
     {
-        return parent::_getElementHtml($element) . $this->renderView();
+        return parent::_getElementHtml($element) . $this->_toHtml();
     }
 }
diff --git a/app/code/core/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/Resource.php b/app/code/core/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/Resource.php
index 7ea5bd9ff7b..4c07225d798 100644
--- a/app/code/core/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/Resource.php
+++ b/app/code/core/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/Resource.php
@@ -64,6 +64,8 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_Resource extends Mage_Backend_Bl
      * @param Mage_Core_Model_Store_Config $storeConfig
      * @param Mage_Core_Controller_Varien_Front $frontController
      * @param Mage_Core_Model_Factory_Helper $helperFactory
+     * @param Mage_Core_Model_Dir $dirs
+     * @param Mage_Core_Model_Logger $logger
      * @param Magento_Filesystem $filesystem
      * @param Mage_Webapi_Model_Authorization_Config $authorizationConfig
      * @param Mage_Webapi_Model_Resource_Acl_Rule $ruleResource
@@ -83,13 +85,15 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_Resource extends Mage_Backend_Bl
         Mage_Core_Model_Store_Config $storeConfig,
         Mage_Core_Controller_Varien_Front $frontController,
         Mage_Core_Model_Factory_Helper $helperFactory,
+        Mage_Core_Model_Dir $dirs,
+        Mage_Core_Model_Logger $logger,
         Magento_Filesystem $filesystem,
         Mage_Webapi_Model_Authorization_Config $authorizationConfig,
         Mage_Webapi_Model_Resource_Acl_Rule $ruleResource,
         array $data = array()
     ) {
         parent::__construct($request, $layout, $eventManager, $urlBuilder, $translator, $cache, $designPackage,
-            $session, $storeConfig, $frontController, $helperFactory, $filesystem, $data
+            $session, $storeConfig, $frontController, $helperFactory, $dirs, $logger, $filesystem, $data
         );
         $this->_authorizationConfig = $authorizationConfig;
         $this->_ruleResource = $ruleResource;
diff --git a/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation.php b/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation.php
index 815036b8344..4aeb73cbd80 100644
--- a/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation.php
+++ b/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation.php
@@ -25,54 +25,24 @@
  */
 class Mage_Webapi_Controller_Dispatcher_Rest_Presentation
 {
-    /** @var Mage_Webapi_Model_Config_Rest */
-    protected $_apiConfig;
+    /** @var Mage_Webapi_Controller_Dispatcher_Rest_Presentation_Request */
+    protected $_requestProcessor;
 
-    /** @var Mage_Webapi_Helper_Data */
-    protected $_apiHelper;
-
-    /** @var Mage_Webapi_Helper_Config */
-    protected $_configHelper;
-
-    /** @var Mage_Webapi_Controller_Request_Rest */
-    protected $_request;
-
-    /** @var Mage_Webapi_Controller_Response_Rest */
-    protected $_response;
-
-    /** @var Magento_Controller_Router_Route_Factory */
-    protected $_routeFactory;
-
-    /** @var Mage_Webapi_Controller_Response_Rest_RendererInterface */
-    protected $_renderer;
+    /** @var Mage_Webapi_Controller_Dispatcher_Rest_Presentation_Response */
+    protected $_responseProcessor;
 
     /**
      * Initialize dependencies.
      *
-     * @param Mage_Webapi_Model_Config_Rest $apiConfig
-     * @param Mage_Webapi_Helper_Data $helper
-     * @param Mage_Webapi_Helper_Config $configHelper
-     * @param Mage_Webapi_Controller_Request_Factory $requestFactory
-     * @param Mage_Webapi_Controller_Response_Rest $response
-     * @param Mage_Webapi_Controller_Response_Rest_Renderer_Factory $rendererFactory
-     * @param Magento_Controller_Router_Route_Factory $routeFactory
+     * @param Mage_Webapi_Controller_Dispatcher_Rest_Presentation_Request $requestPresentation
+     * @param Mage_Webapi_Controller_Dispatcher_Rest_Presentation_Response $responsePresentation
      */
     public function __construct(
-        Mage_Webapi_Model_Config_Rest $apiConfig,
-        Mage_Webapi_Helper_Data $helper,
-        Mage_Webapi_Helper_Config $configHelper,
-        Mage_Webapi_Controller_Request_Factory $requestFactory,
-        Mage_Webapi_Controller_Response_Rest $response,
-        Mage_Webapi_Controller_Response_Rest_Renderer_Factory $rendererFactory,
-        Magento_Controller_Router_Route_Factory $routeFactory
+        Mage_Webapi_Controller_Dispatcher_Rest_Presentation_Request $requestPresentation,
+        Mage_Webapi_Controller_Dispatcher_Rest_Presentation_Response $responsePresentation
     ) {
-        $this->_apiConfig = $apiConfig;
-        $this->_apiHelper = $helper;
-        $this->_configHelper = $configHelper;
-        $this->_request = $requestFactory->get();
-        $this->_response = $response;
-        $this->_routeFactory = $routeFactory;
-        $this->_renderer = $rendererFactory->get();
+        $this->_requestProcessor = $requestPresentation;
+        $this->_responseProcessor = $responsePresentation;
     }
 
     /**
@@ -84,26 +54,7 @@ class Mage_Webapi_Controller_Dispatcher_Rest_Presentation
      */
     public function fetchRequestData($controllerInstance, $action)
     {
-        $methodReflection = Mage_Webapi_Helper_Data::createMethodReflection($controllerInstance, $action);
-        $methodName = $this->_configHelper->getMethodNameWithoutVersionSuffix($methodReflection);
-        $bodyParamName = $this->_configHelper->getOperationBodyParamName($methodReflection);
-        $requestParams = array_merge(
-            $this->_request->getParams(),
-            array($bodyParamName => $this->_getRequestBody($methodName))
-        );
-        /** Convert names of ID and Parent ID params in request to those which are used in method interface. */
-        $idArgumentName = $this->_configHelper->getOperationIdParamName($methodReflection);
-        $parentIdParamName = Mage_Webapi_Controller_Router_Route_Rest::PARAM_PARENT_ID;
-        $idParamName = Mage_Webapi_Controller_Router_Route_Rest::PARAM_ID;
-        if (isset($requestParams[$parentIdParamName]) && ($idArgumentName != $parentIdParamName)) {
-            $requestParams[$idArgumentName] = $requestParams[$parentIdParamName];
-            unset($requestParams[$parentIdParamName]);
-        } elseif (isset($requestParams[$idParamName]) && ($idArgumentName != $idParamName)) {
-            $requestParams[$idArgumentName] = $requestParams[$idParamName];
-            unset($requestParams[$idParamName]);
-        }
-
-        return $this->_apiHelper->prepareMethodParams($controllerInstance, $action, $requestParams, $this->_apiConfig);
+        return $this->_requestProcessor->fetchRequestData($controllerInstance, $action);
     }
 
     /**
@@ -114,121 +65,6 @@ class Mage_Webapi_Controller_Dispatcher_Rest_Presentation
      */
     public function prepareResponse($method, $outputData = null)
     {
-        switch ($method) {
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_CREATE:
-                /** @var $createdItem Mage_Core_Model_Abstract */
-                $createdItem = $outputData;
-                $this->_response->setHeader('Location', $this->_getCreatedItemLocation($createdItem));
-                break;
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_GET:
-                // TODO: Implement fields filtration
-                $filteredData = $outputData;
-                $this->_render($filteredData);
-                break;
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_LIST:
-                // TODO: Implement fields filtration
-                $filteredData = $outputData;
-                $this->_render($filteredData);
-                break;
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_UPDATE:
-                // break is intentionally omitted
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_CREATE:
-                // break is intentionally omitted
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_DELETE:
-                $this->_response->setHttpResponseCode(Mage_Webapi_Controller_Response_Rest::HTTP_MULTI_STATUS);
-                break;
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_UPDATE:
-                // break is intentionally omitted
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_DELETE:
-                break;
-        }
-        $this->_renderMessages();
-    }
-
-    /**
-     * Render error and success messages.
-     */
-    protected function _renderMessages()
-    {
-        if ($this->_response->getMessages()) {
-            $this->_render(array('messages' => $this->_response->getMessages()));
-        }
-    }
-
-    /**
-     * Generate resource location.
-     *
-     * @param Mage_Core_Model_Abstract $createdItem
-     * @return string URL
-     */
-    protected function _getCreatedItemLocation($createdItem)
-    {
-        $apiTypeRoute = $this->_routeFactory->createRoute(
-            'Mage_Webapi_Controller_Router_Route_Webapi',
-            Mage_Webapi_Controller_Router_Route_Webapi::getApiRoute()
-        );
-        $resourceName = $this->_request->getResourceName();
-        $routeToItem = $this->_routeFactory->createRoute(
-            'Zend_Controller_Router_Route',
-            $this->_apiConfig->getRestRouteToItem($resourceName)
-        );
-        $chain = $apiTypeRoute->chain($routeToItem);
-        $params = array(
-            Mage_Webapi_Controller_Router_Route_Webapi::PARAM_API_TYPE => $this->_request->getApiType(),
-            Mage_Webapi_Controller_Router_Route_Rest::PARAM_ID => $createdItem->getId(),
-            Mage_Webapi_Controller_Router_Route_Rest::PARAM_VERSION => $this->_request->getResourceVersion()
-        );
-        $uri = $chain->assemble($params);
-
-        return '/' . $uri;
-    }
-
-    /**
-     * Retrieve request data. Ensure that data is not empty.
-     *
-     * @param string $method
-     * @return array
-     */
-    protected function _getRequestBody($method)
-    {
-        $processedInputData = null;
-        switch ($method) {
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_CREATE:
-                $processedInputData = $this->_request->getBodyParams();
-                // TODO: Implement data filtration of item
-                break;
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_CREATE:
-                $processedInputData = $this->_request->getBodyParams();
-                break;
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_UPDATE:
-                $processedInputData = $this->_request->getBodyParams();
-                // TODO: Implement data filtration
-                break;
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_UPDATE:
-                $processedInputData = $this->_request->getBodyParams();
-                // TODO: Implement fields filtration
-                break;
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_DELETE:
-                // break is intentionally omitted
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_GET:
-                // break is intentionally omitted
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_DELETE:
-                // break is intentionally omitted
-            case Mage_Webapi_Controller_ActionAbstract::METHOD_LIST:
-                break;
-        }
-        return $processedInputData;
-    }
-
-    /**
-     * Render data using registered Renderer.
-     *
-     * @param mixed $data
-     */
-    protected function _render($data)
-    {
-        $mimeType = $this->_renderer->getMimeType();
-        $body = $this->_renderer->render($data);
-        $this->_response->setMimeType($mimeType)->setBody($body);
+        $this->_responseProcessor->prepareResponse($method, $outputData);
     }
 }
diff --git a/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation/Request.php b/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation/Request.php
new file mode 100644
index 00000000000..f5a73cfc61c
--- /dev/null
+++ b/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation/Request.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Helper for request data processing according to REST presentation.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Webapi_Controller_Dispatcher_Rest_Presentation_Request
+{
+    /** @var Mage_Webapi_Model_Config_Rest */
+    protected $_apiConfig;
+
+    /** @var Mage_Webapi_Helper_Data */
+    protected $_apiHelper;
+
+    /** @var Mage_Webapi_Helper_Config */
+    protected $_configHelper;
+
+    /** @var Mage_Webapi_Controller_Request_Rest */
+    protected $_request;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param Mage_Webapi_Model_Config_Rest $apiConfig
+     * @param Mage_Webapi_Helper_Data $helper
+     * @param Mage_Webapi_Helper_Config $configHelper
+     * @param Mage_Webapi_Controller_Request_Factory $requestFactory
+     */
+    public function __construct(
+        Mage_Webapi_Model_Config_Rest $apiConfig,
+        Mage_Webapi_Helper_Data $helper,
+        Mage_Webapi_Helper_Config $configHelper,
+        Mage_Webapi_Controller_Request_Factory $requestFactory
+    ) {
+        $this->_apiConfig = $apiConfig;
+        $this->_apiHelper = $helper;
+        $this->_configHelper = $configHelper;
+        $this->_request = $requestFactory->get();
+    }
+
+    /**
+     * Fetch data from request and prepare it for passing to specified action.
+     *
+     * @param object $controllerInstance
+     * @param string $action
+     * @return array
+     */
+    public function fetchRequestData($controllerInstance, $action)
+    {
+        $methodReflection = Mage_Webapi_Helper_Data::createMethodReflection($controllerInstance, $action);
+        $methodName = $this->_configHelper->getMethodNameWithoutVersionSuffix($methodReflection);
+        $bodyParamName = $this->_configHelper->getOperationBodyParamName($methodReflection);
+        $requestParams = array_merge(
+            $this->_request->getParams(),
+            array($bodyParamName => $this->_getRequestBody($methodName))
+        );
+        /** Convert names of ID and Parent ID params in request to those which are used in method interface. */
+        $idArgumentName = $this->_configHelper->getOperationIdParamName($methodReflection);
+        $parentIdParamName = Mage_Webapi_Controller_Router_Route_Rest::PARAM_PARENT_ID;
+        $idParamName = Mage_Webapi_Controller_Router_Route_Rest::PARAM_ID;
+        if (isset($requestParams[$parentIdParamName]) && ($idArgumentName != $parentIdParamName)) {
+            $requestParams[$idArgumentName] = $requestParams[$parentIdParamName];
+            unset($requestParams[$parentIdParamName]);
+        } elseif (isset($requestParams[$idParamName]) && ($idArgumentName != $idParamName)) {
+            $requestParams[$idArgumentName] = $requestParams[$idParamName];
+            unset($requestParams[$idParamName]);
+        }
+
+        return $this->_apiHelper->prepareMethodParams($controllerInstance, $action, $requestParams, $this->_apiConfig);
+    }
+
+    /**
+     * Retrieve request data. Ensure that data is not empty.
+     *
+     * @param string $method
+     * @return array
+     */
+    protected function _getRequestBody($method)
+    {
+        $processedInputData = null;
+        switch ($method) {
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_CREATE:
+                $processedInputData = $this->_request->getBodyParams();
+                // TODO: Implement data filtration of item
+                break;
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_CREATE:
+                $processedInputData = $this->_request->getBodyParams();
+                break;
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_UPDATE:
+                $processedInputData = $this->_request->getBodyParams();
+                // TODO: Implement data filtration
+                break;
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_UPDATE:
+                $processedInputData = $this->_request->getBodyParams();
+                // TODO: Implement fields filtration
+                break;
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_DELETE:
+                // break is intentionally omitted
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_GET:
+                // break is intentionally omitted
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_DELETE:
+                // break is intentionally omitted
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_LIST:
+                break;
+        }
+        return $processedInputData;
+    }
+}
diff --git a/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation/Response.php b/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation/Response.php
new file mode 100644
index 00000000000..e9b7ea94c9e
--- /dev/null
+++ b/app/code/core/Mage/Webapi/Controller/Dispatcher/Rest/Presentation/Response.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * Helper for response data processing according to REST presentation.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Webapi_Controller_Dispatcher_Rest_Presentation_Response
+{
+    /** @var Mage_Webapi_Model_Config_Rest */
+    protected $_apiConfig;
+
+    /** @var Mage_Webapi_Controller_Request_Rest */
+    protected $_request;
+
+    /** @var Mage_Webapi_Controller_Response_Rest */
+    protected $_response;
+
+    /** @var Magento_Controller_Router_Route_Factory */
+    protected $_routeFactory;
+
+    /** @var Mage_Webapi_Controller_Response_Rest_RendererInterface */
+    protected $_renderer;
+
+    /** @var Mage_Core_Model_Config */
+    protected $_applicationConfig;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param Mage_Webapi_Model_Config_Rest $apiConfig
+     * @param Mage_Webapi_Controller_Request_Factory $requestFactory
+     * @param Mage_Webapi_Controller_Response_Rest $response
+     * @param Mage_Webapi_Controller_Response_Rest_Renderer_Factory $rendererFactory
+     * @param Magento_Controller_Router_Route_Factory $routeFactory
+     * @param Mage_Core_Model_Config $applicationConfig
+     */
+    public function __construct(
+        Mage_Webapi_Model_Config_Rest $apiConfig,
+        Mage_Webapi_Controller_Request_Factory $requestFactory,
+        Mage_Webapi_Controller_Response_Rest $response,
+        Mage_Webapi_Controller_Response_Rest_Renderer_Factory $rendererFactory,
+        Magento_Controller_Router_Route_Factory $routeFactory,
+        Mage_Core_Model_Config $applicationConfig
+    ) {
+        $this->_apiConfig = $apiConfig;
+        $this->_request = $requestFactory->get();
+        $this->_response = $response;
+        $this->_routeFactory = $routeFactory;
+        $this->_renderer = $rendererFactory->get();
+        $this->_applicationConfig = $applicationConfig;
+    }
+
+    /**
+     * Perform rendering of action results.
+     *
+     * @param string $method
+     * @param array|null $outputData
+     */
+    public function prepareResponse($method, $outputData = null)
+    {
+        switch ($method) {
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_CREATE:
+                /** @var $createdItem Mage_Core_Model_Abstract */
+                $createdItem = $outputData;
+                $this->_response->setHeader('Location', $this->_getCreatedItemLocation($createdItem));
+                break;
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_GET:
+                // TODO: Implement fields filtration
+                $filteredData = $outputData;
+                $this->_render($filteredData);
+                break;
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_LIST:
+                // TODO: Implement fields filtration
+                $filteredData = $outputData;
+                $this->_render($filteredData);
+                break;
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_UPDATE:
+                // break is intentionally omitted
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_CREATE:
+                // break is intentionally omitted
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_MULTI_DELETE:
+                $this->_response->setHttpResponseCode(Mage_Webapi_Controller_Response_Rest::HTTP_MULTI_STATUS);
+                break;
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_UPDATE:
+                // break is intentionally omitted
+            case Mage_Webapi_Controller_ActionAbstract::METHOD_DELETE:
+                break;
+        }
+        $this->_renderMessages();
+    }
+
+    /**
+     * Render error and success messages.
+     */
+    protected function _renderMessages()
+    {
+        if ($this->_response->getMessages()) {
+            $this->_render(array('messages' => $this->_response->getMessages()));
+        }
+    }
+
+    /**
+     * Generate resource location.
+     *
+     * @param Mage_Core_Model_Abstract $createdItem
+     * @return string URL
+     */
+    protected function _getCreatedItemLocation($createdItem)
+    {
+        $apiTypeRoute = $this->_routeFactory->createRoute(
+            'Mage_Webapi_Controller_Router_Route',
+            $this->_applicationConfig->getAreaFrontName() . '/:' . Mage_Webapi_Controller_Request::PARAM_API_TYPE
+        );
+        $resourceName = $this->_request->getResourceName();
+        $routeToItem = $this->_routeFactory->createRoute(
+            'Zend_Controller_Router_Route',
+            $this->_apiConfig->getRestRouteToItem($resourceName)
+        );
+        $chain = $apiTypeRoute->chain($routeToItem);
+        $params = array(
+            Mage_Webapi_Controller_Request::PARAM_API_TYPE => $this->_request->getApiType(),
+            Mage_Webapi_Controller_Router_Route_Rest::PARAM_ID => $createdItem->getId(),
+            Mage_Webapi_Controller_Router_Route_Rest::PARAM_VERSION => $this->_request->getResourceVersion()
+        );
+        $uri = $chain->assemble($params);
+
+        return '/' . $uri;
+    }
+
+    /**
+     * Render data using registered Renderer.
+     *
+     * @param mixed $data
+     */
+    protected function _render($data)
+    {
+        $mimeType = $this->_renderer->getMimeType();
+        $body = $this->_renderer->render($data);
+        $this->_response->setMimeType($mimeType)->setBody($body);
+    }
+}
diff --git a/app/code/core/Mage/Webapi/Controller/Front.php b/app/code/core/Mage/Webapi/Controller/Front.php
index 94193c03700..ffd5e5fb158 100644
--- a/app/code/core/Mage/Webapi/Controller/Front.php
+++ b/app/code/core/Mage/Webapi/Controller/Front.php
@@ -148,16 +148,18 @@ class Mage_Webapi_Controller_Front implements Mage_Core_Controller_FrontInterfac
     {
         if (is_null($this->_apiType)) {
             $request = $this->_application->getRequest();
+            $apiRoutePath = $this->_application->getConfig()->getAreaFrontName()
+                . '/:' . Mage_Webapi_Controller_Request::PARAM_API_TYPE;
             $apiRoute = $this->_routeFactory->createRoute(
-                'Mage_Webapi_Controller_Router_Route_Webapi',
-                Mage_Webapi_Controller_Router_Route_Webapi::getApiRoute()
+                'Mage_Webapi_Controller_Router_Route',
+                $apiRoutePath
             );
             if (!($apiTypeMatch = $apiRoute->match($request, true))) {
                 throw new Mage_Webapi_Exception($this->_helper->__('Request does not match any API type route.'),
                     Mage_Webapi_Exception::HTTP_BAD_REQUEST);
             }
 
-            $apiType = $apiTypeMatch[Mage_Webapi_Controller_Router_Route_Webapi::PARAM_API_TYPE];
+            $apiType = $apiTypeMatch[Mage_Webapi_Controller_Request::PARAM_API_TYPE];
             if (!in_array($apiType, $this->getListOfAvailableApiTypes())) {
                 throw new Mage_Webapi_Exception($this->_helper->__('The "%s" API type is not defined.', $apiType),
                     Mage_Webapi_Exception::HTTP_BAD_REQUEST);
diff --git a/app/code/core/Mage/Webapi/Controller/Request.php b/app/code/core/Mage/Webapi/Controller/Request.php
index 8d436e4afac..9d4d196cb72 100644
--- a/app/code/core/Mage/Webapi/Controller/Request.php
+++ b/app/code/core/Mage/Webapi/Controller/Request.php
@@ -25,6 +25,8 @@
  */
 class Mage_Webapi_Controller_Request extends Zend_Controller_Request_Http
 {
+    const PARAM_API_TYPE = 'api_type';
+
     /**#@+
      * Name of query ($_GET) parameters to use in navigation and so on.
      */
diff --git a/app/code/core/Mage/Webapi/Controller/Request/Rest.php b/app/code/core/Mage/Webapi/Controller/Request/Rest.php
index 46abbd72b06..bd5b9f0251c 100644
--- a/app/code/core/Mage/Webapi/Controller/Request/Rest.php
+++ b/app/code/core/Mage/Webapi/Controller/Request/Rest.php
@@ -160,16 +160,16 @@ class Mage_Webapi_Controller_Request_Rest extends Mage_Webapi_Controller_Request
         $headerValue = $this->getHeader('Content-Type');
 
         if (!$headerValue) {
-            throw new Mage_Webapi_Exception($this->_helper->__('Content-Type header is empty'),
+            throw new Mage_Webapi_Exception($this->_helper->__('Content-Type header is empty.'),
                 Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
         if (!preg_match('~^([a-z\d/\-+.]+)(?:; *charset=(.+))?$~Ui', $headerValue, $matches)) {
-            throw new Mage_Webapi_Exception($this->_helper->__('Invalid Content-Type header'),
+            throw new Mage_Webapi_Exception($this->_helper->__('Content-Type header is invalid.'),
                 Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
         // request encoding check if it is specified in header
         if (isset($matches[2]) && self::REQUEST_CHARSET != strtolower($matches[2])) {
-            throw new Mage_Webapi_Exception($this->_helper->__('UTF-8 is the only supported charset'),
+            throw new Mage_Webapi_Exception($this->_helper->__('UTF-8 is the only supported charset.'),
                 Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
 
@@ -185,7 +185,7 @@ class Mage_Webapi_Controller_Request_Rest extends Mage_Webapi_Controller_Request
     public function getHttpMethod()
     {
         if (!$this->isGet() && !$this->isPost() && !$this->isPut() && !$this->isDelete()) {
-            throw new Mage_Webapi_Exception($this->_helper->__('Invalid request method'),
+            throw new Mage_Webapi_Exception($this->_helper->__('Request method is invalid.'),
                 Mage_Webapi_Exception::HTTP_BAD_REQUEST);
         }
         // Map HTTP methods to classic CRUD verbs
diff --git a/app/code/core/Mage/Webapi/Controller/Request/Rest/Interpreter/Json.php b/app/code/core/Mage/Webapi/Controller/Request/Rest/Interpreter/Json.php
index 773ee5dbcc4..48151e1e537 100644
--- a/app/code/core/Mage/Webapi/Controller/Request/Rest/Interpreter/Json.php
+++ b/app/code/core/Mage/Webapi/Controller/Request/Rest/Interpreter/Json.php
@@ -58,7 +58,7 @@ class Mage_Webapi_Controller_Request_Rest_Interpreter_Json implements
     {
         if (!is_string($encodedBody)) {
             throw new InvalidArgumentException(sprintf(
-                'Invalid data type "%s". String is expected.',
+                '"%s" data type is invalid. String is expected.',
                 gettype($encodedBody)
             ));
         }
diff --git a/app/code/core/Mage/Webapi/Controller/Request/Rest/Interpreter/Xml.php b/app/code/core/Mage/Webapi/Controller/Request/Rest/Interpreter/Xml.php
index 2a8a0656e4e..08a95447552 100644
--- a/app/code/core/Mage/Webapi/Controller/Request/Rest/Interpreter/Xml.php
+++ b/app/code/core/Mage/Webapi/Controller/Request/Rest/Interpreter/Xml.php
@@ -77,7 +77,7 @@ class Mage_Webapi_Controller_Request_Rest_Interpreter_Xml implements
     {
         if (!is_string($xmlRequestBody)) {
             throw new InvalidArgumentException(
-                sprintf('Invalid data type "%s". String is expected.', gettype($xmlRequestBody))
+                sprintf('"%s" data type is invalid. String is expected.', gettype($xmlRequestBody))
             );
         }
         /** Disable external entity loading to prevent possible vulnerability */
diff --git a/app/code/core/Mage/Webapi/Controller/Request/Soap.php b/app/code/core/Mage/Webapi/Controller/Request/Soap.php
index 8e00c687cde..2888d07c2c4 100644
--- a/app/code/core/Mage/Webapi/Controller/Request/Soap.php
+++ b/app/code/core/Mage/Webapi/Controller/Request/Soap.php
@@ -51,7 +51,7 @@ class Mage_Webapi_Controller_Request_Soap extends Mage_Webapi_Controller_Request
         $wsdlParam = Mage_Webapi_Model_Soap_Server::REQUEST_PARAM_WSDL;
         $resourcesParam = Mage_Webapi_Model_Soap_Server::REQUEST_PARAM_RESOURCES;
         $requestParams = array_keys($this->getParams());
-        $allowedParams = array(Mage_Webapi_Controller_Router_Route_Webapi::PARAM_API_TYPE, $wsdlParam, $resourcesParam);
+        $allowedParams = array(Mage_Webapi_Controller_Request::PARAM_API_TYPE, $wsdlParam, $resourcesParam);
         $notAllowedParameters = array_diff($requestParams, $allowedParams);
         if (count($notAllowedParameters)) {
             $message = $this->_helper->__('Not allowed parameters: %s. ', implode(', ', $notAllowedParameters))
diff --git a/app/code/core/Mage/Webapi/Controller/Router/RouteAbstract.php b/app/code/core/Mage/Webapi/Controller/Router/Route.php
similarity index 93%
rename from app/code/core/Mage/Webapi/Controller/Router/RouteAbstract.php
rename to app/code/core/Mage/Webapi/Controller/Router/Route.php
index 371559b7f95..41d1d0494eb 100644
--- a/app/code/core/Mage/Webapi/Controller/Router/RouteAbstract.php
+++ b/app/code/core/Mage/Webapi/Controller/Router/Route.php
@@ -23,7 +23,7 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-abstract class Mage_Webapi_Controller_Router_RouteAbstract extends Zend_Controller_Router_Route
+class Mage_Webapi_Controller_Router_Route extends Zend_Controller_Router_Route
 {
     /**
      * Matches a Request with parts defined by a map. Assigns and
diff --git a/app/code/core/Mage/Webapi/Controller/Router/Route/Rest.php b/app/code/core/Mage/Webapi/Controller/Router/Route/Rest.php
index 31851fed156..722a159f0d9 100644
--- a/app/code/core/Mage/Webapi/Controller/Router/Route/Rest.php
+++ b/app/code/core/Mage/Webapi/Controller/Router/Route/Rest.php
@@ -23,7 +23,7 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-class Mage_Webapi_Controller_Router_Route_Rest extends Mage_Webapi_Controller_Router_RouteAbstract
+class Mage_Webapi_Controller_Router_Route_Rest extends Mage_Webapi_Controller_Router_Route
 {
     /**#@+
      * Names of special parameters in routes.
diff --git a/app/code/core/Mage/Webapi/Model/Authorization/Config.php b/app/code/core/Mage/Webapi/Model/Authorization/Config.php
index b5edcd6425b..56aabdf35c1 100644
--- a/app/code/core/Mage/Webapi/Model/Authorization/Config.php
+++ b/app/code/core/Mage/Webapi/Model/Authorization/Config.php
@@ -76,7 +76,7 @@ class Mage_Webapi_Model_Authorization_Config implements Mage_Core_Model_Acl_Conf
     {
         if (is_null($this->_reader)) {
             $aclResourceFiles = $this->_getAclResourceFiles();
-            $this->_reader = $this->_readerFactory->createReader(array($aclResourceFiles));
+            $this->_reader = $this->_readerFactory->createReader(array('configFiles' => $aclResourceFiles));
         }
         return $this->_reader;
     }
diff --git a/app/code/core/Mage/Webapi/Model/Authorization/Config/Reader.php b/app/code/core/Mage/Webapi/Model/Authorization/Config/Reader.php
index a8039c7eede..7ffde825c51 100644
--- a/app/code/core/Mage/Webapi/Model/Authorization/Config/Reader.php
+++ b/app/code/core/Mage/Webapi/Model/Authorization/Config/Reader.php
@@ -39,7 +39,10 @@ class Mage_Webapi_Model_Authorization_Config_Reader extends Magento_Acl_Config_R
         Mage_Core_Model_Config $config,
         array $configFiles
     ) {
-        parent::__construct($configFiles);
+        // TODO: Remove temporary workaround, that allows to avoid exception if no ACL files are available
+        if (!empty($configFiles)) {
+            parent::__construct($configFiles);
+        }
         $this->_config = $config;
     }
 
diff --git a/app/code/core/Mage/Webapi/Model/Config/Rest.php b/app/code/core/Mage/Webapi/Model/Config/Rest.php
index 64bb74405a1..a1a2aa47d84 100644
--- a/app/code/core/Mage/Webapi/Model/Config/Rest.php
+++ b/app/code/core/Mage/Webapi/Model/Config/Rest.php
@@ -33,16 +33,16 @@ class Mage_Webapi_Model_Config_Rest extends Mage_Webapi_Model_ConfigAbstract
      *
      * @param Mage_Webapi_Model_Config_Reader_Rest $reader
      * @param Mage_Webapi_Helper_Config $helper
-     * @param Mage_Core_Model_App $app
+     * @param Mage_Core_Model_App $application
      * @param Magento_Controller_Router_Route_Factory $routeFactory
      */
     public function __construct(
         Mage_Webapi_Model_Config_Reader_Rest $reader,
         Mage_Webapi_Helper_Config $helper,
-        Mage_Core_Model_App $app,
+        Mage_Core_Model_App $application,
         Magento_Controller_Router_Route_Factory $routeFactory
     ) {
-        parent::__construct($reader, $helper, $app);
+        parent::__construct($reader, $helper, $application);
         $this->_routeFactory = $routeFactory;
     }
 
@@ -124,7 +124,7 @@ class Mage_Webapi_Model_Config_Rest extends Mage_Webapi_Model_ConfigAbstract
      */
     protected function _createRoute($routePath, $resourceName, $actionType)
     {
-        $apiTypeRoutePath = Mage_Webapi_Controller_Router_Route_Webapi::API_AREA_NAME
+        $apiTypeRoutePath = $this->_application->getConfig()->getAreaFrontName()
             . '/:' . Mage_Webapi_Controller_Front::API_TYPE_REST;
         $fullRoutePath = $apiTypeRoutePath . $routePath;
         /** @var $route Mage_Webapi_Controller_Router_Route_Rest */
diff --git a/app/code/core/Mage/Webapi/Model/Config/Soap.php b/app/code/core/Mage/Webapi/Model/Config/Soap.php
index c139217b918..5ed7ace1655 100644
--- a/app/code/core/Mage/Webapi/Model/Config/Soap.php
+++ b/app/code/core/Mage/Webapi/Model/Config/Soap.php
@@ -30,14 +30,14 @@ class Mage_Webapi_Model_Config_Soap extends Mage_Webapi_Model_ConfigAbstract
      *
      * @param Mage_Webapi_Model_Config_Reader_Soap $reader
      * @param Mage_Webapi_Helper_Config $helper
-     * @param Mage_Core_Model_App $app
+     * @param Mage_Core_Model_App $application
      */
     public function __construct(
         Mage_Webapi_Model_Config_Reader_Soap $reader,
         Mage_Webapi_Helper_Config $helper,
-        Mage_Core_Model_App $app
+        Mage_Core_Model_App $application
     ) {
-        parent::__construct($reader, $helper, $app);
+        parent::__construct($reader, $helper, $application);
     }
 
     /**
diff --git a/app/code/core/Mage/Webapi/Model/ConfigAbstract.php b/app/code/core/Mage/Webapi/Model/ConfigAbstract.php
index 864f6b1a3d1..6fe290683d7 100644
--- a/app/code/core/Mage/Webapi/Model/ConfigAbstract.php
+++ b/app/code/core/Mage/Webapi/Model/ConfigAbstract.php
@@ -51,7 +51,7 @@ abstract class Mage_Webapi_Model_ConfigAbstract
     protected $_helper;
 
     /** @var Mage_Core_Model_App */
-    protected $_app;
+    protected $_application;
 
     /**
      * Resources configuration data.
@@ -65,16 +65,16 @@ abstract class Mage_Webapi_Model_ConfigAbstract
      *
      * @param Mage_Webapi_Model_Config_ReaderAbstract $reader
      * @param Mage_Webapi_Helper_Config $helper
-     * @param Mage_Core_Model_App $app
+     * @param Mage_Core_Model_App $application
      */
     public function __construct(
         Mage_Webapi_Model_Config_ReaderAbstract $reader,
         Mage_Webapi_Helper_Config $helper,
-        Mage_Core_Model_App $app
+        Mage_Core_Model_App $application
     ) {
         $this->_reader = $reader;
         $this->_helper = $helper;
-        $this->_app = $app;
+        $this->_application = $application;
         $this->_data = $this->_reader->getData();
     }
 
@@ -288,7 +288,7 @@ abstract class Mage_Webapi_Model_ConfigAbstract
                     $resourceName
                 );
                 throw new Mage_Webapi_Exception($removalMessage . ' ' . $messageUseMethod, $badRequestCode);
-            } elseif (isset($deprecationPolicy['deprecated']) && $this->_app->isDeveloperMode()) {
+            } elseif (isset($deprecationPolicy['deprecated']) && $this->_application->isDeveloperMode()) {
                 $deprecationMessage = $this->_helper
                     ->__('Version "%s" of "%s" method in "%s" resource is deprecated.',
                     $resourceVersion,
diff --git a/app/code/core/Mage/Webapi/Model/Soap/Server.php b/app/code/core/Mage/Webapi/Model/Soap/Server.php
index 5609192b567..f543e9163c5 100644
--- a/app/code/core/Mage/Webapi/Model/Soap/Server.php
+++ b/app/code/core/Mage/Webapi/Model/Soap/Server.php
@@ -193,7 +193,7 @@ class Mage_Webapi_Model_Soap_Server extends \Zend\Soap\Server
     {
         // @TODO: Implement proper endpoint URL retrieval mechanism in APIA-718 story
         return $this->_application->getStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB)
-            . Mage_Webapi_Controller_Router_Route_Webapi::API_AREA_NAME . '/'
+            . $this->_application->getConfig()->getAreaFrontName() . '/'
             . Mage_Webapi_Controller_Front::API_TYPE_SOAP;
     }
 }
diff --git a/app/code/core/Mage/Webapi/etc/adminhtml/menu.xml b/app/code/core/Mage/Webapi/etc/adminhtml/menu.xml
index 332a4fbc88c..0dbadc30ed3 100644
--- a/app/code/core/Mage/Webapi/etc/adminhtml/menu.xml
+++ b/app/code/core/Mage/Webapi/etc/adminhtml/menu.xml
@@ -27,11 +27,11 @@
 -->
 <config>
     <menu>
-        <add id="Mage_Webapi::system_api" title="Web Services" module="Mage_Webapi" sortOrder="25"
+        <add id="Mage_Webapi::system_webapi" title="Web Services" module="Mage_Webapi" sortOrder="26"
              parent="Mage_Adminhtml::system" resource="Mage_Webapi::webapi"/>
         <add id="Mage_Webapi::system_api_webapi_users" title="API Users" module="Mage_Webapi" sortOrder="1"
-             parent="Mage_Webapi::system_api" action="adminhtml/webapi_user" resource="Mage_Webapi::webapi_users"/>
+             parent="Mage_Webapi::system_webapi" action="adminhtml/webapi_user" resource="Mage_Webapi::webapi_users"/>
         <add id="Mage_Webapi::system_api_webapi_roles" title="API Roles" module="Mage_Webapi" sortOrder="2"
-             parent="Mage_Webapi::system_api" action="adminhtml/webapi_role" resource="Mage_Webapi::webapi_roles"/>
+             parent="Mage_Webapi::system_webapi" action="adminhtml/webapi_role" resource="Mage_Webapi::webapi_roles"/>
     </menu>
 </config>
diff --git a/app/code/core/Mage/Webapi/etc/config.xml b/app/code/core/Mage/Webapi/etc/config.xml
index 73dab0d689d..d90be7a2f48 100644
--- a/app/code/core/Mage/Webapi/etc/config.xml
+++ b/app/code/core/Mage/Webapi/etc/config.xml
@@ -41,7 +41,7 @@
     <global>
         <areas>
             <webapi>
-                <frontName>api</frontName>
+                <frontName>webapi</frontName>
                 <front_controller>Mage_Webapi_Controller_Front</front_controller>
                 <!--TODO: Utilize base action controller from config, not constant-->
                 <base_controller>Mage_Webapi_Controller_ActionAbstract</base_controller>
@@ -125,10 +125,9 @@
             </rest>
         </webapi>
         <di>
-            <!--<Zend/Server/Reflection><shared>0</shared></Zend/Server/Reflection>-->
-            <Mage_Webapi_Controller_Router_Route_Webapi>
+            <Mage_Webapi_Controller_Router_Route>
                 <shared>0</shared>
-            </Mage_Webapi_Controller_Router_Route_Webapi>
+            </Mage_Webapi_Controller_Router_Route>
             <Mage_Xml_Generator>
                 <shared>0</shared>
             </Mage_Xml_Generator>
diff --git a/app/design/adminhtml/default/basic/boxes.css b/app/design/adminhtml/default/basic/boxes.css
index 47bd9a8d83a..4529bcc7870 100644
--- a/app/design/adminhtml/default/basic/boxes.css
+++ b/app/design/adminhtml/default/basic/boxes.css
@@ -886,6 +886,51 @@ div.autocomplete ul li { padding:.5em .7em; min-height:32px; cursor:pointer; tex
     overflow: auto;
     max-height: 500px;
 }
+.mage-suggest.category-select .mage-suggest-inner {background: transparent; position: static; border: none; border-radius: 0px; box-shadow: none;}
+.mage-suggest.category-select .category-selector-choices {background: #fff; border: 1px solid #ddd; border-radius: 5px; box-shadow: none; overflow: hidden;}
+.mage-suggest.category-select .category-selector-choices li {float: left; margin: 5px 0 5px 7px;}
+.mage-suggest.category-select .category-selector-search-field input {
+    background: none repeat scroll 0 0 transparent !important;
+    border: 0 none;
+    box-shadow: none;
+    font-family: sans-serif;
+    font-size: 100%;
+    height: 22px;
+    margin: 1px 0;
+    outline: 0 none;
+    padding: 0 5;
+}
+.mage-suggest.category-select .mage-suggest-dropdown {
+    position: absolute;
+    width: 100%;
+    background: #fff; border: 1px solid #ddd; border-radius: 5px;
+    margin-top: 2px;
+}
+.mage-suggest-dropdown .jstree-default.jstree-focused {
+    background: #ffffff;
+}
+.mage-suggest-dropdown .jstree li {
+    margin-left: 18px;
+}
+.mage-suggest-dropdown .jstree > ul > li {
+    margin-left: 0px;
+}
+.mage-suggest-dropdown .jstree a {
+    padding: 2px 3px;
+}
+.mage-suggest-dropdown .jstree .jstree-hovered {
+    border: none;
+    background: #efefef;
+}
+.mage-suggest-dropdown .jstree .jstree-clicked {
+    border: none;
+    background: #e5e5e5;
+}
+.mage-suggest-dropdown .category-path {
+    color: #777777;
+    margin-left: 7px;
+    font-size: 11px;
+}
 
 /* Footer */
 .footer .bug-report                     { float:left; width:35%; text-align:left; }
diff --git a/app/design/frontend/default/iphone/Mage_CatalogSearch/form.mini.phtml b/app/design/frontend/default/iphone/Mage_CatalogSearch/form.mini.phtml
index 5ddae748685..549d2c85bdc 100644
--- a/app/design/frontend/default/iphone/Mage_CatalogSearch/form.mini.phtml
+++ b/app/design/frontend/default/iphone/Mage_CatalogSearch/form.mini.phtml
@@ -23,17 +23,19 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-/* @var $this Mage_Core_Block_Template */
-/* @var $catalogSearchHelper Mage_CatalogSearch_Helper_Data */
-$catalogSearchHelper =  $this->helper('Mage_CatalogSearch_Helper_Data');
 ?>
-<form id="search_mini_form" action="<?php echo $catalogSearchHelper->getResultUrl() ?>" method="get">
-    <input type="search" name="<?php echo $this->helper('Mage_CatalogSearch_Helper_Data')->getQueryParamName() ?>" id="search" placeholder="Search" maxlength="<?php echo $catalogSearchHelper->getMaxQueryLength();?>"/>
+<?php
+/** @var $this Mage_Core_Block_Template */
+/** @var $helper Mage_CatalogSearch_Helper_Data */
+$helper = $this->helper('Mage_CatalogSearch_Helper_Data');
+?>
+<form id="search_mini_form" action="<?php echo $helper->getResultUrl() ?>" method="get">
+    <input type="search" name="<?php echo $helper->getQueryParamName() ?>" id="search" placeholder="Search" maxlength="<?php echo $helper->getMaxQueryLength();?>"/>
     <div id="search_autocomplete" class="search-autocomplete"></div>
 </form>
 <script type="text/javascript">
     //<![CDATA[
-    var searchForm = new Varien.searchForm('search_mini_form', 'search', '<?php echo $this->__('Search') ?>');
-    searchForm.initAutocomplete('<?php echo $catalogSearchHelper->getSuggestUrl() ?>', 'search_autocomplete');
+    var searchForm = new Varien.searchForm('search_mini_form', 'search', '<?php echo $helper->__('Search') ?>');
+    searchForm.initAutocomplete('<?php echo $helper->getSuggestUrl() ?>', 'search_autocomplete');
     //]]>
 </script>
diff --git a/app/design/frontend/default/modern/Mage_CatalogSearch/form.mini.phtml b/app/design/frontend/default/modern/Mage_CatalogSearch/form.mini.phtml
index fb416de6960..924848848d2 100644
--- a/app/design/frontend/default/modern/Mage_CatalogSearch/form.mini.phtml
+++ b/app/design/frontend/default/modern/Mage_CatalogSearch/form.mini.phtml
@@ -24,10 +24,15 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 ?>
-<form id="search_mini_form" action="<?php echo $this->helper('Mage_CatalogSearch_Helper_Data')->getResultUrl() ?>"
+<?php
+/** @var $this Mage_Core_Block_Template */
+/** @var $helper Mage_CatalogSearch_Helper_Data */
+$helper = $this->helper('Mage_CatalogSearch_Helper_Data');
+?>
+<form id="search_mini_form" action="<?php echo $helper->getResultUrl() ?>"
       method="get">
     <div class="form-search">
-        <label for="search"><?php echo $this->__('Search site:') ?></label><input id="search" type="text" name="<?php echo $this->helper('Mage_CatalogSearch_Helper_Data')->getQueryParamName() ?>" value="<?php echo $this->helper('Mage_CatalogSearch_Helper_Data')->getEscapedQueryText() ?>" class="input-text" autocomplete="off"/>&nbsp;<button type="submit" title="<?php echo $this->__('Go') ?>" class="button"><span><span><?php echo $this->__('Go') ?></span></span></button><a href="<?php echo Mage::helper('Mage_CatalogSearch_Helper_Data')->getAdvancedSearchUrl(); ?>"><?php echo $this->__('Advanced Search'); ?></a>
+        <label for="search"><?php echo $helper->__('Search:') ?></label><input id="search" type="text" name="<?php echo $helper->getQueryParamName() ?>" value="<?php echo $helper->getEscapedQueryText() ?>" class="input-text" autocomplete="off"/>&nbsp;<button type="submit" title="<?php echo $helper->__('Search') ?>" class="button"><span><span><?php echo $helper->__('Search') ?></span></span></button><a href="<?php echo $helper->getAdvancedSearchUrl(); ?>"><?php echo $helper->__('Advanced Search'); ?></a>
         <div id="search_autocomplete" class="search-autocomplete"></div>
         <script type="text/javascript">
         //<![CDATA[
@@ -35,8 +40,8 @@
             head.js("<?php echo $this->getViewFileUrl('Mage_CatalogSearch::form-mini.js')?>", function() {
                 $('#search').catalogSearch({
                     formSelector: '#search_mini_form',
-                    placeholder: '<?php echo $this->__('Search entire store here...') ?>',
-                    url: '<?php echo $this->helper('Mage_CatalogSearch_Helper_Data')->getSuggestUrl() ?>',
+                    placeholder: '<?php echo $helper->__('Search entire store here...') ?>',
+                    url: '<?php echo $helper->getSuggestUrl() ?>',
                     destinationSelector: '#search_autocomplete'
                 });
             });
diff --git a/dev/shell/install.php b/dev/shell/install.php
index f383725f2b9..557cdf5c1da 100644
--- a/dev/shell/install.php
+++ b/dev/shell/install.php
@@ -64,7 +64,8 @@ define('BARE_BOOTSTRAP', 1);
 require_once __DIR__ . '/../../app/bootstrap.php';
 
 $installer = new Mage_Install_Model_Installer_Console(
-    new Magento_Filesystem(new Magento_Filesystem_Adapter_Local())
+    new Magento_Filesystem(new Magento_Filesystem_Adapter_Local()),
+    $args
 );
 if (isset($args['show_locales'])) {
     var_export($installer->getAvailableLocales());
diff --git a/dev/tests/integration/framework/Magento/Test/Annotation/AppIsolation.php b/dev/tests/integration/framework/Magento/Test/Annotation/AppIsolation.php
index 17e75d27f2c..4e8be43ed80 100644
--- a/dev/tests/integration/framework/Magento/Test/Annotation/AppIsolation.php
+++ b/dev/tests/integration/framework/Magento/Test/Annotation/AppIsolation.php
@@ -38,96 +38,9 @@ class Magento_Test_Annotation_AppIsolation
     private $_hasNonIsolatedTests = true;
 
     /**
-     * Should clearStaticVariables() be invoked in endTestSuite()
-     *
-     * @var bool
-     */
-    protected $_runClearStatics = false;
-
-    /**
-     * Directories to clear static variables
-     *
-     * @var array
+     * @var Zend_Cache_Core
      */
-    protected static $_cleanableFolders = array(
-        '/app/code/',
-        '/dev/tests/',
-        '/lib/',
-    );
-
-    /**
-     * Classes to exclude from static variables cleaning
-     *
-     * @var array
-     */
-    protected static $_classesToSkip = array(
-        'Mage',
-        'Magento_Test_Bootstrap',
-        'Magento_Test_Event_Magento',
-        'Magento_Test_Event_PhpUnit',
-        'Magento_Test_Annotation_AppIsolation',
-    );
-
-    /**
-     * Check whether it is allowed to clean given class static variables
-     *
-     * @param ReflectionClass $reflectionClass
-     * @return bool
-     */
-    protected static function _isClassCleanable(ReflectionClass $reflectionClass)
-    {
-        // 1. do not process php internal classes
-        if ($reflectionClass->isInternal()) {
-            return false;
-        }
-
-        // 2. do not process blacklisted classes from integration framework
-        foreach (self::$_classesToSkip as $notCleanableClass) {
-            if ($reflectionClass->getName() == $notCleanableClass
-                || is_subclass_of($reflectionClass->getName(), $notCleanableClass)
-            ) {
-                return false;
-            }
-        }
-
-        // 3. process only files from specific folders
-        $fileName = $reflectionClass->getFileName();
-
-        if ($fileName) {
-            $fileName = str_replace('\\', '/', $fileName);
-            foreach (self::$_cleanableFolders as $directory) {
-                if (stripos($fileName, $directory) !== false) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Clear static variables (after running controller test case)
-     * @TODO: workaround to reduce memory leak
-     * @TODO: refactor all code where objects are stored to static variables to use object manager instead
-     */
-    public static function clearStaticVariables()
-    {
-        $classes = get_declared_classes();
-
-        foreach ($classes as $class) {
-            $reflectionCLass = new ReflectionClass($class);
-            if (self::_isClassCleanable($reflectionCLass)) {
-                $staticProperties = $reflectionCLass->getProperties(ReflectionProperty::IS_STATIC);
-                foreach ($staticProperties as $staticProperty) {
-                    $staticProperty->setAccessible(true);
-                    $value = $staticProperty->getValue();
-                    if (is_object($value) || (is_array($value) && is_object(current($value)))) {
-                        $staticProperty->setValue(null);
-                    }
-                    unset($value);
-                }
-            }
-        }
-    }
+    private $_cache;
 
     /**
      * Isolate global application objects
@@ -147,7 +60,10 @@ class Magento_Test_Annotation_AppIsolation
      */
     protected function _cleanupCache()
     {
-        Mage::app()->getCache()->clean(
+        if (!$this->_cache) {
+            $this->_cache = Mage::app()->getCache();
+        }
+        $this->_cache->clean(
             Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG,
             array(Mage_Core_Model_Config::CACHE_TAG,
                 Varien_Db_Adapter_Pdo_Mysql::DDL_CACHE_TAG,
@@ -194,31 +110,12 @@ class Magento_Test_Annotation_AppIsolation
             }
             $isIsolationEnabled = $isolation === array('enabled');
         } else {
-            if ($test instanceof Magento_Test_TestCase_ControllerAbstract) {
-                $this->_runClearStatics = true;
-                /* Controller tests should be isolated by default */
-                $isIsolationEnabled = true;
-            } else {
-                $isIsolationEnabled = false;
-            }
+            /* Controller tests should be isolated by default */
+            $isIsolationEnabled = $test instanceof Magento_Test_TestCase_ControllerAbstract;
         }
 
         if ($isIsolationEnabled) {
             $this->_isolateApp();
         }
     }
-
-    /**
-     * Clear static cache
-     */
-    public function endTestSuite()
-    {
-        if ($this->_runClearStatics) {
-            self::clearStaticVariables();
-            // forced garbage collection to avoid process non-zero exit code (exec returned: 139) caused by PHP bug
-            gc_collect_cycles();
-
-            $this->_runClearStatics = false;
-        }
-    }
 }
diff --git a/dev/tests/integration/framework/Magento/Test/Bootstrap.php b/dev/tests/integration/framework/Magento/Test/Bootstrap.php
index 6f787cad3fc..b79a7e56c2e 100644
--- a/dev/tests/integration/framework/Magento/Test/Bootstrap.php
+++ b/dev/tests/integration/framework/Magento/Test/Bootstrap.php
@@ -24,7 +24,6 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-require_once __DIR__ . '/../../../../../../lib/Varien/Simplexml/Element.php';
 
 /**
  * Tests entry point. Implements application installation, initialization and uninstall
@@ -106,18 +105,11 @@ class Magento_Test_Bootstrap
     protected $_installEtcDir;
 
     /**
-     * Temporary directory
-     *
-     * @var string
-     */
-    protected $_tmpDir;
-
-    /**
-     * Application initialization options
+     * Application initialization parameters
      *
      * @var array
      */
-    protected $_options = array();
+    protected $_initParams = array();
 
     /**
      * DB vendor name
@@ -204,24 +196,22 @@ class Magento_Test_Bootstrap
         $this->_globalEtcFiles = $this->_exposeFiles($globalEtcFiles);
         $this->_moduleEtcFiles = $this->_exposeFiles($moduleEtcFiles);
         $this->_customXmlFile  = $customXmlFile;
-        $this->_tmpDir         = $tmpDir;
 
         $this->_readLocalXml();
-        $this->_verifyDirectories();
+        $this->_verifyDirectories($tmpDir);
 
         $sandboxUniqueId = md5(sha1_file($this->_localXmlFile) . '_' . $globalEtcFiles . '_' . $moduleEtcFiles);
-        $this->_installDir = "{$tmpDir}/sandbox-{$this->_dbVendorName}-{$sandboxUniqueId}";
-        $this->_installEtcDir = $this->_installDir . '/etc';
-
-        $this->_options = array(
-            'etc_dir'     => $this->_installEtcDir,
-            'var_dir'     => $this->_installDir,
-            'tmp_dir'     => $this->_installDir . DIRECTORY_SEPARATOR . 'tmp',
-            'cache_dir'   => $this->_installDir . DIRECTORY_SEPARATOR . 'cache',
-            'log_dir'     => $this->_installDir . DIRECTORY_SEPARATOR . 'log',
-            'session_dir' => $this->_installDir . DIRECTORY_SEPARATOR . 'session',
-            'media_dir'   => $this->_installDir . DIRECTORY_SEPARATOR . 'media',
-            'upload_dir'  => $this->_installDir . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR . 'upload',
+        $installDir = "{$tmpDir}/sandbox-{$this->_dbVendorName}-{$sandboxUniqueId}";
+        $this->_ensureDirExists($installDir);
+        $this->_installDir = $installDir;
+        $this->_installEtcDir = "{$installDir}/etc";
+
+        $this->_initParams = array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::CONFIG => $this->_installEtcDir,
+                Mage_Core_Model_Dir::VAR_DIR => $installDir,
+                Mage_Core_Model_Dir::MEDIA => "{$installDir}/media",
+            ),
         );
 
         $this->_db = $this->_instantiateDb($shell);
@@ -229,19 +219,26 @@ class Magento_Test_Bootstrap
         if ($isCleanupEnabled) {
             $this->_cleanup();
         }
-        $this->_ensureDirExists($this->_installDir);
 
         $this->_isDeveloperMode = $isDeveloperMode;
 
         $this->_emulateEnvironment();
 
         if ($this->_isInstalled()) {
-            $this->initialize();
+            $this->_initialize($this->_initParams);
         } else {
             $this->_install();
         }
     }
 
+    /**
+     * Get directory path with application instance custom data (cache, temporary directory, etc...)
+     */
+    public function getInstallDir()
+    {
+        return $this->_installDir;
+    }
+
     /**
      * Get DB vendor name
      *
@@ -254,53 +251,52 @@ class Magento_Test_Bootstrap
 
     /**
      * Initialize an already installed Magento application
+     *
+     * @param array $initParams
      */
-    public function initialize()
+    protected function _initialize($initParams)
     {
         Mage::setIsDeveloperMode($this->_isDeveloperMode);
-        Mage_Core_Utility_Theme::registerDesignMock();
         Mage::$headersSentThrowsException = false;
-        Mage::app('', 'store', $this->_options);
+        Mage::app($initParams);
     }
 
     /**
      * Initialize an already installed Magento application
+     *
+     * @param array $additionalParams
      */
-    public function reinitialize()
+    public function reinitialize(array $additionalParams = array())
     {
-        $this->resetApp();
-        $this->initialize();
+        $this->_resetApp();
+        $this->_initialize($this->_customizeParams($additionalParams));
     }
 
     /**
-     * Re-create empty temporary dir by specified
+     * Run application normally, but with encapsulated initialization options
      *
-     * @param string $optionCode
-     * @throws Magento_Exception if one of protected directories specified
+     * @param array $additionalParams
      */
-    public function cleanupDir($optionCode)
+    public function runApp(array $additionalParams)
     {
-        if (in_array($optionCode, array('etc_dir', 'var_dir', 'media_dir'))) {
-            throw new Magento_Exception("Directory '{$optionCode}' must not be cleaned up while running tests.");
-        }
-        $dir = $this->_options[$optionCode];
-        $this->_removeDirectory($dir, false);
+        Mage::run($this->_customizeParams($additionalParams));
     }
 
     /**
-     * Get application initialization options
+     * Sub-routine for merging custom parameters with the ones defined in object state
      *
+     * @param array $params
      * @return array
      */
-    public function getAppOptions()
+    private function _customizeParams($params)
     {
-        return $this->_options;
+        return array_replace_recursive($this->_initParams, $params);
     }
 
     /**
      * Reset application global state
      */
-    public function resetApp()
+    protected function _resetApp()
     {
         /** @var $objectManager Magento_Test_ObjectManager */
         $objectManager = Mage::getObjectManager();
@@ -360,17 +356,18 @@ class Magento_Test_Bootstrap
     /**
      * Check all required directories contents and permissions
      *
+     * @param string $tmpDir
      * @throws Magento_Exception when any of required directories is not eligible
      */
-    protected function _verifyDirectories()
+    protected function _verifyDirectories($tmpDir)
     {
         /* Magento application dir */
         if (!is_file($this->_magentoDir . '/app/bootstrap.php')) {
             throw new Magento_Exception('Unable to locate Magento root folder and bootstrap.php.');
         }
         /* Temporary directory */
-        if (!is_dir($this->_tmpDir) || !is_writable($this->_tmpDir)) {
-            throw new Magento_Exception("The '{$this->_tmpDir}' is not a directory or not writable.");
+        if (!is_dir($tmpDir) || !is_writable($tmpDir)) {
+            throw new Magento_Exception("The '{$tmpDir}' is not a directory or not writable.");
         }
     }
 
@@ -502,7 +499,7 @@ class Magento_Test_Bootstrap
         $this->_localXml->asNiceXml($targetLocalXml);
 
         /* Initialize an application in non-installed mode */
-        $this->initialize();
+        $this->_initialize($this->_initParams);
 
         /* Run all install and data-install scripts */
         Mage_Core_Model_Resource_Setup::applyAllUpdates();
@@ -523,7 +520,7 @@ class Magento_Test_Bootstrap
         $this->_createAdminUser();
 
         /* Switch an application to installed mode */
-        $this->initialize();
+        $this->_initialize($this->_initParams);
     }
 
     /**
@@ -585,24 +582,24 @@ class Magento_Test_Bootstrap
         ));
         $roleUser->save();
     }
-
+    
     /**
-     * Returns path to framework's temporary directory
+     * Returns path to integration tests root directory
      *
      * @return string
      */
-    public function getTmpDir()
+    public function getTestsDir()
     {
-        return $this->_tmpDir;
+        return $this->_testsDir;
     }
 
     /**
-     * Returns path to integration tests root directory
+     * Get application initialization parameters
      *
-     * @return string
+     * @return array
      */
-    public function getTestsDir()
+    public function getInitParams()
     {
-        return $this->_testsDir;
+        return $this->_initParams;
     }
 }
diff --git a/dev/tests/integration/framework/Magento/Test/Helper/Api.php b/dev/tests/integration/framework/Magento/Test/Helper/Api.php
new file mode 100644
index 00000000000..6789a751b05
--- /dev/null
+++ b/dev/tests/integration/framework/Magento/Test/Helper/Api.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * Helper for API integration tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Magento_Test_Helper_Api
+{
+    /**
+     * Call API method via API handler.
+     *
+     * @param PHPUnit_Framework_TestCase $testCase Active test case
+     * @param string $path
+     * @param array $params Order of items matters as they are passed to call_user_func_array
+     * @return mixed
+     */
+    public static function call(PHPUnit_Framework_TestCase $testCase, $path, $params = array())
+    {
+        $soapAdapterMock = $testCase->getMock('Mage_Api_Model_Server_Adapter_Soap', array('fault'));
+        $soapAdapterMock->expects($testCase->any())->method('fault')->will(
+            $testCase->returnCallback(array(__CLASS__, 'soapAdapterFaultCallback'))
+        );
+
+        $serverMock = $testCase->getMock('Mage_Api_Model_Server', array('getAdapter'));
+        $serverMock->expects($testCase->any())->method('getAdapter')->will($testCase->returnValue($soapAdapterMock));
+
+        $apiSessionMock = $testCase->getMock('Mage_Api_Model_Session', array('isAllowed', 'isLoggedIn'));
+        $apiSessionMock->expects($testCase->any())->method('isAllowed')->will($testCase->returnValue(true));
+        $apiSessionMock->expects($testCase->any())->method('isLoggedIn')->will($testCase->returnValue(true));
+
+        $handlerMock = $testCase->getMock('Mage_Api_Model_Server_Handler_Soap', array('_getServer', '_getSession'));
+        $handlerMock->expects($testCase->any())->method('_getServer')->will($testCase->returnValue($serverMock));
+        $handlerMock->expects($testCase->any())->method('_getSession')->will($testCase->returnValue($apiSessionMock));
+
+        array_unshift($params, 'sessionId');
+        Mage::unregister('isSecureArea');
+        Mage::register('isSecureArea', true);
+        $result = call_user_func_array(array($handlerMock, $path), $params);
+        Mage::unregister('isSecureArea');
+        Mage::register('isSecureArea', false);
+        return $result;
+    }
+
+    /**
+     * Throw SoapFault exception. Callback for 'fault' method of API.
+     *
+     * @param string $exceptionCode
+     * @param string $exceptionMessage
+     * @throws SoapFault
+     */
+    public static function soapAdapterFaultCallback($exceptionCode, $exceptionMessage)
+    {
+        throw new SoapFault($exceptionCode, $exceptionMessage);
+    }
+
+    /**
+     * Convert Simple XML to array
+     *
+     * @param SimpleXMLObject $xml
+     * @param String $keyTrimmer
+     * @return object
+     *
+     * In XML notation we can't have nodes with digital names in other words fallowing XML will be not valid:
+     * &lt;24&gt;
+     *      Default category
+     * &lt;/24&gt;
+     *
+     * But this one will not cause any problems:
+     * &lt;qwe_24&gt;
+     *      Default category
+     * &lt;/qwe_24&gt;
+     *
+     * So when we want to obtain an array with key 24 we will pass the correct XML from above and $keyTrimmer = 'qwe_';
+     * As a result we will obtain an array with digital key node.
+     *
+     * In the other case just don't pass the $keyTrimmer.
+     */
+    public static function simpleXmlToArray($xml, $keyTrimmer = null)
+    {
+        $result = array();
+
+        $isTrimmed = false;
+        if (null !== $keyTrimmer) {
+            $isTrimmed = true;
+        }
+
+        if (is_object($xml)) {
+            foreach (get_object_vars($xml->children()) as $key => $node) {
+                $arrKey = $key;
+                if ($isTrimmed) {
+                    $arrKey = str_replace($keyTrimmer, '', $key); //, &$isTrimmed);
+                }
+                if (is_numeric($arrKey)) {
+                    $arrKey = 'Obj' . $arrKey;
+                }
+                if (is_object($node)) {
+                    $result[$arrKey] = self::simpleXmlToArray($node, $keyTrimmer);
+                } elseif (is_array($node)) {
+                    $result[$arrKey] = array();
+                    foreach ($node as $nodeValue) {
+                        $result[$arrKey][] = self::simpleXmlToArray(
+                            $nodeValue,
+                            $keyTrimmer
+                        );
+                    }
+                } else {
+                    $result[$arrKey] = (string)$node;
+                }
+            }
+        } else {
+            $result = (string)$xml;
+        }
+        return $result;
+    }
+
+    /**
+     * Check specific fields value in some entity data.
+     *
+     * @param PHPUnit_Framework_TestCase $testCase
+     * @param array $expectedData
+     * @param array $actualData
+     * @param array $fieldsToCompare To be able to compare fields from loaded model with fields from API response
+     *     this parameter provides fields mapping.
+     *     Array can store model field name $entityField mapped on field name in API response.
+     *     $fieldsToCompare format is:
+     *     $fieldsToCompare = array($modelFieldName => $apiResponseFieldName);
+     *     Example:
+     *     $fieldsToCompare = array(
+     *         'entity_id' => 'product_id',
+     *         'sku',
+     *         'attribute_set_id' => 'set',
+     *         'type_id' => 'type',
+     *         'category_ids',
+     *     );
+     */
+    public static function checkEntityFields(
+        PHPUnit_Framework_TestCase $testCase,
+        array $expectedData,
+        array $actualData,
+        array $fieldsToCompare = array()
+    ) {
+        $fieldsToCompare = !empty($fieldsToCompare) ? $fieldsToCompare : array_keys($expectedData);
+        foreach ($fieldsToCompare as $entityField => $field) {
+            $testCase->assertEquals(
+                $expectedData[is_numeric($entityField) ? $field : $entityField],
+                $actualData[$field],
+                sprintf('"%s" filed has invalid value.', $field)
+            );
+        }
+    }
+}
diff --git a/dev/tests/integration/framework/Magento/Test/Helper/Eav.php b/dev/tests/integration/framework/Magento/Test/Helper/Eav.php
new file mode 100644
index 00000000000..4d7f0d86b80
--- /dev/null
+++ b/dev/tests/integration/framework/Magento/Test/Helper/Eav.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Helper for EAV functionality in integration tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Magento_Test_Helper_Eav
+{
+    /**
+     * Set increment id prefix in entity model.
+     *
+     * @param string $entityType
+     * @param string $prefix
+     */
+    public static function setIncrementIdPrefix($entityType, $prefix)
+    {
+        $website = Mage::app()->getWebsite();
+        $storeId = $website->getDefaultStore()->getId();
+        $entityTypeModel = Mage::getModel('Mage_Eav_Model_Entity_Type')->loadByCode($entityType);
+        /** @var Mage_Eav_Model_Entity_Store $entityStore */
+        $entityStore = Mage::getModel('Mage_Eav_Model_Entity_Store')->loadByEntityStore(
+            $entityTypeModel->getId(),
+            $storeId
+        );
+        $entityStore->setEntityTypeId($entityTypeModel->getId());
+        $entityStore->setStoreId($storeId);
+        $entityStore->setIncrementPrefix($prefix);
+        $entityStore->save();
+    }
+}
diff --git a/dev/tests/integration/framework/Magento/Test/ObjectManager.php b/dev/tests/integration/framework/Magento/Test/ObjectManager.php
index 2c049df6c16..e37a4cc610d 100644
--- a/dev/tests/integration/framework/Magento/Test/ObjectManager.php
+++ b/dev/tests/integration/framework/Magento/Test/ObjectManager.php
@@ -27,18 +27,6 @@
 
 class Magento_Test_ObjectManager extends Magento_ObjectManager_Zend
 {
-    /**
-     * Classes with xml properties to explicitly call __destruct() due to https://bugs.php.net/bug.php?id=62468
-     *
-     * @var array
-     */
-    protected $_classesToDestruct = array(
-        'Mage_Core_Model_Config',
-        'Mage_Core_Model_Layout',
-        'Mage_Core_Model_Layout_Merge',
-        'Mage_Core_Model_Layout_ScheduledStructure',
-    );
-
     /**
      * Clear InstanceManager cache
      *
@@ -46,16 +34,6 @@ class Magento_Test_ObjectManager extends Magento_ObjectManager_Zend
      */
     public function clearCache()
     {
-        foreach ($this->_classesToDestruct as $className) {
-            if ($this->hasSharedInstance($className)) {
-                $object = $this->get($className);
-                if ($object) {
-                    // force to cleanup circular references
-                    $object->__destruct();
-                }
-            }
-        }
-
         $instanceManagerNew = new Magento_Di_InstanceManager_Zend();
         $instanceManagerNew->addSharedInstance($this, 'Magento_ObjectManager');
         if ($this->_di->instanceManager()->hasSharedInstance('Mage_Core_Model_Resource')) {
diff --git a/dev/tests/integration/framework/Magento/Test/TestCase/ControllerAbstract.php b/dev/tests/integration/framework/Magento/Test/TestCase/ControllerAbstract.php
index b63f1ab1f4e..e0e64a7dd36 100644
--- a/dev/tests/integration/framework/Magento/Test/TestCase/ControllerAbstract.php
+++ b/dev/tests/integration/framework/Magento/Test/TestCase/ControllerAbstract.php
@@ -64,19 +64,12 @@ abstract class Magento_Test_TestCase_ControllerAbstract extends PHPUnit_Framewor
 
     /**
      * Bootstrap application before eny test
-     *
-     * @return void
      */
     protected function setUp()
     {
         $this->_objectManager = Mage::getObjectManager();
-
-        /**
-         * Use run options from bootstrap
-         */
-        $this->_runOptions = $this->_getBootstrap()->getAppOptions();
-        $this->_runOptions['request']   = $this->getRequest();
-        $this->_runOptions['response']  = $this->getResponse();
+        $this->_runOptions[Mage::INIT_OPTION_REQUEST]  = $this->getRequest();
+        $this->_runOptions[Mage::INIT_OPTION_RESPONSE] = $this->getResponse();
     }
 
     protected function tearDown()
@@ -95,7 +88,7 @@ abstract class Magento_Test_TestCase_ControllerAbstract extends PHPUnit_Framewor
     public function dispatch($uri)
     {
         $this->getRequest()->setRequestUri($uri);
-        Mage::run($this->_runCode, $this->_runScope, $this->_runOptions);
+        $this->_getBootstrap()->runApp($this->_runOptions);
     }
 
     /**
diff --git a/dev/tests/integration/framework/Magento/Test/Workaround/Cleanup/StaticProperties.php b/dev/tests/integration/framework/Magento/Test/Workaround/Cleanup/StaticProperties.php
new file mode 100644
index 00000000000..54c500ebe3b
--- /dev/null
+++ b/dev/tests/integration/framework/Magento/Test/Workaround/Cleanup/StaticProperties.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.
+ *
+ * @category    Magento
+ * @package     Magento
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Workaround for decreasing memory consumption by cleaning up static properties
+ */
+class Magento_Test_Workaround_Cleanup_StaticProperties
+{
+    /**
+     * Directories to clear static variables
+     *
+     * @var array
+     */
+    protected static $_cleanableFolders = array(
+        '/app/code/',
+        '/dev/tests/',
+        '/lib/',
+    );
+
+    /**
+     * Classes to exclude from static variables cleaning
+     *
+     * @var array
+     */
+    protected static $_classesToSkip = array(
+        'Mage',
+        'Magento_Test_Bootstrap',
+        'Magento_Test_Event_Magento',
+        'Magento_Test_Event_PhpUnit',
+        'Magento_Test_Annotation_AppIsolation',
+    );
+
+    /**
+     * Check whether it is allowed to clean given class static variables
+     *
+     * @param ReflectionClass $reflectionClass
+     * @return bool
+     */
+    protected static function _isClassCleanable(ReflectionClass $reflectionClass)
+    {
+        // 1. do not process php internal classes
+        if ($reflectionClass->isInternal()) {
+            return false;
+        }
+
+        // 2. do not process blacklisted classes from integration framework
+        foreach (self::$_classesToSkip as $notCleanableClass) {
+            if ($reflectionClass->getName() == $notCleanableClass
+                || is_subclass_of($reflectionClass->getName(), $notCleanableClass)
+            ) {
+                return false;
+            }
+        }
+
+        // 3. process only files from specific folders
+        $fileName = $reflectionClass->getFileName();
+
+        if ($fileName) {
+            $fileName = str_replace('\\', '/', $fileName);
+            foreach (self::$_cleanableFolders as $directory) {
+                if (stripos($fileName, $directory) !== false) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Clear static variables (after running controller test case)
+     * @TODO: refactor all code where objects are stored to static variables to use object manager instead
+     */
+    public static function clearStaticVariables()
+    {
+        $classes = get_declared_classes();
+
+        foreach ($classes as $class) {
+            $reflectionCLass = new ReflectionClass($class);
+            if (self::_isClassCleanable($reflectionCLass)) {
+                $staticProperties = $reflectionCLass->getProperties(ReflectionProperty::IS_STATIC);
+                foreach ($staticProperties as $staticProperty) {
+                    $staticProperty->setAccessible(true);
+                    $value = $staticProperty->getValue();
+                    if (is_object($value) || (is_array($value) && is_object(current($value)))) {
+                        $staticProperty->setValue(null);
+                    }
+                    unset($value);
+                }
+            }
+        }
+    }
+
+    /**
+     * Handler for 'endTestSuite' event
+     *
+     * @param PHPUnit_Framework_TestSuite $suite
+     */
+    public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
+    {
+        $clearStatics = false;
+        foreach ($suite->tests() as $test) {
+            if ($test instanceof Magento_Test_TestCase_ControllerAbstract) {
+                $clearStatics = true;
+                break;
+            }
+        }
+        if ($clearStatics) {
+            self::clearStaticVariables();
+        }
+    }
+}
diff --git a/dev/tests/integration/framework/Magento/Test/ClearProperties.php b/dev/tests/integration/framework/Magento/Test/Workaround/Cleanup/TestCaseProperties.php
similarity index 91%
rename from dev/tests/integration/framework/Magento/Test/ClearProperties.php
rename to dev/tests/integration/framework/Magento/Test/Workaround/Cleanup/TestCaseProperties.php
index 0c01547dde3..e547eacb857 100644
--- a/dev/tests/integration/framework/Magento/Test/ClearProperties.php
+++ b/dev/tests/integration/framework/Magento/Test/Workaround/Cleanup/TestCaseProperties.php
@@ -26,9 +26,9 @@
  */
 
 /**
- * Clear test method properties, it isn't needed to unset properties manually in tearDown() anymore
+ * Automatic cleanup of test case's properties, it isn't needed to unset properties manually in tearDown() anymore
  */
-class Magento_Test_ClearProperties
+class Magento_Test_Workaround_Cleanup_TestCaseProperties
 {
     /**
      * Clear test method properties after each test suite
diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/_files/Stub.php b/dev/tests/integration/framework/Magento/Test/Workaround/Segfault.php
similarity index 81%
rename from dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/_files/Stub.php
rename to dev/tests/integration/framework/Magento/Test/Workaround/Segfault.php
index cb26d2aa4f3..7ef528ffeb4 100644
--- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/_files/Stub.php
+++ b/dev/tests/integration/framework/Magento/Test/Workaround/Segfault.php
@@ -25,15 +25,16 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-class Magento_Test_ClearProperties_Stub
+/**
+ * Workaround for occasional non-zero exit code (exec returned: 139) caused by the PHP bug
+ */
+class Magento_Test_Workaround_Segfault
 {
     /**
-     * @var boolean
+     * Force garbage collection
      */
-    public static $isDestructCalled = false;
-
-    public function __destruct()
+    public function endTestSuite()
     {
-        self::$isDestructCalled = true;
+        gc_collect_cycles();
     }
 }
diff --git a/dev/tests/integration/framework/bootstrap.php b/dev/tests/integration/framework/bootstrap.php
index 2c783a3eeca..f6109a62ea5 100644
--- a/dev/tests/integration/framework/bootstrap.php
+++ b/dev/tests/integration/framework/bootstrap.php
@@ -89,13 +89,15 @@ if (defined('TESTS_BAMBOO_PROFILER_FILE') && defined('TESTS_BAMBOO_PROFILER_METR
  * To allow config fixtures to deal with fixture stores, data fixtures should be processed before config fixtures.
  */
 $eventManager = new Magento_Test_EventManager(array(
-    new Magento_Test_ClearProperties(),
+    new Magento_Test_Workaround_Segfault(),
+    new Magento_Test_Workaround_Cleanup_TestCaseProperties(),
+    new Magento_Test_Workaround_Cleanup_StaticProperties(),
     new Magento_Test_Annotation_AppIsolation(),
     new Magento_Test_Event_Transaction(new Magento_Test_EventManager(array(
         new Magento_Test_Annotation_DbIsolation(),
         new Magento_Test_Annotation_DataFixture("$testsBaseDir/testsuite"),
     ))),
-    new Magento_Test_Annotation_ConfigFixture(),
+    new Magento_Test_Annotation_ConfigFixture()
 ));
 Magento_Test_Event_PhpUnit::setDefaultEventManager($eventManager);
 Magento_Test_Event_Magento::setDefaultEventManager($eventManager);
@@ -110,7 +112,7 @@ Magento_Test_Bootstrap::setInstance(new Magento_Test_Bootstrap(
     $localXmlFile,
     $globalEtcFiles,
     $moduleEtcFiles,
-    'etc/integration-tests-config.xml',
+    $testsBaseDir . DIRECTORY_SEPARATOR . 'etc/integration-tests-config.xml',
     $testsTmpDir,
     new Magento_Shell(),
     $isCleanupEnabled,
diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/BootstrapTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/BootstrapTest.php
index c5a1cd3e069..f4d542cd440 100644
--- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/BootstrapTest.php
+++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/BootstrapTest.php
@@ -80,7 +80,8 @@ class Magento_Test_BootstrapTest extends PHPUnit_Framework_TestCase
         $this->_bootstrap = $this->getMock(
             'Magento_Test_Bootstrap',
             array(
-                'initialize',
+                '_initialize',
+                '_resetApp',
                 '_verifyDirectories',
                 '_instantiateDb',
                 '_isInstalled',
@@ -203,7 +204,7 @@ class Magento_Test_BootstrapTest extends PHPUnit_Framework_TestCase
         ;
         $this->_bootstrap
             ->expects($this->once())
-            ->method('initialize')
+            ->method('_initialize')
         ;
         $this->_callBootstrapConstructor();
     }
@@ -269,33 +270,64 @@ class Magento_Test_BootstrapTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * @dataProvider cleanupDirExceptionDataProvider
-     * @expectedException Magento_Exception
+     * @param $origParams
+     * @param $customParams
+     * @param $expectedResult
+     * @dataProvider reinitializeDataProvider
      */
-    public function testCleanupDirException($optionCode)
+    public function testReinitialize($origParams, $customParams, $expectedResult)
     {
-        $this->_bootstrap->cleanupDir($optionCode);
+
+        $property = new ReflectionProperty(get_class($this->_bootstrap), '_initParams');
+        $property->setAccessible(true);
+        $property->setValue($this->_bootstrap, $origParams);
+
+        $this->_bootstrap->expects($this->once())->method('_resetApp');
+        $this->_bootstrap->expects($this->once())->method('_initialize')->with($expectedResult);
+
+        $this->_bootstrap->reinitialize($customParams);
     }
 
     /**
      * @return array
      */
-    public function cleanupDirExceptionDataProvider()
+    public function reinitializeDataProvider()
     {
+        $origParams = array('one' => array('two' => 'three'));
         return array(
-            'etc'   => array('etc_dir'),
-            'var'   => array('var_dir'),
-            'media' => array('media_dir'),
+            array(
+                $origParams,
+                array(),
+                $origParams
+            ),
+            array(
+                $origParams,
+                array('one' => array('four' => 'five')),
+                array('one' => array('two' => 'three', 'four' => 'five'))
+            ),
+            array(
+                $origParams,
+                array('one' => array('two' => 'five')),
+                array('one' => array('two' => 'five'))
+            ),
         );
     }
 
-    public function testGetTmpDir()
+    public function testGetTestsDir()
     {
-        $this->assertEquals(self::$_tmpDir, $this->_bootstrap->getTmpDir());
+        $this->assertEquals(self::$_testsDir, $this->_bootstrap->getTestsDir());
     }
 
-    public function testGetTestsDir()
+    public function testGetInitParams()
     {
-        $this->assertEquals(self::$_testsDir, $this->_bootstrap->getTestsDir());
+        $initParams = $this->_bootstrap->getInitParams();
+        $this->_bootstrap->expects($this->once())
+            ->method('_initialize')
+            ->with($initParams);
+        $this->_bootstrap->expects($this->once())
+            ->method('_isInstalled')
+            ->will($this->returnValue(true));
+
+        $this->_callBootstrapConstructor();
     }
 }
diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ClearPropertiesTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ClearPropertiesTest.php
deleted file mode 100644
index 737f1c5ac1f..00000000000
--- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ClearPropertiesTest.php
+++ /dev/null
@@ -1,118 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Magento
- * @package     Magento
- * @subpackage  integration_tests
- * @copyright   Copyright (c) 2013 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_Test_ClearProperties.
- */
-class Magento_Test_ClearPropertiesTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var array
-     */
-    protected $_properties = array(
-        array(
-            'name' => 'testPublic',
-            'is_static' => false,
-            'expectedValue' => 'public',
-        ),
-        array(
-            'name' => '_testPrivate',
-            'is_static' => false,
-            'expectedValue' => 'private',
-        ),
-        array(
-            'name' => '_testPropertyBoolean',
-            'is_static' => false,
-            'expectedValue' => true,
-        ),
-        array(
-            'name' => '_testPropertyInteger',
-            'is_static' => false,
-            'expectedValue' => 10,
-        ),
-        array(
-            'name' => '_testPropertyFloat',
-            'is_static' => false,
-            'expectedValue' => 1.97,
-        ),
-        array(
-            'name' => '_testPropertyString',
-            'is_static' => false,
-            'expectedValue' => 'string',
-        ),
-        array(
-            'name' => '_testPropertyArray',
-            'is_static' => false,
-            'expectedValue' => array('test', 20),
-        ),
-        array(
-            'name' => 'testPublicStatic',
-            'is_static' => true,
-            'expectedValue' => 'static public',
-        ),
-        array(
-            'name' => '_testProtectedStatic',
-            'is_static' => true,
-            'expectedValue' => 'static protected',
-        ),
-        array(
-            'name' => '_testPrivateStatic',
-            'is_static' => true,
-            'expectedValue' => 'static private',
-        ),
-    );
-
-    public function testEndTestSuiteDestruct()
-    {
-        $clearProperties = new Magento_Test_ClearProperties();
-        $phpUnitTestSuite = new PHPUnit_Framework_TestSuite();
-        $phpUnitTestSuite->addTestFile(__DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR
-            . 'DummyTestCase.php'
-        );
-        // Because addTestFile() adds classes from file to tests array, use first testsuite
-        /** @var $testSuite PHPUnit_Framework_TestSuite */
-        $testSuite = $phpUnitTestSuite->testAt(0);
-        $testSuite->run();
-        $testClass = $testSuite->testAt(0);
-        foreach ($this->_properties as $property) {
-            if ($property['is_static']) {
-                $this->assertAttributeEquals($property['expectedValue'], $property['name'], get_class($testClass));
-            } else {
-                $this->assertAttributeEquals($property['expectedValue'], $property['name'], $testClass);
-            }
-        }
-        $clearProperties->endTestSuite($testSuite);
-        $this->assertTrue(Magento_Test_ClearProperties_Stub::$isDestructCalled);
-        foreach ($this->_properties as $property) {
-            if ($property['is_static']) {
-                $this->assertAttributeEmpty($property['name'], get_class($testClass));
-            } else {
-                $this->assertAttributeEmpty($property['name'], $testClass);
-            }
-        }
-    }
-}
diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ObjectManagerTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ObjectManagerTest.php
index 632e2301940..6594b5b6c17 100644
--- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ObjectManagerTest.php
+++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/ObjectManagerTest.php
@@ -42,30 +42,14 @@ class Magento_Test_ObjectManagerTest extends PHPUnit_Framework_TestCase
 
     public function testClearCache()
     {
-        $object = $this->getMock('stdClass', array('__destruct'));
-        $object
-            ->expects($this->once())
-            ->method('__destruct')
-        ;
-
-        $resource = $this->getMock('stdClass', array('__destruct'));
-        $object
-            ->expects($this->once())
-            ->method('__destruct')
-        ;
+        $resource = new stdClass;
 
         $instanceManager = new Magento_Di_InstanceManager_Zend();
-        $instanceManager->addSharedInstance($object, 'sharedInstance');
         $instanceManager->addSharedInstance($resource, 'Mage_Core_Model_Resource');
 
         $diInstance = new Magento_Di_Zend();
         $model = new Magento_Test_ObjectManager(null, $diInstance);
 
-        // Reflection is the only way to setup fixture input data in place of the hard-coded property value
-        $reflectionClass = new ReflectionProperty(get_class($model), '_classesToDestruct');
-        $reflectionClass->setAccessible(true);
-        $reflectionClass->setValue($model, array('sharedInstance', 'nonRegisteredInstance'));
-
         $diInstance->setInstanceManager($instanceManager);
         $this->assertSame($model, $model->clearCache());
         $this->assertNotSame($instanceManager, $diInstance->instanceManager());
diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Cleanup/TestCasePropertiesTest.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Cleanup/TestCasePropertiesTest.php
new file mode 100644
index 00000000000..aaf332100bb
--- /dev/null
+++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Cleanup/TestCasePropertiesTest.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.
+ *
+ * @category    Magento
+ * @package     Magento
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 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_Test_Workaround_Cleanup_TestCaseProperties.
+ */
+class Magento_Test_Workaround_Cleanup_TestCasePropertiesTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var array
+     */
+    protected $_fixtureProperties = array(
+        array('name' => 'testPublic',           'is_static' => false),
+        array('name' => '_testPrivate',         'is_static' => false),
+        array('name' => '_testPropertyBoolean', 'is_static' => false),
+        array('name' => '_testPropertyInteger', 'is_static' => false),
+        array('name' => '_testPropertyFloat',   'is_static' => false),
+        array('name' => '_testPropertyString',  'is_static' => false),
+        array('name' => '_testPropertyArray',   'is_static' => false),
+        array('name' => '_testPropertyObject',  'is_static' => false),
+        array('name' => 'testPublicStatic',     'is_static' => true),
+        array('name' => '_testProtectedStatic', 'is_static' => true),
+        array('name' => '_testPrivateStatic',   'is_static' => true),
+    );
+
+    public function testEndTestSuiteDestruct()
+    {
+        $phpUnitTestSuite = new PHPUnit_Framework_TestSuite();
+        $phpUnitTestSuite->addTestFile(__DIR__ . '/_files/DummyTestCase.php');
+        // Because addTestFile() adds classes from file to tests array, use first testsuite
+        /** @var $testSuite PHPUnit_Framework_TestSuite */
+        $testSuite = $phpUnitTestSuite->testAt(0);
+        $testSuite->run();
+        /** @var $testClass Magento_Test_Workaround_Cleanup_DummyTestCase */
+        $testClass = $testSuite->testAt(0);
+
+        $propertyObjectMock = $this->getMock('stdClass', array('__destruct'));
+        $propertyObjectMock
+            ->expects($this->once())
+            ->method('__destruct')
+        ;
+        $testClass->setPropertyObject($propertyObjectMock);
+
+        foreach ($this->_fixtureProperties as $property) {
+            if ($property['is_static']) {
+                $this->assertAttributeNotEmpty($property['name'], get_class($testClass));
+            } else {
+                $this->assertAttributeNotEmpty($property['name'], $testClass);
+            }
+        }
+
+        $clearProperties = new Magento_Test_Workaround_Cleanup_TestCaseProperties();
+        $clearProperties->endTestSuite($testSuite);
+
+        foreach ($this->_fixtureProperties as $property) {
+            if ($property['is_static']) {
+                $this->assertAttributeEmpty($property['name'], get_class($testClass));
+            } else {
+                $this->assertAttributeEmpty($property['name'], $testClass);
+            }
+        }
+    }
+}
diff --git a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/_files/DummyTestCase.php b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Cleanup/_files/DummyTestCase.php
similarity index 84%
rename from dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/_files/DummyTestCase.php
rename to dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Cleanup/_files/DummyTestCase.php
index 0570d8d31f2..5c02b9572fb 100644
--- a/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/_files/DummyTestCase.php
+++ b/dev/tests/integration/framework/tests/unit/testsuite/Magento/Test/Workaround/Cleanup/_files/DummyTestCase.php
@@ -25,14 +25,16 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-require_once __DIR__ . DIRECTORY_SEPARATOR . 'Stub.php';
-
-class Magento_Test_ClearProperties_DummyTestCase extends PHPUnit_Framework_TestCase
+class Magento_Test_Workaround_Cleanup_DummyTestCase extends PHPUnit_Framework_TestCase
 {
     /**
      * @var string
      */
     public $testPublic;
+
+    /**
+     * @var string
+     */
     private $_testPrivate;
 
     /**
@@ -61,7 +63,7 @@ class Magento_Test_ClearProperties_DummyTestCase extends PHPUnit_Framework_TestC
     protected $_testPropertyArray;
 
     /**
-     * @var mixed
+     * @var object
      */
     protected $_testPropertyObject;
 
@@ -69,7 +71,15 @@ class Magento_Test_ClearProperties_DummyTestCase extends PHPUnit_Framework_TestC
      * @var string
      */
     static public $testPublicStatic;
+
+    /**
+     * @var string
+     */
     static protected $_testProtectedStatic;
+
+    /**
+     * @var string
+     */
     static private $_testPrivateStatic;
 
     public function testDummy()
@@ -81,9 +91,18 @@ class Magento_Test_ClearProperties_DummyTestCase extends PHPUnit_Framework_TestC
         $this->_testPropertyFloat = 1.97;
         $this->_testPropertyString = 'string';
         $this->_testPropertyArray = array('test', 20);
-        $this->_testPropertyObject = new Magento_Test_ClearProperties_Stub();
         self::$testPublicStatic = 'static public';
         self::$_testProtectedStatic = 'static protected';
         self::$_testPrivateStatic = 'static private';
     }
+
+    /**
+     * Assign value to the object property
+     *
+     * @param object $object
+     */
+    public function setPropertyObject($object)
+    {
+        $this->_testPropertyObject = $object;
+    }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Category/TreeTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Category/TreeTest.php
index 83598e82947..29decfe9f8b 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Category/TreeTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Catalog/Category/TreeTest.php
@@ -42,7 +42,7 @@ class Mage_Adminhtml_Block_Catalog_Category_TreeTest extends PHPUnit_Framework_T
     public function testGetSuggestedCategoriesJson()
     {
         $this->assertEquals(
-            '[{"id":"2","children":[],"is_active":"1","name":"Default Category"}]',
+            '[{"id":"2","children":[],"is_active":"1","label":"Default Category"}]',
             $this->_block->getSuggestedCategoriesJson('Default')
         );
         $this->assertEquals(
diff --git a/app/code/core/Mage/Webapi/Controller/Router/Route/Webapi.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Notification/BaseurlTest.php
similarity index 70%
rename from app/code/core/Mage/Webapi/Controller/Router/Route/Webapi.php
rename to dev/tests/integration/testsuite/Mage/Adminhtml/Block/Notification/BaseurlTest.php
index eeba98de52d..f08c99dcaac 100644
--- a/app/code/core/Mage/Webapi/Controller/Router/Route/Webapi.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Notification/BaseurlTest.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Route to Magento web API.
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,18 +21,12 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-class Mage_Webapi_Controller_Router_Route_Webapi extends Mage_Webapi_Controller_Router_RouteAbstract
+class Mage_Adminhtml_Block_Notification_BaseurlTest extends PHPUnit_Framework_TestCase
 {
-    const PARAM_API_TYPE = 'api_type';
-    const API_AREA_NAME = 'api';
-
-    /**
-     * Retrieve API route.
-     *
-     * @return string
-     */
-    public static function getApiRoute()
+    public function testGetConfigUrl()
     {
-        return self::API_AREA_NAME . '/:' . self::PARAM_API_TYPE;
+        /** @var $block Mage_Adminhtml_Block_Notification_Baseurl */
+        $block = Mage::app()->getLayout()->createBlock('Mage_Adminhtml_Block_Notification_Baseurl');
+        $this->assertStringStartsWith('http://localhost/', $block->getConfigUrl());
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Page/HeadTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Page/HeadTest.php
new file mode 100644
index 00000000000..7e87bc7e94c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Page/HeadTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Adminhtml_Block_Page_HeadTest extends PHPUnit_Framework_TestCase
+{
+    public function testConstruct()
+    {
+        $this->assertInstanceOf(
+            'Mage_Adminhtml_Block_Page_Head', Mage::app()->getLayout()->createBlock('Mage_Adminhtml_Block_Page_Head')
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/LabelsTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/LabelsTest.php
new file mode 100644
index 00000000000..36dba811686
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Promo/Quote/Edit/Tab/LabelsTest.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_LabelsTest extends PHPUnit_Framework_TestCase
+{
+    public function testConstruct()
+    {
+        $this->assertInstanceOf(
+            'Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_Labels',
+            Mage::app()->getLayout()->createBlock('Mage_Adminhtml_Block_Promo_Quote_Edit_Tab_Labels')
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Rating/Edit/Tab/FormTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Rating/Edit/Tab/FormTest.php
new file mode 100644
index 00000000000..5dcd7ad218b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Rating/Edit/Tab/FormTest.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Adminhtml_Block_Rating_Edit_Tab_FormTest extends PHPUnit_Framework_TestCase
+{
+    public function testConstruct()
+    {
+        $this->assertInstanceOf(
+            'Mage_Adminhtml_Block_Rating_Edit_Tab_Form',
+            Mage::app()->getLayout()->createBlock('Mage_Adminhtml_Block_Rating_Edit_Tab_Form')
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Sales/Order/Create/Form/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Sales/Order/Create/Form/AbstractTest.php
index a5f14a8427f..783f03bf178 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Sales/Order/Create/Form/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Sales/Order/Create/Form/AbstractTest.php
@@ -49,6 +49,8 @@ class Mage_Adminhtml_Block_Sales_Order_Create_Form_AbstractTest
             Mage::getObjectManager()->get('Mage_Core_Model_Store_Config'),
             Mage::getObjectManager()->get('Mage_Core_Controller_Varien_Front'),
             Mage::getObjectManager()->get('Mage_Core_Model_Factory_Helper'),
+            Mage::getObjectManager()->get('Mage_Core_Model_Dir'),
+            Mage::getObjectManager()->get('Mage_Core_Model_Logger'),
             Mage::getObjectManager()->get('Magento_Filesystem'),
         );
         /** @var $block Mage_Adminhtml_Block_Sales_Order_Create_Form_Abstract */
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Widget/Form/ContainerTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Widget/Form/ContainerTest.php
index a0ae7015c79..221196265c7 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Widget/Form/ContainerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/Block/Widget/Form/ContainerTest.php
@@ -44,9 +44,11 @@ class Mage_Adminhtml_Block_Widget_Form_ContainerTest extends PHPUnit_Framework_T
         'Mage_Core_Model_Store_Config',
         'Mage_Core_Controller_Varien_Front',
         'Mage_Core_Model_Factory_Helper',
+        'Mage_Core_Model_Dir',
+        'Mage_Core_Model_Logger',
         'Magento_Filesystem'
     );
-    
+
     public function testGetFormHtml()
     {
         /** @var $layout Mage_Core_Model_Layout */
@@ -75,7 +77,7 @@ class Mage_Adminhtml_Block_Widget_Form_ContainerTest extends PHPUnit_Framework_T
     {
         $arguments = array();
         foreach ($this->_blockInjections as $injectionClass) {
-            $arguments[] = Mage::getModel($injectionClass);
+            $arguments[] = Mage::getObjectManager()->get($injectionClass);
         }
         return $arguments;
     }
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/CategoryControllerTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/CategoryControllerTest.php
index b7869eef157..08d24895585 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/CategoryControllerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/CategoryControllerTest.php
@@ -81,6 +81,7 @@ class Mage_Adminhtml_Catalog_CategoryControllerTest extends Mage_Backend_Utility
     /**
      * @param array $postData
      * @dataProvider categoryCreatedFromProductCreationPageDataProvider
+     * @magentoDbIsolation enabled
      */
     public function testSaveActionFromProductCreationPage($postData)
     {
@@ -137,7 +138,7 @@ class Mage_Adminhtml_Catalog_CategoryControllerTest extends Mage_Backend_Utility
         $this->getRequest()->setParam('name_part', 'Default');
         $this->dispatch('backend/admin/catalog_category/suggestCategories');
         $this->assertEquals(
-            '[{"id":"2","children":[],"is_active":"1","name":"Default Category"}]',
+            '[{"id":"2","children":[],"is_active":"1","label":"Default Category"}]',
             $this->getResponse()->getBody()
         );
     }
diff --git a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/AttributeControllerTest.php b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/AttributeControllerTest.php
index 7efdbfcaa72..9e13d09d73e 100644
--- a/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/AttributeControllerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Adminhtml/controllers/Catalog/Product/AttributeControllerTest.php
@@ -36,8 +36,8 @@ class Mage_Adminhtml_Catalog_Product_AttributeControllerTest extends Mage_Backen
         $this->getRequest()->setPost($postData);
         $this->dispatch('backend/admin/catalog_product_attribute/save');
         $model = new Mage_Catalog_Model_Resource_Eav_Attribute(
-            new Mage_Core_Model_Event_Manager(),
-            new Mage_Core_Model_Cache()
+            Mage::getModel('Mage_Core_Model_Event_Manager'),
+            Mage::getModel('Mage_Core_Model_Cache')
         );
         $model->load($postData['attribute_id']);
         $this->assertNull($model->getData('apply_to'));
@@ -52,8 +52,8 @@ class Mage_Adminhtml_Catalog_Product_AttributeControllerTest extends Mage_Backen
         $this->getRequest()->setPost($postData);
         $this->dispatch('backend/admin/catalog_product_attribute/save');
         $model = new Mage_Catalog_Model_Resource_Eav_Attribute(
-            new Mage_Core_Model_Event_Manager(),
-            new Mage_Core_Model_Cache()
+            Mage::getModel('Mage_Core_Model_Event_Manager'),
+            Mage::getModel('Mage_Core_Model_Cache')
         );
         $model->load($postData['attribute_id']);
         $this->assertEquals('simple,configurable', $model->getData('apply_to'));
@@ -69,8 +69,8 @@ class Mage_Adminhtml_Catalog_Product_AttributeControllerTest extends Mage_Backen
         $this->getRequest()->setPost($postData);
         $this->dispatch('backend/admin/catalog_product_attribute/save');
         $model = new Mage_Catalog_Model_Resource_Eav_Attribute(
-            new Mage_Core_Model_Event_Manager(),
-            new Mage_Core_Model_Cache()
+            Mage::getModel('Mage_Core_Model_Event_Manager'),
+            Mage::getModel('Mage_Core_Model_Cache')
         );
         $model->load($postData['attribute_id']);
         $this->assertEquals(array('simple', 'configurable'), $model->getApplyTo());
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormStub.php b/dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormStub.php
index 2062847df06..68a59d1bc29 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormStub.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormStub.php
@@ -44,7 +44,6 @@ class Mage_Backend_Block_System_Config_FormStub extends Mage_Backend_Block_Syste
      * Sets stub config data
      *
      * @param array $configData
-     * @return void
      */
     public function setStubConfigData(array $configData = array())
     {
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormTest.php b/dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormTest.php
index 153d70d33b9..597a28347ba 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormTest.php
@@ -129,8 +129,10 @@ class Mage_Backend_Block_System_Config_FormTest extends PHPUnit_Framework_TestCa
      */
     public function initFieldsInheritCheckboxDataProvider()
     {
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            'global_ban_use_cache' => true,
+        ));
         Mage::getConfig()->setCurrentAreaCode('adminhtml');
-        Mage::getConfig()->setOptions(array('global_ban_use_cache' => 1));
 
         $configMock = $this->getMock('Mage_Core_Model_Config', array(), array(), '', false, false);
         $configMock->expects($this->any())->method('getModuleConfigurationFiles')
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/Grid/MassactionTest.php b/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/Grid/MassactionTest.php
index d6591f9808c..11553a173b0 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/Grid/MassactionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/Grid/MassactionTest.php
@@ -26,9 +26,7 @@
  */
 
 /**
- * @magentoAppIsolation enabled
- * @magentoDbIsolation enabled
- * @magentoDataFixture Mage/Backend/Block/_files/theme_registration.php
+ * @magentoDataFixture Mage/Backend/Block/_files/backend_theme.php
  */
 class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_TestCase
 {
@@ -44,6 +42,8 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
 
     protected function setUp()
     {
+        $this->_setFixtureTheme();
+
         $this->_layout = Mage::getModel('Mage_Core_Model_Layout', array('area' => 'adminhtml'));
         $this->_layout->getUpdate()->load('layout_test_grid_handle');
         $this->_layout->generateXml();
@@ -52,6 +52,25 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
         $this->_block = $this->_layout->getBlock('admin.test.grid.massaction');
     }
 
+    /**
+     * Set fixture theme for admin backend area
+     */
+    protected function _setFixtureTheme()
+    {
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_SCOPE_TYPE => 'store',
+            Mage_Core_Model_App::INIT_OPTION_SCOPE_CODE => 'admin',
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES => __DIR__ . '/../../_files/design'
+            ),
+        ));
+
+        Mage::app()->getConfig()->setNode(
+            'adminhtml/' . Mage_Core_Model_Design_Package::XML_PATH_THEME,
+            'test/default'
+        );
+    }
+
     protected function tearDown()
     {
         unset($this->_layout);
@@ -63,7 +82,6 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
      * @covers Mage_Backend_Block_Widget_Grid_Massaction::getCount
      * @covers Mage_Backend_Block_Widget_Grid_Massaction::getItemsJson
      * @covers Mage_Backend_Block_Widget_Grid_Massaction::isAvailable
-     * @magentoConfigFixture adminhtml/design/theme/full_name test/default
      */
     public function testMassactionDefaultValues()
     {
@@ -76,28 +94,22 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
         $this->assertFalse($blockEmpty->isAvailable());
     }
 
-    /**
-     * @magentoConfigFixture adminhtml/design/theme/full_name test/default
-     */
-    public function testJavascript()
+    public function testGetJavaScript()
     {
         $javascript = $this->_block->getJavaScript();
 
         $expectedItemFirst = '#"option_id1":{"label":"Option One",'
-            . '"url":"http:\\\/\\\/localhost\\\/index\.php\\\/key\\\/([\w\d]+)\\\/",'
+            . '"url":"http:\\\/\\\/localhost\\\/index\.php\\\/(?:key\\\/([\w\d]+)\\\/)?",'
             . '"complete":"Test","id":"option_id1"}#';
         $this->assertRegExp($expectedItemFirst, $javascript);
 
         $expectedItemSecond = '#"option_id2":{"label":"Option Two",'
-            . '"url":"http:\\\/\\\/localhost\\\/index\.php\\\/key\\\/([\w\d]+)\\\/",'
+            . '"url":"http:\\\/\\\/localhost\\\/index\.php\\\/(?:key\\\/([\w\d]+)\\\/)?",'
             . '"confirm":"Are you sure\?","id":"option_id2"}#';
         $this->assertRegExp($expectedItemSecond, $javascript);
     }
 
-    /**
-     * @magentoConfigFixture adminhtml/design/theme/full_name test/default
-     */
-    public function testJavascriptWithAddedItem()
+    public function testGetJavaScriptWithAddedItem()
     {
         $input = array(
             'id' => 'option_id3',
@@ -106,31 +118,27 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
             'block_name' => 'admin.test.grid.massaction.option3'
         );
         $expected = '#"option_id3":{"id":"option_id3","label":"Option Three",'
-            . '"url":"http:\\\/\\\/localhost\\\/index\.php\\\/key\\\/([\w\d]+)\\\/",'
+            . '"url":"http:\\\/\\\/localhost\\\/index\.php\\\/(?:key\\\/([\w\d]+)\\\/)?",'
             . '"block_name":"admin.test.grid.massaction.option3"}#';
 
         $this->_block->addItem($input['id'], $input);
         $this->assertRegExp($expected, $this->_block->getJavaScript());
     }
 
-    /**
-     * @magentoConfigFixture adminhtml/design/theme/full_name test/default
-     */
-    public function testItemsCount()
+    public function testGetCount()
     {
-        $this->assertEquals(2, count($this->_block->getItems()));
         $this->assertEquals(2, $this->_block->getCount());
     }
 
     /**
      * @param $itemId
      * @param $expectedItem
-     * @dataProvider itemsDataProvider
-     * @magentoConfigFixture adminhtml/design/theme/full_name test/default
+     * @dataProvider getItemsDataProvider
      */
-    public function testItems($itemId, $expectedItem)
+    public function testGetItems($itemId, $expectedItem)
     {
         $items = $this->_block->getItems();
+        $this->assertCount(2, $items);
         $this->assertArrayHasKey($itemId, $items);
 
         $actualItem = $items[$itemId];
@@ -144,7 +152,7 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
     /**
      * @return array
      */
-    public function itemsDataProvider()
+    public function getItemsDataProvider()
     {
         return array(
             array(
@@ -152,7 +160,7 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
                 array(
                     'id' => 'option_id1',
                     'label' => 'Option One',
-                    'url' => '#http:\/\/localhost\/index\.php\/key\/([\w\d]+)\/#',
+                    'url' => '#http:\/\/localhost\/index\.php\/(?:key\/([\w\d]+)\/)?#',
                     'selected' => false,
                     'blockname' => ''
                 )
@@ -162,7 +170,7 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
                 array(
                     'id' => 'option_id2',
                     'label' => 'Option Two',
-                    'url' => '#http:\/\/localhost\/index\.php\/key\/([\w\d]+)\/#',
+                    'url' => '#http:\/\/localhost\/index\.php\/(?:key\/([\w\d]+)\/)?#',
                     'selected' => false,
                     'blockname' => ''
                 )
@@ -170,9 +178,6 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
         );
     }
 
-    /**
-     * @magentoConfigFixture adminhtml/design/theme/full_name test/default
-     */
     public function testGridContainsMassactionColumn()
     {
         $this->_layout->getBlock('admin.test.grid')->toHtml();
@@ -180,11 +185,11 @@ class Mage_Backend_Block_Widget_Grid_MassactionTest extends PHPUnit_Framework_Te
         $gridMassactionColumn = $this->_layout->getBlock('admin.test.grid')
             ->getColumnSet()
             ->getChildBlock('massaction');
-        $this->assertNotNull($gridMassactionColumn, 'Massaction column is not existed in grid column set');
+        $this->assertNotNull($gridMassactionColumn, 'Massaction column does not exist in the grid column set');
         $this->assertInstanceOf(
             'Mage_Backend_Block_Widget_Grid_Column',
             $gridMassactionColumn,
-            'Massaction column is not instance of Mage_Backend_Block_Widget_Column'
+            'Massaction column is not an instance of Mage_Backend_Block_Widget_Column'
         );
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/GridTest.php b/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/GridTest.php
index 966e1d28ae3..7afde5b2fbc 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/GridTest.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Block/Widget/GridTest.php
@@ -42,36 +42,10 @@ class Mage_Backend_Block_Widget_GridTest extends PHPUnit_Framework_TestCase
      */
     protected $_columnSetMock;
 
-    /**
-     * List of block injection classes
-     *
-     * @var array
-     */
-    protected $_blockInjections = array(
-        'Mage_Core_Controller_Request_Http',
-        'Mage_Core_Model_Layout',
-        'Mage_Core_Model_Event_Manager',
-        'Mage_Backend_Model_Url',
-        'Mage_Core_Model_Translate',
-        'Mage_Core_Model_Cache',
-        'Mage_Core_Model_Design_Package',
-        'Mage_Core_Model_Session',
-        'Mage_Core_Model_Store_Config',
-        'Mage_Core_Controller_Varien_Front',
-        'Mage_Core_Model_Factory_Helper',
-        'Magento_Filesystem',
-        'Mage_Backend_Helper_Data',
-        'Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory',
-        'Mage_Backend_Model_Widget_Grid_SubTotals',
-        'Mage_Backend_Model_Widget_Grid_Totals',
-    );
-
     protected function setUp()
     {
         $this->_layoutMock = $this->getMock('Mage_Core_Model_Layout', array(), array(), '', false);
-        $this->_columnSetMock = $this->getMock(
-            'Mage_Backend_Block_Widget_Grid_ColumnSet', array(), $this->_prepareConstructorArguments()
-        );
+        $this->_columnSetMock = $this->_getColumnSetMock();
 
         $returnValueMap = array(
             array('grid', 'grid.columnSet', 'grid.columnSet'),
@@ -92,18 +66,40 @@ class Mage_Backend_Block_Widget_GridTest extends PHPUnit_Framework_TestCase
         $this->_block->setNameInLayout('grid');
     }
 
+    protected function tearDown()
+    {
+        $this->_block = null;
+        $this->_layoutMock = null;
+        $this->_columnSetMock = null;
+    }
+
     /**
-     * List of block constructor arguments
+     * Retrieve the mocked column set block instance
      *
-     * @return array
+     * @return Mage_Backend_Block_Widget_Grid_ColumnSet|PHPUnit_Framework_MockObject_MockObject
      */
-    protected function _prepareConstructorArguments()
+    protected function _getColumnSetMock()
     {
-        $arguments = array();
-        foreach ($this->_blockInjections as $injectionClass) {
-            $arguments[] = Mage::getModel($injectionClass);
-        }
-        return $arguments;
+        return $this->getMock('Mage_Backend_Block_Widget_Grid_ColumnSet', array(), array(
+            Mage::getModel('Mage_Core_Controller_Request_Http'),
+            Mage::getModel('Mage_Core_Model_Layout'),
+            Mage::getModel('Mage_Core_Model_Event_Manager'),
+            Mage::getModel('Mage_Backend_Model_Url'),
+            Mage::getModel('Mage_Core_Model_Translate'),
+            Mage::getModel('Mage_Core_Model_Cache'),
+            Mage::getModel('Mage_Core_Model_Design_Package'),
+            Mage::getModel('Mage_Core_Model_Session'),
+            Mage::getModel('Mage_Core_Model_Store_Config'),
+            Mage::getModel('Mage_Core_Controller_Varien_Front'),
+            Mage::getModel('Mage_Core_Model_Factory_Helper'),
+            new Mage_Core_Model_Dir(__DIR__),
+            Mage::getModel('Mage_Core_Model_Logger'),
+            new Magento_Filesystem(new Magento_Filesystem_Adapter_Local),
+            Mage::getModel('Mage_Backend_Helper_Data'),
+            Mage::getModel('Mage_Backend_Model_Widget_Grid_Row_UrlGeneratorFactory'),
+            Mage::getModel('Mage_Backend_Model_Widget_Grid_SubTotals'),
+            Mage::getModel('Mage_Backend_Model_Widget_Grid_Totals'),
+        ));
     }
 
     public function testToHtmlPreparesColumns()
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Block/_files/backend_theme.php b/dev/tests/integration/testsuite/Mage/Backend/Block/_files/backend_theme.php
new file mode 100644
index 00000000000..12d81526658
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Backend/Block/_files/backend_theme.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/** @var $registration Mage_Core_Model_Theme_Registration */
+$registration = Mage::getModel('Mage_Core_Model_Theme_Registration');
+$registration->register(
+    __DIR__ . DIRECTORY_SEPARATOR . 'design',
+    implode(DIRECTORY_SEPARATOR, array('*', '*', '*', 'theme.xml'))
+);
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Model/Config/Backend/BaseurlTest.php b/dev/tests/integration/testsuite/Mage/Backend/Model/Config/Backend/BaseurlTest.php
new file mode 100644
index 00000000000..400449e2146
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Backend/Model/Config/Backend/BaseurlTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Backend_Model_Config_Backend_BaseurlTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @param string $path
+     * @param string $value
+     * @magentoDbIsolation enabled
+     * @dataProvider validationDataProvider
+     */
+    public function testValidation($path, $value)
+    {
+        /** @var $model Mage_Backend_Model_Config_Backend_Baseurl */
+        $model = Mage::getModel('Mage_Backend_Model_Config_Backend_Baseurl');
+        $model->setPath($path)->setValue($value)->save();
+        $this->assertNotEmpty((int)$model->getId());
+    }
+
+    /**
+     * @return array
+     */
+    public function validationDataProvider()
+    {
+        $basePlaceholder = '{{base_url}}';
+        $unsecurePlaceholder = '{{unsecure_base_url}}';
+        $unsecureSuffix = '{{unsecure_base_url}}test/';
+        $securePlaceholder = '{{secure_base_url}}';
+        $secureSuffix = '{{secure_base_url}}test/';
+
+        return array(
+            // any fully qualified URLs regardless of path
+            array('any/path', 'http://example.com/'),
+            array('any/path', 'http://example.com/uri/'),
+
+            // unsecure base URLs
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL, $basePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LINK_URL, $unsecurePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LINK_URL, $unsecureSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_MEDIA_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_MEDIA_URL, $unsecurePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_MEDIA_URL, $unsecureSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LIB_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LIB_URL, $unsecurePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LIB_URL, $unsecureSuffix),
+
+            // secure base URLs
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL, $basePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LINK_URL, $securePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LINK_URL, $secureSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL, $securePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL, $secureSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL, $securePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL, $secureSuffix),
+
+            // secure base URLs - in addition can use unsecure
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL, $unsecurePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LINK_URL, $unsecurePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LINK_URL, $unsecureSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL, $unsecurePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL, $unsecureSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL, $unsecurePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL, $unsecureSuffix),
+        );
+    }
+
+    /**
+     * @param string $path
+     * @param string $value
+     * @magentoDbIsolation enabled
+     * @expectedException Mage_Core_Exception
+     * @dataProvider validationExceptionDataProvider
+     */
+    public function testValidationException($path, $value)
+    {
+        /** @var $model Mage_Backend_Model_Config_Backend_Baseurl */
+        $model = Mage::getModel('Mage_Backend_Model_Config_Backend_Baseurl');
+        $model->setPath($path)->setValue($value)->save();
+    }
+
+    /**
+     * @return array
+     */
+    public function validationExceptionDataProvider()
+    {
+        $baseSuffix = '{{base_url}}test/';
+        $unsecurePlaceholder = '{{unsecure_base_url}}';
+        $unsecureSuffix = '{{unsecure_base_url}}test/';
+        $unsecureWrongSuffix = '{{unsecure_base_url}}test';
+        $securePlaceholder = '{{secure_base_url}}';
+        $secureSuffix = '{{secure_base_url}}test/';
+        $secureWrongSuffix = '{{secure_base_url}}test';
+
+        return array(
+            // not a fully qualified URLs regardless path
+            array('', 'not a valid URL'),
+            array('', 'example.com'),
+            array('', 'http://example.com'),
+            array('', 'http://example.com/uri'),
+
+            // unsecure base URLs
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL, ''), // breaks cache
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL, $baseSuffix), // creates redirect loops
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL, $unsecureSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_URL, $unsecurePlaceholder), // creates endless recursion
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LINK_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LINK_URL, $baseSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LINK_URL, $unsecureWrongSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_MEDIA_URL, $unsecureWrongSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_UNSECURE_BASE_LIB_URL, $unsecureWrongSuffix),
+
+            // secure base URLs
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL, $baseSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL, $secureSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_URL, $securePlaceholder),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LINK_URL, ''),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LINK_URL, $baseSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LINK_URL, $secureWrongSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_MEDIA_URL, $secureWrongSuffix),
+            array(Mage_Core_Model_Store::XML_PATH_SECURE_BASE_LIB_URL, $secureWrongSuffix),
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Backend/Utility/Controller.php b/dev/tests/integration/testsuite/Mage/Backend/Utility/Controller.php
index b0191c39f97..e9faf4626c7 100644
--- a/dev/tests/integration/testsuite/Mage/Backend/Utility/Controller.php
+++ b/dev/tests/integration/testsuite/Mage/Backend/Utility/Controller.php
@@ -46,7 +46,7 @@ class Mage_Backend_Utility_Controller extends Magento_Test_TestCase_ControllerAb
     {
         parent::setUp();
 
-        Mage::app()->loadDiConfiguration(Mage_Core_Model_App_Area::AREA_ADMINHTML);
+        Mage::app()->getConfig()->loadDiConfiguration(Mage_Core_Model_App_Area::AREA_ADMINHTML);
         Mage::getSingleton('Mage_Backend_Model_Url')->turnOffSecretKey();
 
         $this->_auth = Mage::getModel('Mage_Backend_Model_Auth');
diff --git a/dev/tests/integration/testsuite/Mage/Captcha/Model/ObserverTest.php b/dev/tests/integration/testsuite/Mage/Captcha/Model/ObserverTest.php
index 3e0dfd76b43..5ab09150d0c 100644
--- a/dev/tests/integration/testsuite/Mage/Captcha/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Mage/Captcha/Model/ObserverTest.php
@@ -37,7 +37,9 @@ class Mage_Captcha_Model_ObserverTest extends Magento_Test_TestCase_ControllerAb
      */
     public function testBackendLoginActionWithInvalidCaptchaReturnsError()
     {
-        $this->markTestIncomplete('MAGETWO-1662');
+        if (Magento_Test_Bootstrap::getInstance()->getDbVendorName() != 'mysql') {
+            $this->markTestIncomplete('MAGETWO-1662');
+        }
         Mage::getSingleton('Mage_Backend_Model_Url')->turnOffSecretKey();
 
         $post = array(
@@ -50,21 +52,23 @@ class Mage_Captcha_Model_ObserverTest extends Magento_Test_TestCase_ControllerAb
             )
         );
         $this->getRequest()->setPost($post);
-        $this->dispatch('/admin');
+        $this->dispatch('backend/admin');
         $this->assertContains(Mage::helper('Mage_Captcha')->__('Incorrect CAPTCHA.'), $this->getResponse()->getBody());
     }
 
     /**
-     * @magentoConfigFixture current_store admin/captcha/enable 1
-     * @magentoConfigFixture current_store admin/captcha/forms backend_login
-     * @magentoConfigFixture current_store admin/captcha/mode after_fail
-     * @magentoConfigFixture current_store admin/captcha/failed_attempts_login 1
+     * @magentoConfigFixture admin_store admin/captcha/enable 1
+     * @magentoConfigFixture admin_store admin/captcha/forms backend_login
+     * @magentoConfigFixture admin_store admin/captcha/mode after_fail
+     * @magentoConfigFixture admin_store admin/captcha/failed_attempts_login 1
      * @magentoDbIsolation enabled
      * @magentoAppIsolation enabled
      */
     public function testCaptchaIsRequiredAfterFailedLoginAttempts()
     {
-        $this->markTestIncomplete('MAGETWO-1662');
+        if (Magento_Test_Bootstrap::getInstance()->getDbVendorName() != 'mysql') {
+            $this->markTestIncomplete('MAGETWO-1662');
+        }
         Mage::app()->setCurrentStore(0);
         $captchaModel = Mage::helper('Mage_Captcha_Helper_Data')->getCaptcha('backend_login');
 
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Api/V2Test.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Api/V2Test.php
new file mode 100644
index 00000000000..8907b50e2cc
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Api/V2Test.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.
+ *
+ * @category    Magento
+ * @package     Magento_Catalog
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 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 Mage_Catalog_Model_Category_Api_V2.
+ */
+class Mage_Catalog_Model_Category_Api_V2Test extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Catalog_Model_Category_Api_V2
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $this->_model = Mage::getModel('Mage_Catalog_Model_Category_Api_V2');
+        Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public function testCRUD()
+    {
+        // @codingStandardsIgnoreStart
+        $category = new stdClass();
+        $category->name                 = 'test category';
+        $category->available_sort_by    = 'name';
+        $category->default_sort_by      = 'name';
+        $category->is_active            = 1;
+        $category->include_in_menu      = 1;
+        // @codingStandardsIgnoreEnd
+
+        $categoryId = $this->_model->create(1, $category);
+        $this->assertNotEmpty($categoryId);
+        $data = $this->_model->info($categoryId);
+        $this->assertNotEmpty($data);
+        $this->assertEquals($category->name, $data['name']);
+        // @codingStandardsIgnoreStart
+        $this->assertEquals($category->default_sort_by, $data['default_sort_by']);
+        $this->assertEquals($category->is_active, $data['is_active']);
+        // @codingStandardsIgnoreEnd
+
+        $category->name = 'new name';
+        $this->_model->update($categoryId, $category);
+        $data = $this->_model->info($categoryId);
+        $this->assertNotEmpty($data);
+        $this->assertEquals($category->name, $data['name']);
+
+        $this->assertTrue($this->_model->delete($categoryId));
+    }
+
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/ApiTest.php
new file mode 100644
index 00000000000..6de32d1bfb7
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/ApiTest.php
@@ -0,0 +1,502 @@
+<?php
+/**
+ * Test class for Mage_Catalog_Model_Category_Api.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Catalog/_files/categories.php
+ * @magentoDbIsolation enabled
+ */
+class Mage_Catalog_Model_Category_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Catalog_Model_Category_Api
+     */
+    protected $_model;
+
+    /**
+     * Fixture data
+     *
+     * @var array
+     */
+    protected $_fixtureData;
+
+    protected function setUp()
+    {
+        $this->_model = Mage::getModel('Mage_Catalog_Model_Category_Api');
+        Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public function testLevel()
+    {
+        $default = $this->_model->level();
+        $this->assertNotEmpty($default);
+
+        $forWebsite = $this->_model->level(1);
+        $this->assertNotEmpty($forWebsite);
+
+        $this->assertEquals($default, $forWebsite);
+        $this->assertEquals(
+            $default,
+            array(
+                array(
+                    'category_id'   => 2,
+                    'parent_id'     => 1,
+                    'name'          => 'Default Category',
+                    'is_active'     => 1,
+                    'position'      => 1,
+                    'level'         => 1
+                )
+            )
+        );
+
+    }
+
+    public function testTree()
+    {
+        $tree = $this->_model->tree();
+        $this->assertNotEmpty($tree);
+        $this->assertArrayHasKey('category_id', $tree);
+        $this->assertArrayHasKey('name', $tree);
+        $this->assertEquals(Mage_Catalog_Model_Category::TREE_ROOT_ID, $tree['category_id']);
+    }
+
+    public function testCRUD()
+    {
+        $categoryId = $this->_model->create(1, array(
+            'name'              => 'test category',
+            'available_sort_by' => 'name',
+            'default_sort_by'   => 'name',
+            'is_active'         => 1,
+            'include_in_menu'   => 1
+        ));
+        $this->assertNotEmpty($categoryId);
+        $data = $this->_model->info($categoryId);
+        $this->assertNotEmpty($data);
+        $this->assertEquals('test category', $data['name']);
+
+        $this->_model->update($categoryId, array(
+            'name'              => 'new name',
+            'available_sort_by' => 'name',
+            'default_sort_by'   => 'name',
+            'is_active'         => 1,
+            'include_in_menu'   => 1
+        ));
+        $data = $this->_model->info($categoryId);
+        $this->assertEquals('new name', $data['name']);
+
+        $this->_model->delete($categoryId);
+    }
+
+    public function testMove()
+    {
+        $this->assertTrue($this->_model->move(7, 6, 0));
+    }
+
+    public function testAssignedProducts()
+    {
+        $this->assertEmpty($this->_model->assignedProducts(1));
+        $this->assertEquals(
+            array(array(
+                'product_id' => 1,
+                'type' => 'simple',
+                'set' => 4,
+                'sku' => 'simple',
+                'position' => '1',
+            )),
+            $this->_model->assignedProducts(3)
+        );
+    }
+
+    /**
+     * @param int $categoryId
+     * @param int|string $productId
+     * @param string|null $identifierType
+     * @dataProvider assignProductDataProvider
+     */
+    public function testAssignProduct($categoryId, $productId, $identifierType = null)
+    {
+        $this->assertEmpty($this->_model->assignedProducts($categoryId));
+        $this->assertTrue($this->_model->assignProduct($categoryId, $productId, null, $identifierType));
+        $this->assertNotEmpty($this->_model->assignedProducts($categoryId));
+    }
+
+    public function assignProductDataProvider()
+    {
+        return array(
+            'product id'           => array(1, 1),
+            'product sku implicit' => array(6, 'simple'),
+            'product sku explicit' => array(7, 12345, 'sku'),
+        );
+    }
+
+    /**
+     * @depends testAssignProduct
+     */
+    public function testUpdateProduct()
+    {
+        $this->assertTrue($this->_model->updateProduct(6, 1, 2));
+        $this->assertEquals(
+            array(array(
+                'product_id' => 1,
+                'type' => 'simple',
+                'set' => 4,
+                'sku' => 'simple',
+                'position' => '2',
+            )),
+            $this->_model->assignedProducts(6)
+        );
+    }
+
+    /**
+     * @depends testAssignProduct
+     */
+    public function testRemoveProduct()
+    {
+        $this->assertNotEmpty($this->_model->assignedProducts(6));
+        $this->assertTrue($this->_model->removeProduct(6, 1));
+        $this->assertEmpty($this->_model->assignedProducts(6));
+    }
+
+    /**
+     * Get formatter design date
+     *
+     * @param string $date
+     * @return string
+     */
+    protected function _formatActiveDesignDate($date)
+    {
+        list($month, $day, $year) = explode('/', $date);
+        return "$year-$month-$day 00:00:00";
+    }
+
+    /**
+     * Get fixture data
+     *
+     * @return array
+     */
+    protected function _getFixtureData()
+    {
+        if (null === $this->_fixtureData) {
+            $this->_fixtureData = require dirname(__FILE__) . '/_files/category_data.php';
+        }
+        return $this->_fixtureData;
+    }
+
+    /**
+     * Test category CRUD
+     */
+    public function testCrudViaHandler()
+    {
+        $categoryFixture = $this->_getFixtureData();
+
+        $categoryId = $this->_testCreate($categoryFixture);
+        $this->_testUpdate($categoryId, $categoryFixture);
+        $this->_testRead($categoryId, $categoryFixture);
+        $this->_testDelete($categoryId);
+    }
+
+    /**
+     * Test category create.
+     *
+     * @param array $categoryFixture
+     * @return int
+     */
+    protected function _testCreate($categoryFixture)
+    {
+        $categoryId = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogCategoryCreate',
+            array(
+                $categoryFixture['create']['parentId'],
+                (object)$categoryFixture['create']['categoryData'],
+                $categoryFixture['create']['store']
+            )
+        );
+
+        $this->assertEquals(
+            $categoryId,
+            (int)$categoryId,
+            'Result of a create method is not an integer.'
+        );
+
+        $category = Mage::getModel('Mage_Catalog_Model_Category');
+        $category->load($categoryId);
+
+        //check created data
+        $this->assertEquals(
+            $categoryId,
+            $category->getId(),
+            'Category ID is not same like from API result.'
+        );
+
+        $this->assertEquals(
+            $category['custom_design_from'],
+            $this->_formatActiveDesignDate(
+                $categoryFixture['create']['categoryData']->custom_design_from
+            ),
+            'Category active design date is not the same like sent to API on create.'
+        );
+
+        $this->assertEquals(
+            $category['custom_design_to'],
+            $this->_formatActiveDesignDate(
+                $categoryFixture['create']['categoryData']->custom_design_to
+            ),
+            'Category active design date is not the same like sent to API on create.'
+        );
+
+        $this->assertNotEmpty(
+            $category['position'],
+            'Category position is empty.'
+        );
+        $this->assertFalse(
+            array_key_exists('custom_design_apply', $category->getData()),
+            'Category data item "custom_design_apply" is deprecated.'
+        );
+
+        foreach ($categoryFixture['create']['categoryData'] as $name => $value) {
+            if (in_array($name, $categoryFixture['create_skip_to_check'])) {
+                continue;
+            }
+            $this->assertEquals(
+                $value,
+                $category[$name],
+                sprintf(
+                    'Category "%s" is "%s" and not the same like sent to create "%s".',
+                    $name,
+                    $category[$name],
+                    $value
+                )
+            );
+        }
+
+        return $categoryId;
+    }
+
+    /**
+     * Test category read
+     *
+     * @param int $categoryId
+     * @param array $categoryFixture
+     */
+    protected function _testRead($categoryId, $categoryFixture)
+    {
+        $categoryRead = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogCategoryInfo',
+            array('categoryId' => $categoryId, $categoryFixture['update']['storeView'])
+        );
+
+        $this->assertEquals(
+            $categoryRead['custom_design_from'],
+            $this->_formatActiveDesignDate(
+                $categoryFixture['update']['categoryData']->custom_design_from
+            ),
+            'Category active design date is not the same like sent to API on update.'
+        );
+
+        $this->assertFalse(
+            array_key_exists('custom_design_apply', $categoryRead),
+            'Category data item "custom_design_apply" is deprecated.'
+        );
+
+        foreach ($categoryFixture['update']['categoryData'] as $name => $value) {
+            if (in_array($name, $categoryFixture['update_skip_to_check'])) {
+                continue;
+            }
+            $this->assertEquals(
+                $value,
+                $categoryRead[$name],
+                sprintf('Category data with name "%s" is not the same like sent to update.', $name)
+            );
+        }
+    }
+
+    /**
+     * Test category update
+     *
+     * @param int $categoryId
+     * @param array $categoryFixture
+     */
+    protected function _testUpdate($categoryId, $categoryFixture)
+    {
+        $categoryFixture['update']['categoryId'] = $categoryId;
+        $resultUpdated = Magento_Test_Helper_Api::call($this, 'catalogCategoryUpdate', $categoryFixture['update']);
+        $this->assertTrue($resultUpdated);
+
+        $category = Mage::getModel('Mage_Catalog_Model_Category');
+        $category->load($categoryId);
+
+        //check updated data
+        $this->assertEquals(
+            $category['custom_design_from'],
+            $this->_formatActiveDesignDate(
+                $categoryFixture['update']['categoryData']->custom_design_from
+            ),
+            'Category active design date is not the same like sent to API on update.'
+        );
+
+        foreach ($categoryFixture['update']['categoryData'] as $name => $value) {
+            if (in_array($name, $categoryFixture['update_skip_to_check'])) {
+                continue;
+            }
+            $this->assertEquals(
+                $value,
+                $category[$name],
+                sprintf('Category data with name "%s" is not the same like sent to update.', $name)
+            );
+        }
+    }
+
+    /**
+     * Test category delete
+     *
+     * @param int $categoryId
+     */
+    protected function _testDelete($categoryId)
+    {
+        $categoryDelete = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogCategoryDelete',
+            array('categoryId' => $categoryId)
+        );
+        $this->assertTrue($categoryDelete);
+
+        $category = Mage::getModel('Mage_Catalog_Model_Category');
+        $category->load($categoryId);
+        $this->assertEmpty($category->getId());
+    }
+
+    /**
+     * Test category bad request
+     *
+     * Test fault requests and vulnerability requests
+     */
+    public function testBadRequestViaHandler()
+    {
+        $categoryFixture = $this->_getFixtureData();
+        $params = $categoryFixture['create'];
+
+        /**
+         * Test vulnerability SQL injection in is_active
+         */
+        $params['categoryData']->is_active = $categoryFixture['vulnerability']['categoryData']->is_active;
+
+        $categoryId = Magento_Test_Helper_Api::call($this, 'catalogCategoryCreate', $params);
+        $this->assertEquals(
+            $categoryId,
+            (int)$categoryId,
+            'Category cannot created with vulnerability in is_active field'
+        );
+
+        $category = Mage::getModel('Mage_Catalog_Model_Category');
+        $category->load($categoryId);
+
+        $this->assertEquals(
+            $category['is_active'],
+            (int)$categoryFixture['vulnerability']['categoryData']->is_active
+        );
+
+        /**
+         * Test update with empty category ID
+         */
+        $params = $categoryFixture['update'];
+        $params['categoryId'] = 9999;
+        try {
+            $result = Magento_Test_Helper_Api::call($this, 'catalogCategoryUpdate', $params);
+        } catch (SoapFault $e) {
+            //make result like in response
+            $result = array(
+                'faultcode' => $e->faultcode,
+                'faultstring' => $e->faultstring
+            );
+        }
+
+        $category->load($categoryId);
+        //name must has old value
+        $this->assertEquals(
+            $category['name'],
+            $categoryFixture['create']['categoryData']->name,
+            'Category updated with empty ID.'
+        );
+        //"102" is code error when category is not found on update
+        $this->assertInternalType('array', $result);
+        $this->assertEquals(102, $result['faultcode'], 'Fault code is not right.');
+
+        /**
+         * Test vulnerability with helper usage in custom layout update
+         */
+        $params['categoryId'] = $categoryId;
+        $params['categoryData']->custom_layout_update =
+            $categoryFixture['vulnerability']['categoryData']->custom_layout_update;
+        try {
+            $result = Magento_Test_Helper_Api::call($this, 'catalogCategoryUpdate', $params);
+        } catch (SoapFault $e) {
+            //make result like in response
+            $result = array(
+                'faultcode' => $e->faultcode,
+                'faultstring' => $e->faultstring
+            );
+        }
+        $category->load($categoryId);
+
+        //"103" is code error when data validation is not passed
+        $this->assertInternalType('array', $result);
+        $this->assertEquals(103, $result['faultcode'], 'Fault code is not right.');
+
+    }
+
+    /**
+     * Test delete root category
+     */
+    public function testRootCategoryDeleteViaHandler()
+    {
+        try {
+            $result = Magento_Test_Helper_Api::call(
+                $this,
+                'catalogCategoryDelete',
+                array('categoryId' => Mage_Catalog_Model_Category::TREE_ROOT_ID)
+            );
+        } catch (SoapFault $e) {
+            $result = array(
+                'faultcode' => $e->faultcode,
+                'faultstring' => $e->faultstring
+            );
+        }
+
+        $this->assertInternalType('array', $result);
+        $this->assertEquals(105, $result['faultcode'], 'Fault code is not right.');
+        $this->assertEquals(
+            'Cannot remove the system category.',
+            $result['faultstring'],
+            'Exception message is not right.'
+        );
+
+        $category = Mage::getModel('Mage_Catalog_Model_Category');
+        $this->assertNotNull($category->load(Mage_Catalog_Model_Category::TREE_ROOT_ID)->getId());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Attribute/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Attribute/ApiTest.php
new file mode 100644
index 00000000000..786e21ab45f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/Attribute/ApiTest.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.
+ *
+ * @category    Magento
+ * @package     Magento_Catalog
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 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 Mage_Catalog_Model_Category_Attribute_Api.
+ */
+class Mage_Catalog_Model_Category_Attribute_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Catalog_Model_Category_Attribute_Api
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $this->_model = Mage::getModel('Mage_Catalog_Model_Category_Attribute_Api');
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public function testItems()
+    {
+        $attributes = $this->_model->items();
+        $this->assertNotEmpty($attributes);
+        $attribute = array_shift($attributes);
+        $this->assertContains('attribute_id', array_keys($attribute));
+        $this->assertContains('code', array_keys($attribute));
+    }
+
+    /**
+     * Internal assert that validate options structure
+     *
+     * @param array $options
+     */
+    protected function _assertOptionsStructure(array $options)
+    {
+        $first = current($options);
+        $this->assertArrayHasKey('value', $first);
+        $this->assertArrayHasKey('label', $first);
+    }
+
+    public function testLayoutOptions()
+    {
+        $options = $this->_model->options('page_layout');
+        $this->assertNotEmpty($options);
+        $this->_assertOptionsStructure($options);
+    }
+
+    public function testModeOptions()
+    {
+        $options = $this->_model->options('display_mode');
+        $this->assertNotEmpty($options);
+        $this->_assertOptionsStructure($options);
+    }
+
+    public function testPageOptions()
+    {
+        $options = $this->_model->options('landing_page');
+        $this->assertNotEmpty($options);
+        $this->_assertOptionsStructure($options);
+    }
+
+    public function testSortByOptions()
+    {
+        $options = $this->_model->options('available_sort_by');
+        $this->assertNotEmpty($options);
+        $this->_assertOptionsStructure($options);
+    }
+
+    /**
+     * @expectedException Mage_Api_Exception
+     */
+    public function testFault()
+    {
+        $this->_model->options('not_exists');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/_files/category_data.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/_files/category_data.php
new file mode 100644
index 00000000000..a9c6f18f57f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Category/_files/category_data.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/**
+ * Api data
+ *
+ * @return array
+ */
+return array(
+    'create' => array(
+        'parentId' => 2,
+        'categoryData' => (object)array(
+            'name' => 'Category Test Created ' . uniqid(),
+            'is_active' => 1,
+            'is_anchor' => 1,
+            'landing_page' => 1, //ID of CMS block
+            'position' => 100,
+            'description' => 'some description',
+            'default_sort_by' => 'name',
+            'available_sort_by' => array('name'),
+            'display_mode' => Mage_Catalog_Model_Category::DM_PRODUCT,
+            'include_in_menu' => 1,
+            'page_layout' => 'one_column',
+            'custom_design' => 'default/default',
+            'custom_design_apply' => 'someValue', //deprecated attribute, should be empty
+            'custom_design_from' => '11/16/2011', //date of start use design
+            'custom_design_to' => '11/21/2011', //date of finish use design
+            'custom_layout_update' => '<block type="core/text_list" name="content" output="toHtml"/>',
+            'meta_description' => 'Meta description',
+            'meta_keywords' => 'Meta keywords',
+            'meta_title' => 'Meta title',
+            'url_key' => 'url-key',
+        ),
+        'store' => '0',
+    ),
+    'update' => array(
+        'categoryId' => null,
+        'categoryData' => (object)array(
+            'name' => 'Category Test updated ' . uniqid(),
+            'is_active' => 0,
+            'is_anchor' => 0,
+            'position' => 200,
+            'description' => 'some description Update',
+            'default_sort_by' => 'position',
+            'available_sort_by' => array('position', 'name'),
+            'display_mode' => Mage_Catalog_Model_Category::DM_MIXED,
+            'landing_page' => 2, //ID of static block
+            'include_in_menu' => 0,
+            'page_layout' => 'one_column',
+            'custom_design' => 'base/default',
+            'custom_design_apply' => 'someValueUpdate', //deprecated attribute, should be empty
+            'custom_design_from' => '11/21/2011', //date of start use design
+            'custom_design_to' => '', //date of finish use design
+            'custom_layout_update' => '<block type="core/text_list" name="content" output="toHtml">
+                <block type="core/text_list" name="content" output="toHtml"/>
+            </block>',
+            'meta_description' => 'Meta description update',
+            'meta_keywords' => 'Meta keywords update',
+            'meta_title' => 'Meta title update',
+            'url_key' => 'url-key-update',
+        ),
+        'store' => '1',
+    ),
+    //skip test keys list.
+    'create_skip_to_check' => array('custom_design_apply', 'custom_design_from', 'custom_design_to', 'position'),
+    'update_skip_to_check' => array('custom_design_apply', 'custom_design_from', 'available_sort_by'),
+    'vulnerability' => array(
+        'categoryData' => (object)array(
+            'is_active' => '8-1',
+            'custom_layout_update' => '<block type="core/text_list" name="contentDdd" output="toHtml">
+                        <block type="core/text_tag_debug" name="test111">
+                            <action method="setValue">
+                                <arg helper="core/data/mergeFiles">
+                                    <src><file>app/etc/local.xml</file></src>
+                                    <trg>tested11.php</trg>
+                                    <must>true</must>
+                                </arg>
+                            </action>
+                        </block>
+                    </block>'
+        )
+    )
+);
+
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmAdvancedTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmAdvancedTest.php
index 356f3e4d4ee..d3cd274b353 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmAdvancedTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Layer/Filter/Price/AlgorithmAdvancedTest.php
@@ -53,7 +53,6 @@ class Mage_Catalog_Model_Layer_Filter_Price_AlgorithmAdvancedTest extends PHPUni
      * Prepare price filter model
      *
      * @param Magento_Test_Request|null $request
-     * @return void
      */
     protected function _prepareFilter($request = null)
     {
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Attribute/TierPriceTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Attribute/TierPriceTest.php
new file mode 100644
index 00000000000..e2c450e66f4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Attribute/TierPriceTest.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Product tier price attribute API test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDbIsolation enabled
+ */
+class Mage_Catalog_Model_Product_Api_Attribute_TierPriceTest extends PHPUnit_Framework_TestCase
+{
+    /** @var Mage_Catalog_Model_Product */
+    protected $_product;
+
+    /**
+     * Set up product fixture
+     */
+    protected function setUp()
+    {
+        $productData = require realpath(dirname(__FILE__) . '/../_files/ProductData.php');
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+
+        $product->setData($productData['create_full_fledged']);
+        $product->save();
+
+        $this->_product = $product;
+
+        parent::setUp();
+    }
+
+    /**
+     * Test product tier price attribute update
+     */
+    public function testUpdate()
+    {
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeTierPriceUpdate',
+            array(
+                'productId' => $this->_product->getId(),
+                'tierPrices' => array(
+                    (object)array(
+                        'customer_group_id' => Mage_Customer_Model_Group::CUST_GROUP_ALL,
+                        'qty' => 3,
+                        'price' => 0.88,
+                    ),
+                    (object)array(
+                        'customer_group_id' => Mage_Customer_Model_Group::CUST_GROUP_ALL,
+                        'qty' => 5,
+                        'price' => 0.77,
+                    )
+                ),
+            )
+        );
+
+        $this->assertTrue((bool)$result, 'Product tier price attribute update API failed');
+        // Reload product to check tier prices were applied
+        $this->_product->load($this->_product->getId());
+        $this->assertEquals(
+            $this->_product->getTierPrice(3),
+            0.88,
+            'Product tier price (3) attribute update was not applied'
+        );
+        $this->assertEquals(
+            $this->_product->getTierPrice(5),
+            0.77,
+            'Product tier price (5) attribute update was not applied'
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/AttributeSetCRUDTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/AttributeSetCRUDTest.php
new file mode 100644
index 00000000000..fefe0d38dcb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/AttributeSetCRUDTest.php
@@ -0,0 +1,235 @@
+<?php
+/**
+ * Product attribute set API model test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Catalog_Model_Product_Api_AttributeSetCRUDTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Remove attribute set
+     *
+     * @param int $attrSetId
+     */
+    protected function _removeAttrSet($attrSetId)
+    {
+        /** @var $attrSet Mage_Eav_Model_Entity_Attribute_Set */
+        $attrSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set');
+
+        $attrSet->setId($attrSetId);
+        $attrSet->delete();
+    }
+
+    /**
+     * Remove attributes
+     *
+     * @param array $attrIds
+     */
+    protected function _removeAttributes($attrIds)
+    {
+        /** @var $attr Mage_Eav_Model_Entity_Attribute */
+        $attr = Mage::getModel('Mage_Eav_Model_Entity_Attribute');
+
+        if (!is_array($attrIds)) {
+            $attrIds = array($attrIds);
+        }
+        foreach ($attrIds as $attrId) {
+            $attr->setId($attrId);
+            $attr->delete();
+        }
+    }
+
+    /**
+     * Test Attribute set CRUD
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testAttributeSetCRUD()
+    {
+        $attributeSetFixture = simplexml_load_file(dirname(__FILE__) . '/_files/_data/xml/AttributeSet.xml');
+        $data = Magento_Test_Helper_Api::simpleXmlToArray($attributeSetFixture->create);
+        $data['attributeSetName'] = $data['attributeSetName'] . ' ' . mt_rand(1000, 9999);
+
+        // create test
+        $createdAttrSetId = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeSetCreate',
+            array($data['attributeSetName'], $data['skeletonSetId'])
+        );
+        $this->assertGreaterThan(0, $createdAttrSetId);
+
+        // Duplicate name exception test
+        try {
+            Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductAttributeSetCreate',
+                array($data['attributeSetName'], $data['skeletonSetId'])
+            );
+            $this->fail("Didn't receive exception!");
+        } catch (Exception $e) {
+        }
+
+        // items list test
+        $attrSetList = Magento_Test_Helper_Api::call($this, 'catalogProductAttributeSetList');
+        $completeFlag = false;
+        foreach ($attrSetList as $attrSet) {
+            if ($attrSet['set_id'] == $createdAttrSetId) {
+                $this->assertEquals($data['attributeSetName'], $attrSet['name']);
+                $completeFlag = true;
+                break;
+            }
+        }
+        $this->assertTrue($completeFlag, "Can't find added attribute set in list");
+
+        // Remove AttrSet with related products
+        $productData = Magento_Test_Helper_Api::simpleXmlToArray($attributeSetFixture->relatedProduct);
+        $productData['sku'] = $productData['sku'] . '_' . mt_rand(1000, 9999);
+        $productId = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCreate',
+            array(
+                'type' => $productData['typeId'],
+                'set' => $createdAttrSetId,
+                'sku' => $productData['sku'],
+                'productData' => $productData['productData']
+            )
+        );
+
+        try {
+            Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductAttributeSetRemove',
+                array('attributeSetId' => $createdAttrSetId)
+            );
+            $this->fail("Didn't receive exception!");
+        } catch (Exception $e) {
+        }
+
+        Magento_Test_Helper_Api::call($this, 'catalogProductDelete', array('productId' => $productId));
+
+        // delete test
+        $attributeSetDelete = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeSetRemove',
+            array('attributeSetId' => $createdAttrSetId)
+        );
+        $this->assertTrue((bool)$attributeSetDelete, "Can't delete added attribute set");
+
+        // Test delete undefined attribute set and check successful delete in previous call
+        try {
+            Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductAttributeSetRemove',
+                array('attributeSetId' => $createdAttrSetId)
+            );
+            $this->fail("Didn't receive exception!");
+        } catch (Exception $e) {
+        }
+
+    }
+
+    /**
+     * Test attribute CRUD in attribute set
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/AttributeSet.php
+     */
+    public function testAttributeSetAttrCRUD()
+    {
+        $testAttributeSetId = Mage::registry('testAttributeSetId');
+        $attrIdsArray = Mage::registry('testAttributeSetAttrIdsArray');
+
+        // add attribute test
+        $addResult = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeSetAttributeAdd',
+            array('attributeId' => $attrIdsArray[0], 'attributeSetId' => $testAttributeSetId)
+        );
+        $this->assertTrue((bool)$addResult);
+
+        // delete attribute test
+        $removeResult = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeSetAttributeRemove',
+            array('attributeId' => $attrIdsArray[0], 'attributeSetId' => $testAttributeSetId)
+        );
+        $this->assertTrue((bool)$removeResult);
+    }
+
+    /**
+     * Test group of attribute sets CRUD
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/AttributeSet.php
+     */
+    public function testAttributeSetGroupCRUD()
+    {
+        $testAttributeSetId = Mage::registry('testAttributeSetId');
+        $attributeSetFixture = simplexml_load_file(dirname(__FILE__) . '/_files/_data/xml/AttributeSet.xml');
+        $data = Magento_Test_Helper_Api::simpleXmlToArray($attributeSetFixture->groupAdd);
+
+        // add group test
+        $attrSetGroupId = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeSetGroupAdd',
+            array('attributeSetId' => $testAttributeSetId, 'groupName' => $data['groupName'])
+        );
+        $this->assertGreaterThan(0, $attrSetGroupId);
+
+        // add already exist group exception test
+        try {
+            $attrSetGroupId = Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductAttributeSetGroupAdd',
+                array('attributeSetId' => $testAttributeSetId, 'groupName' => $data['existsGroupName'])
+            );
+            $this->fail("Didn't receive exception!");
+        } catch (Exception $e) {
+        }
+
+        // rename group test
+        $groupName = $data['groupName'] . ' ' . mt_rand(1000, 9999);
+        $renameResult = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeSetGroupRename',
+            array('groupId' => $attrSetGroupId, 'groupName' => $groupName)
+        );
+        $this->assertTrue((bool)$renameResult);
+
+        // remove group test
+        $removeResult = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeSetGroupRemove',
+            array('attributeGroupId' => $attrSetGroupId)
+        );
+        $this->assertTrue((bool)$removeResult);
+
+        $this->_removeAttrSet($testAttributeSetId);
+        $this->_removeAttributes(Mage::registry('testAttributeSetAttrIdsArray'));
+
+        // remove undefined group exception test
+        $this->setExpectedException('SoapFault');
+        Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeSetGroupRemove',
+            array('attributeGroupId' => $attrSetGroupId)
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/AttributeTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/AttributeTest.php
new file mode 100644
index 00000000000..2b40d645214
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/AttributeTest.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Test API getting orders list method
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDbIsolation enabled
+ */
+class Mage_Catalog_Model_Product_Api_AttributeTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Tests attribute creation with invalid characters in attribute code (possible SQL injection)
+     */
+    public function testCreateWithInvalidCode()
+    {
+        $attributeData = array(
+            'attribute_code' => 'mytest1.entity_id = e.entity_id); DROP TABLE aaa_test;',
+            'scope' => 'global',
+            'frontend_input' => 'select',
+            'frontend_label' => array(
+                array('store_id' => 0, 'label' => 'My Attribute With SQL Injection')
+            )
+        );
+
+        try {
+            Magento_Test_Helper_Api::call($this, 'catalogProductAttributeCreate', array('data' => $attributeData));
+
+            $this->fail('Exception with message like "invalid attribute code" expected but not thrown');
+        } catch (Exception $e) {
+            $this->assertEquals(103, $e->faultcode, 'Unexpected fault code');
+            $this->assertEquals(
+                'Attribute code is invalid. Please use only letters (a-z), numbers (0-9), '
+                    . 'or underscore(_) in this field. First character should be a letter.',
+                $e->getMessage(),
+                'Unexpected exception messsage'
+            );
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/BackorderStatusTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/BackorderStatusTest.php
new file mode 100644
index 00000000000..0d0c49a9d8f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/BackorderStatusTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Test updating product back-order status through API
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDbIsolation enabled
+ */
+class Mage_Catalog_Model_Product_Api_BackorderStatusTest extends PHPUnit_Framework_TestCase
+{
+    /** @var Mage_Catalog_Model_Product */
+    protected $_product;
+
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $productData = require dirname(__FILE__) . '/_files/ProductData.php';
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+
+        $product->setData($productData['create_full_fledged']);
+        $product->save();
+
+        $this->_product = $product;
+
+        parent::setUp();
+    }
+
+    /**
+     * Test updating product back-order status
+     */
+    public function testBackorderStatusUpdate()
+    {
+        $newProductData = array(
+            'use_config_manage_stock' => 0,
+            'manage_stock' => 1,
+            'is_in_stock' => 0,
+            'use_config_backorders' => 0,
+            'backorders' => 1,
+        );
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogInventoryStockItemUpdate',
+            array(
+                'productId' => $this->_product->getSku(),
+                'data' => $newProductData
+            )
+        );
+
+        $this->assertEquals(1, $result);
+        // have to re-load product for stock item set
+        $this->_product->load($this->_product->getId());
+        $this->assertEquals(1, $this->_product->getStockItem()->getBackorders());
+        $this->assertEquals(0, $this->_product->getStockItem()->getUseConfigBackorders());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/ConfigurableTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/ConfigurableTest.php
new file mode 100644
index 00000000000..ceb45e7096c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/ConfigurableTest.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Test configurable product API
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @method Mage_Catalog_Model_Product_Api_Helper_Configurable _getHelper()
+ * @magentoDbIsolation enabled
+ */
+class Mage_Catalog_Model_Product_Api_ConfigurableTest extends Mage_Catalog_Model_Product_Api_TestCaseAbstract
+{
+    /**
+     * Default helper for current test suite
+     *
+     * @var string
+     */
+    protected $_defaultHelper = 'Mage_Catalog_Model_Product_Api_Helper_Configurable';
+
+    /**
+     * Test successful configurable product create.
+     * Scenario:
+     * 1. Create EAV attributes and attribute set usable for configurable.
+     * 2. Send request to create product with type 'configurable' and all valid attributes data.
+     * Expected result:
+     * Load product and assert it was created correctly.
+     */
+    public function testCreate()
+    {
+        $productData = $this->_getHelper()->getValidCreateData();
+        $productId = $this->_createProductWithApi($productData);
+        // Validate outcome
+        /** @var $actual Mage_Catalog_Model_Product */
+        $actual = Mage::getModel('Mage_Catalog_Model_Product')->load($productId);
+        $this->_getHelper()->checkConfigurableAttributesData(
+            $actual,
+            $productData['configurable_attributes'],
+            false
+        );
+        unset($productData['configurable_attributes']);
+        $expected = Mage::getModel('Mage_Catalog_Model_Product');
+        $expected->setData($productData);
+        $this->assertProductEquals($expected, $actual);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/DownloadableLinkCRUDTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/DownloadableLinkCRUDTest.php
new file mode 100644
index 00000000000..ce268a4b1c8
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/DownloadableLinkCRUDTest.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Downloadable product links API model test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Catalog_Model_Product_Api_DownloadableLinkCRUDTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test downloadable link create
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/LinkCRUD.php
+     */
+    public function testDownloadableLinkCreate()
+    {
+        $tagFixture = simplexml_load_file(dirname(__FILE__) . '/_files/_data/xml/LinkCRUD.xml');
+        $items = Magento_Test_Helper_Api::simpleXmlToArray($tagFixture->items);
+
+        $productId = Mage::registry('productData')->getId();
+
+        foreach ($items as $item) {
+            foreach ($item as $key => $value) {
+                if ($value['type'] == 'file') {
+                    $filePath = dirname(__FILE__) . '/_files/_data/files/' . $value['file']['filename'];
+                    $value['file'] = array(
+                        'name' => str_replace('/', '_', $value['file']['filename']),
+                        'base64_content' => base64_encode(file_get_contents($filePath)),
+                        'type' => $value['type']
+                    );
+                }
+                if ($key == 'link' && $value['sample']['type'] == 'file') {
+                    $filePath = dirname(__FILE__) . '/_files/_data/files/' . $value['sample']['file']['filename'];
+                    $value['sample']['file'] = array(
+                        'name' => str_replace('/', '_', $value['sample']['file']['filename']),
+                        'base64_content' => base64_encode(file_get_contents($filePath))
+                    );
+                }
+
+                $resultId = Magento_Test_Helper_Api::call(
+                    $this,
+                    'catalogProductDownloadableLinkAdd',
+                    array(
+                        'productId' => $productId,
+                        'resource' => $value,
+                        'resourceType' => $key
+                    )
+                );
+                $this->assertGreaterThan(0, $resultId);
+            }
+        }
+    }
+
+    /**
+     * Test get downloadable link items
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks.php
+     */
+    public function testDownloadableLinkItems()
+    {
+        /** @var Mage_Catalog_Model_Product $product */
+        $product = Mage::registry('downloadable');
+        $productId = $product->getId();
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductDownloadableLinkList',
+            array('productId' => $productId)
+        );
+        /** @var Mage_Downloadable_Model_Product_Type $downloadable */
+        $downloadable = $product->getTypeInstance();
+        $links = $downloadable->getLinks($product);
+
+        $this->assertEquals(count($links), count($result['links']));
+        foreach ($result['links'] as $actualLink) {
+            foreach ($links as $expectedLink) {
+                if ($actualLink['link_id'] == $expectedLink) {
+                    $this->assertEquals($expectedLink->getData('title'), $actualLink['title']);
+                    $this->assertEquals($expectedLink->getData('price'), $actualLink['price']);
+                }
+            }
+        }
+    }
+
+    /**
+     * Remove downloadable link
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks.php
+     */
+    public function testDownloadableLinkRemove()
+    {
+        /** @var Mage_Catalog_Model_Product $product */
+        $product = Mage::registry('downloadable');
+        /** @var Mage_Downloadable_Model_Product_Type $downloadable */
+        $downloadable = $product->getTypeInstance();
+        $links = $downloadable->getLinks($product);
+        foreach ($links as $link) {
+            $removeResult = Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductDownloadableLinkRemove',
+                array(
+                    'linkId' => $link->getId(),
+                    'resourceType' => 'link'
+                )
+            );
+            $this->assertTrue((bool)$removeResult);
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Helper/Configurable.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Helper/Configurable.php
new file mode 100644
index 00000000000..fa5c87197d3
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Helper/Configurable.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Helper for configurable product tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Catalog_Model_Product_Api_Helper_Configurable extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Retrieve valid configurable data
+     *
+     * @return array
+     */
+    public function getValidCreateData()
+    {
+        require __DIR__ . '/../_files/attribute_set_with_configurable.php';
+        // Prepare fixture
+        $productData = $this->_getValidProductPostData();
+        /** @var Mage_Eav_Model_Entity_Attribute_Set $attributeSet */
+        $attributeSet = Mage::registry('attribute_set_with_configurable');
+        /** @var Mage_Catalog_Model_Resource_Eav_Attribute $attributeOne */
+        $attributeOne = Mage::registry('eav_configurable_attribute_1');
+        /** @var Mage_Catalog_Model_Resource_Eav_Attribute $attributeTwo */
+        $attributeTwo = Mage::registry('eav_configurable_attribute_2');
+        $productData['attribute_set_id'] = $attributeSet->getId();
+        /** @var Mage_Eav_Model_Entity_Attribute_Source_Table $attributeOneSource */
+        $attributeOneSource = $attributeOne->getSource();
+        $attributeOnePrices = array();
+        foreach ($attributeOneSource->getAllOptions(false) as $option) {
+            $attributeOnePrices[] = array(
+                'option_value' => $option['value'],
+                'price' => rand(1, 50),
+                'price_type' => rand(0, 1) ? 'percent' : 'fixed' // is percentage used
+            );
+        }
+        $productData['configurable_attributes'] = array(
+            array(
+                'attribute_code' => $attributeOne->getAttributeCode(),
+                'prices' => $attributeOnePrices,
+                'frontend_label' => "Must not be used",
+                'frontend_label_use_default' => 1,
+                'position' => 2
+            ),
+            array(
+                'attribute_code' => $attributeTwo->getAttributeCode(),
+                'frontend_label' => "Custom Label",
+                'position' => '4'
+            )
+        );
+        return $productData;
+    }
+
+    /**
+     * Check if the configurable attributes' data was saved correctly during create
+     *
+     * @param Mage_Catalog_Model_Product $configurable
+     * @param array $expectedAttributes
+     * @param bool $validatePrices
+     */
+    public function checkConfigurableAttributesData(
+        $configurable,
+        $expectedAttributes,
+        $validatePrices = true
+    ) {
+        /** @var Mage_Catalog_Model_Product_Type_Configurable $configurableType */
+        $configurableType = $configurable->getTypeInstance();
+        $actualAttributes = $configurableType->getConfigurableAttributesAsArray($configurable);
+        foreach ($expectedAttributes as $expectedAttribute) {
+            $attributeCode = $expectedAttribute['attribute_code'];
+            $attributeDataFound = false;
+            foreach ($actualAttributes as $actualAttribute) {
+                if ($actualAttribute['attribute_code'] == $attributeCode) {
+                    $this->_assetAttributes($expectedAttribute, $actualAttribute);
+                    if ($validatePrices && isset($expectedAttribute['prices'])
+                        && is_array($expectedAttribute['prices'])
+                    ) {
+                        $this->_assertPrices($actualAttribute['values'], $expectedAttribute['prices']);
+                    }
+                    $attributeDataFound = true;
+                    break;
+                }
+            }
+            $this->assertTrue(
+                $attributeDataFound,
+                "Attribute with code $attributeCode is not used as a configurable one."
+            );
+        }
+    }
+
+    protected function _assetAttributes($expectedAttribute, $actualAttribute)
+    {
+        if (isset($expectedAttribute['position'])) {
+            $this->assertEquals(
+                $expectedAttribute['position'],
+                $actualAttribute['position'],
+                "Position is invalid."
+            );
+        }
+        if (isset($expectedAttribute['frontend_label_use_default'])
+            && $expectedAttribute['frontend_label_use_default'] == 1
+        ) {
+            $this->assertEquals(
+                $expectedAttribute['frontend_label_use_default'],
+                $actualAttribute['use_default'],
+                "The value of 'use default frontend label' is invalid."
+            );
+            if (isset($expectedAttribute['frontend_label'])) {
+                $this->assertNotEquals(
+                    $expectedAttribute['frontend_label'],
+                    $actualAttribute['label'],
+                    "Default frontend label must be used."
+                );
+            }
+        } else {
+            if (isset($expectedAttribute['frontend_label'])) {
+                $this->assertEquals(
+                    $expectedAttribute['frontend_label'],
+                    $actualAttribute['label'],
+                    "Frontend label is invalid."
+                );
+            }
+        }
+    }
+
+    /**
+     * Validate prices
+     *
+     * @param $actualValues
+     * @param $expectedPrices
+     */
+    protected function _assertPrices($actualValues, $expectedPrices)
+    {
+        $values = array();
+        foreach ($actualValues as $value) {
+            $values[$value['value_index']] = $value;
+        }
+        foreach ($expectedPrices as $expectedValue) {
+            if (isset($expectedValue['option_value'])) {
+                $this->assertArrayHasKey(
+                    $expectedValue['option_value'],
+                    $values,
+                    'Expected price value not found in actual values.'
+                );
+                $actualValue = $values[$expectedValue['option_value']];
+                if (isset($expectedValue['price'])) {
+                    $this->assertEquals(
+                        $expectedValue['price'],
+                        $actualValue['pricing_value'],
+                        'Option price does not match.'
+                    );
+                }
+                if (isset($expectedValue['price_type'])) {
+                    $isPercent = ($expectedValue['price_type'] == 'percent') ? 1 : 0;
+                    $this->assertEquals(
+                        $isPercent,
+                        $actualValue['is_percent'],
+                        'Option price type does not match.'
+                    );
+                }
+            }
+        }
+    }
+
+    /**
+     * Get valid data for configurable product POST
+     *
+     * @return array
+     */
+    protected function _getValidProductPostData()
+    {
+        return require __DIR__ . '/../_files/_data/product_configurable_all_fields.php';
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Helper/Simple.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Helper/Simple.php
new file mode 100644
index 00000000000..5865fbd4391
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/Helper/Simple.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Simple product tests helper.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Catalog_Model_Product_Api_Helper_Simple extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Load simple product fixture data
+     *
+     * @param string $fixtureName
+     * @return array
+     */
+    public function loadSimpleProductFixtureData($fixtureName)
+    {
+        return require '_fixture/_data/Catalog/Product/Simple/' . $fixtureName . '.php';
+    }
+
+    /**
+     * Check simple product attributes
+     *
+     * @param Mage_Catalog_Model_Product $product
+     * @param array $expectedProductData
+     * @param array $skipAttributes
+     * @param array $skipStockItemAttrs
+     */
+    public function checkSimpleAttributesData(
+        $product,
+        $expectedProductData,
+        $skipAttributes = array(),
+        $skipStockItemAttrs = array()
+    ) {
+        $expectedProductData = array_diff_key($expectedProductData, array_flip($skipAttributes));
+
+        $dateAttributes = array(
+            'news_from_date',
+            'news_to_date',
+            'special_from_date',
+            'special_to_date',
+            'custom_design_from',
+            'custom_design_to'
+        );
+        foreach ($dateAttributes as $attribute) {
+            if (isset($expectedProductData[$attribute])) {
+                $this->assertEquals(
+                    strtotime($expectedProductData[$attribute]),
+                    strtotime($product->getData($attribute))
+                );
+            }
+        }
+
+        $exclude = array_merge(
+            $dateAttributes,
+            array(
+                'group_price',
+                'tier_price',
+                'stock_data',
+                'url_key',
+                'url_key_create_redirect'
+            )
+        );
+        // Validate URL Key - all special chars should be replaced with dash sign
+        $this->assertEquals('123-abc', $product->getUrlKey());
+        $productAttributes = array_diff_key($expectedProductData, array_flip($exclude));
+        foreach ($productAttributes as $attribute => $value) {
+            $this->assertEquals($value, $product->getData($attribute), 'Invalid attribute "' . $attribute . '"');
+        }
+
+        if (isset($expectedProductData['stock_data'])) {
+            $stockItem = $product->getStockItem();
+            $expectedStock = array_diff_key($expectedProductData['stock_data'], array_flip($skipStockItemAttrs));
+            foreach ($expectedStock as $attribute => $value) {
+                $this->assertEquals(
+                    $value,
+                    $stockItem->getData($attribute),
+                    'Invalid stock_data attribute "' . $attribute . '"'
+                );
+            }
+        }
+    }
+
+    /**
+     * Check stock item use default flags
+     *
+     * @param Mage_Catalog_Model_Product $product
+     */
+    public function checkStockItemDataUseDefault($product)
+    {
+        $stockItem = $product->getStockItem();
+        $this->assertNotNull($stockItem);
+        $fields = array(
+            'use_config_min_qty',
+            'use_config_min_sale_qty',
+            'use_config_max_sale_qty',
+            'use_config_backorders',
+            'use_config_notify_stock_qty',
+            'use_config_enable_qty_inc'
+        );
+        foreach ($fields as $field) {
+            $this->assertEquals(1, $stockItem->getData($field), $field . ' is not set to 1');
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/ImageTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/ImageTest.php
new file mode 100644
index 00000000000..82ac6d66290
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/ImageTest.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * Test API work with product images
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDbIsolation enabled
+ */
+class Mage_Catalog_Model_Product_Api_ImageTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Catalog_Model_Product
+     */
+    protected $_product;
+
+    protected $_requestData;
+
+    /**
+     * Sets up the fixture, for example, open a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $productFixture = require dirname(__FILE__) . '/_files/ProductData.php';
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+
+        $product->setData($productFixture['create_full_fledged']);
+        $product->save();
+
+        $this->_product = $product;
+        $this->_requestData = array(
+            'label' => 'My Product Image',
+            'position' => 2,
+            'types' => array('small_image', 'image', 'thumbnail'),
+            'exclude' => 1,
+            'remove' => 0,
+            'file' => array(
+                'name' => 'my_image_file',
+                'content' => null,
+                'mime' => 'image/jpeg'
+            )
+        );
+
+        parent::setUp();
+    }
+
+    /**
+     * Tests valid image for product creation
+     *
+     * @dataProvider validImageProvider
+     * @param string $validImgPath Absolute path to valid image file
+     */
+    public function testCreateValidImage($validImgPath)
+    {
+        $product = $this->_product;
+        $requestData = $this->_requestData;
+
+        // valid JPG image file
+        $requestData['file']['content'] = base64_encode(file_get_contents($validImgPath));
+
+        $imagePath = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeMediaCreate',
+            array('productId' => $product->getSku(), 'data' => $requestData)
+        );
+        $this->assertInternalType('string', $imagePath, 'String type of response expected but not received');
+
+        // reload product to reflect changes done by API request
+        $product->load($product->getId());
+
+        // retrieve saved image
+        $attributes = $product->getTypeInstance()->getSetAttributes($product);
+        $imageParams = $attributes['media_gallery']->getBackend()->getImage($product, $imagePath);
+
+        $this->assertInternalType('array', $imageParams, 'Image not found');
+        $this->assertEquals($requestData['label'], $imageParams['label'], 'Label does not match');
+        $this->assertEquals($requestData['position'], $imageParams['position'], 'Position does not match');
+        $this->assertEquals($requestData['exclude'], $imageParams['disabled'], 'Disabled does not match');
+    }
+
+    /**
+     * Tests not an image for product creation
+     */
+    public function testCreateNotAnImage()
+    {
+        $product = $this->_product;
+        $requestData = $this->_requestData;
+
+        // TXT file
+        $requestData['file']['content'] = base64_encode(
+            file_get_contents(dirname(__FILE__) . '/_files/_data/files/test.txt')
+        );
+
+        try {
+            Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductAttributeMediaCreate',
+                array('productId' => $product->getSku(), 'data' => $requestData)
+            );
+        } catch (Exception $e) {
+            $this->assertEquals('Unsupported image format.', $e->getMessage(), 'Invalid exception message');
+        }
+        // reload product to reflect changes done by API request
+        $product->load($product->getId());
+
+        $mediaData = $product->getData('media_gallery');
+
+        $this->assertCount(0, $mediaData['images'], 'Invalid image file has been saved');
+    }
+
+    /**
+     * Tests an invalid image for product creation
+     *
+     * @dataProvider invalidImageProvider
+     * @param strign $invalidImgPath Absolute path to invalid image file
+     */
+    public function testCreateInvalidImage($invalidImgPath)
+    {
+        $product = $this->_product;
+        $requestData = $this->_requestData;
+
+        // Not an image file with JPG extension
+        $requestData['file']['content'] = base64_encode(file_get_contents($invalidImgPath));
+
+        try {
+            Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductAttributeMediaCreate',
+                array('productId' => $product->getSku(), 'data' => $requestData)
+            );
+        } catch (Exception $e) {
+            $this->assertEquals('Unsupported image format.', $e->getMessage(), 'Invalid exception message');
+        }
+        // reload product to reflect changes done by API request
+        $product->load($product->getId());
+
+        $mediaData = $product->getData('media_gallery');
+
+        $this->assertCount(0, $mediaData['images'], 'Invalid image file has been saved');
+    }
+
+    /**
+     * Data provider
+     *
+     * @return array
+     */
+    public function invalidImageProvider()
+    {
+        return array(
+            array(dirname(__FILE__) . '/_files/_data/files/images/test.bmp.jpg'),
+            array(dirname(__FILE__) . '/_files/_data/files/images/test.php.jpg')
+        );
+    }
+
+    /**
+     * Data provider
+     *
+     * @return array
+     */
+    public function validImageProvider()
+    {
+        return array(
+            array(dirname(__FILE__) . '/_files/_data/files/images/test.jpg.jpg'),
+            array(dirname(__FILE__) . '/_files/_data/files/images/test.png.jpg')
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/SimpleTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/SimpleTest.php
new file mode 100644
index 00000000000..bfbd8bca2db
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/SimpleTest.php
@@ -0,0 +1,458 @@
+<?php
+/**
+ * Test Product CRUD operations
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @method Mage_Catalog_Model_Product_Api_Helper_Simple _getHelper()
+ */
+class Mage_Catalog_Model_Product_Api_SimpleTest extends Mage_Catalog_Model_Product_Api_TestCaseAbstract
+{
+    /**
+     * Default helper for current test suite
+     *
+     * @var string
+     */
+    protected $_defaultHelper = 'Mage_Catalog_Model_Product_Api_Helper_Simple';
+
+    /**
+     * Test product resource post
+     * @magentoDbIsolation enabled
+     */
+    public function testCreateSimpleRequiredFieldsOnly()
+    {
+        $productData = require '_files/_data/simple_product_data.php';
+        $productId = $this->_createProductWithApi($productData);
+
+        $actualProduct = Mage::getModel('Mage_Catalog_Model_Product');
+        $actualProduct->load($productId);
+        $this->assertNotNull($actualProduct->getId());
+        $expectedProduct = Mage::getModel('Mage_Catalog_Model_Product');
+        $expectedProduct->setData($productData);
+
+        $this->assertProductEquals($expectedProduct, $actualProduct);
+    }
+
+    /**
+     * Test product resource post with all fields
+     *
+     * @param array $productData
+     * @dataProvider dataProviderTestCreateSimpleAllFieldsValid
+     * @magentoDbIsolation enabled
+     */
+    public function testCreateSimpleAllFieldsValid($productData)
+    {
+        $productId = $this->_createProductWithApi($productData);
+
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+        $this->assertNotNull($product->getId());
+        $skipAttributes = array(
+            'news_from_date',
+            'news_to_date',
+            'custom_design_from',
+            'custom_design_to',
+            'msrp_enabled',
+            'msrp_display_actual_price_type',
+            'msrp',
+            'meta_title',
+            'meta_keyword',
+            'meta_description',
+            'page_layout',
+            'gift_wrapping_available',
+            'gift_wrapping_price'
+        );
+        $skipStockItemAttrs = array('min_qty');
+
+        $this->_getHelper()->checkSimpleAttributesData(
+            $product,
+            $productData,
+            $skipAttributes,
+            $skipStockItemAttrs
+        );
+    }
+
+    /**
+     * Data provider for testCreateSimpleAllFieldsValid
+     *
+     * @magentoDbIsolation enabled
+     * @return array
+     */
+    public function dataProviderTestCreateSimpleAllFieldsValid()
+    {
+        $productData = require '_files/_data/simple_product_all_fields_data.php';
+        // Fix for tests, because in current soap version this field has "int" type in WSDL
+        // @TODO: fix WSDL in new soap version when implemented
+        $productData['stock_data']['notify_stock_qty'] = 2;
+        $specialCharsData = require '_files/_data/simple_product_special_chars_data.php';
+
+        return array(
+            array($specialCharsData),
+            array($productData),
+        );
+    }
+
+    /**
+     * Test product resource post using config values in inventory
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testCreateInventoryUseConfigValues()
+    {
+        $productData = require '_files/_data/simple_product_inventory_use_config.php';
+        $productId = $this->_createProductWithApi($productData);
+
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+        $this->assertNotNull($product->getId());
+
+        $this->_getHelper()->checkStockItemDataUseDefault($product);
+    }
+
+    /**
+     * Test product resource post using config values in inventory manage stock field
+     *
+     * @magentoConfigFixture current_store cataloginventory/item_options/manage_stock 0
+     * @magentoDbIsolation enabled
+     */
+    public function testCreateInventoryManageStockUseConfig()
+    {
+        $productData = require '_files/_data/simple_product_manage_stock_use_config.php';
+
+        $productId = $this->_createProductWithApi($productData);
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+        $this->assertNotNull($product->getId());
+
+        $stockItem = $product->getStockItem();
+        $this->assertNotNull($stockItem);
+        $this->assertEquals(0, $stockItem->getManageStock());
+    }
+
+    /**
+     * Test for set special price for product
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testSetSpecialPrice()
+    {
+        $productData = require dirname(__FILE__) . '/_files/ProductData.php';
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $specialPrice = 1.99;
+        $specialFrom = '2011-12-22 00:00:00';
+        $specialTo = '2011-12-25 00:00:00';
+
+        $product->setData($productData['create_full_fledged']);
+        $product->save();
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductSetSpecialPrice',
+            array(
+                'productId' => $product->getSku(),
+                'specialPrice' => $specialPrice,
+                'fromDate' => $specialFrom,
+                'toDate' => $specialTo,
+                'store' => Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID
+            )
+        );
+
+        $this->assertEquals(true, $result, 'Response is not true casted value');
+
+        // reload product to reflect changes done by API request
+        $product->load($product->getId());
+
+        $this->assertEquals($specialPrice, $product->getSpecialPrice(), 'Special price not changed');
+        $this->assertEquals($specialFrom, $product->getSpecialFromDate(), 'Special price from not changed');
+        $this->assertEquals($specialTo, $product->getSpecialToDate(), 'Special price to not changed');
+    }
+
+    /**
+     * Test get product info by numeric SKU
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testProductInfoByNumericSku()
+    {
+        $data = require dirname(__FILE__) . '/_files/ProductData.php';
+
+        //generate numeric sku
+        $data['create_with_attributes_soapv2']->sku = rand(1000000, 99999999);
+
+        $productId = Magento_Test_Helper_Api::call($this, 'catalogProductCreate', $data['create']);
+
+        $this->assertEquals(
+            $productId,
+            (int)$productId,
+            'Result of a create method is not an integer.'
+        );
+
+        //test new product exists in DB
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+        $this->assertNotNull($product->getId(), 'Tested product not found.');
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductInfo',
+            array(
+                'productId' => $data['create']['sku'],
+                'store' => 0, //default 0
+                'attributes' => '',
+                'identifierType' => 'sku',
+            )
+        );
+
+        $this->assertInternalType('array', $result, 'Response is not an array');
+        $this->assertArrayHasKey('product_id', $result, 'Response array does not have "product_id" key');
+        $this->assertEquals($productId, $result['product_id'], 'Product cannot be load by SKU which is numeric');
+    }
+
+    /**
+     * Test product CRUD
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testProductCrud()
+    {
+        $data = require dirname(__FILE__) . '/_files/ProductData.php';
+
+        // create product for test
+        $productId = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCreate',
+            $data['create_with_attributes_soapv2']
+        );
+
+        // test new product id returned
+        $this->assertGreaterThan(0, $productId);
+
+        //test new product exists in DB
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+        $this->assertNotNull($product->getId());
+
+        //update product
+        $data['create_with_attributes_soapv2'] = array('productId' => $productId) + $data['update'];
+
+        $isOk = Magento_Test_Helper_Api::call($this, 'catalogProductUpdate', $data['create_with_attributes_soapv2']);
+
+        //test call response is true
+        $this->assertTrue($isOk, 'Call returned false');
+
+        //test product exists in DB after update and product data changed
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+        $this->assertNotNull($product->getId());
+        $this->assertEquals($data['update']['productData']->name, $product->getName());
+
+        //delete product
+        $isOk = Magento_Test_Helper_Api::call($this, 'catalogProductDelete', array('productId' => $productId));
+
+        //test call response is true
+        $this->assertTrue((bool)$isOk, 'Call returned false'); //in SOAP v2 it's integer:1
+
+        //test product not exists in DB after delete
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+        $this->assertNull($product->getId());
+    }
+
+    /**
+     * Test product CRUD with custom options
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud.php
+     * @magentoDbIsolation enabled
+     */
+    public function testProductWithOptionsCrud()
+    {
+        $this->markTestSkipped("TODO: Fix test");
+        $optionValueApi = Mage::registry('optionValueApi');
+        $optionValueInstaller = Mage::registry('optionValueInstaller');
+        $data = require dirname(__FILE__) . '/_files/ProductData.php';
+
+        $singleData = & $data['create_with_attributes_soapv2']['productData']->additional_attributes->singleData;
+        $singleData[1]->value = $optionValueApi;
+        $singleData[3]->value = $optionValueInstaller;
+        $attributes = $data['create_with_attributes_soapv2']['productData']->additional_attributes;
+
+        // create product for test
+        $productId = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCreate',
+            $data['create_with_attributes_soapv2']
+        );
+
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+
+        // test new product id returned
+        $this->assertGreaterThan(0, $productId);
+
+        //test new product attributes
+        $this->assertEquals($attributes->singleData[0]->value, $product->getData('a_text_api'));
+        $this->assertEquals($attributes->singleData[1]->value, $product->getData('a_select_api'));
+        $this->assertEquals($attributes->singleData[2]->value, $product->getData('a_text_ins'));
+        $this->assertEquals($attributes->singleData[3]->value, $product->getData('a_select_ins'));
+
+    }
+
+    /**
+     * Test create product with invalid attribute set
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testProductCreateWithInvalidAttributeSet()
+    {
+        $productData = require dirname(__FILE__) . '/_files/ProductData.php';
+        $productData = $productData['create_full']['soap'];
+        $productData['set'] = 9999;
+
+        try {
+            Magento_Test_Helper_Api::call($this, 'catalogProductCreate', $productData);
+        } catch (Exception $e) {
+            $this->assertEquals('Product attribute set does not exist.', $e->getMessage(), 'Invalid exception message');
+        }
+
+        // find not product (category) attribute set identifier to try other error message
+        /** @var $entity Mage_Eav_Model_Entity_Type */
+        $entity = Mage::getModel('Mage_Eav_Model_Entity_Type');
+        $entityTypeId = $entity->loadByCode('catalog_category')->getId();
+
+        /** @var $attrSet Mage_Eav_Model_Entity_Attribute_Set */
+        $attrSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set');
+
+        /** @var $attrSetCollection Mage_Eav_Model_Resource_Entity_Attribute_Set_Collection */
+        $attrSetCollection = $attrSet->getCollection();
+        $categoryAtrrSets = $attrSetCollection->setEntityTypeFilter($entityTypeId)->toOptionHash();
+        $categoryAttrSetId = key($categoryAtrrSets);
+
+        $productData['set'] = $categoryAttrSetId;
+
+        try {
+            Magento_Test_Helper_Api::call($this, 'catalogProductCreate', $productData);
+        } catch (Exception $e) {
+            $this->assertEquals(
+                'Product attribute set does not belong to catalog product entity type.',
+                $e->getMessage(),
+                'Invalid exception message'
+            );
+        }
+    }
+
+    /**
+     * Test product attributes update in custom store view
+     *
+     * @magentoDbIsolation enabled
+     * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/store_on_new_website.php
+     */
+    public function testProductUpdateCustomStore()
+    {
+        /** @var Mage_Core_Model_Store $store */
+        $store = Mage::registry('store_on_new_website');
+
+        $data = require dirname(__FILE__) . '/_files/ProductData.php';
+        // create product for test
+        $productId = Magento_Test_Helper_Api::call($this, 'catalogProductCreate', $data['create_full']['soap']);
+        $this->assertGreaterThan(0, $productId, 'Product was not created');
+
+        // update product on test store
+        $data['update_custom_store'] = array('productId' => $productId) + $data['update_custom_store'];
+        $data['update_custom_store']['store'] = $store->getCode();
+        $isOk = Magento_Test_Helper_Api::call($this, 'catalogProductUpdate', $data['update_custom_store']);
+        $this->assertTrue($isOk, 'Can not update product on test store');
+
+        // Load product in test store
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->setStoreId($store->getId())->load($productId);
+        $this->assertNotNull($product->getId());
+        $this->assertEquals(
+            $data['update_custom_store']['productData']->name,
+            $product->getName(),
+            'Product name was not updated'
+        );
+
+        // update product attribute in default store
+        $data['update_default_store'] = array('productId' => $productId) + $data['update_default_store'];
+        $isOk = Magento_Test_Helper_Api::call($this, 'catalogProductUpdate', $data['update_default_store']);
+        $this->assertTrue($isOk, 'Can not update product on default store');
+
+        // Load product in default store
+        $productDefault = Mage::getModel('Mage_Catalog_Model_Product');
+        $productDefault->load($productId);
+        $this->assertEquals(
+            $data['update_default_store']['productData']->description,
+            $productDefault->getDescription(),
+            'Description attribute was not updated for default store'
+        );
+        $this->assertEquals(
+            $data['create_full']['soap']['productData']->name,
+            $productDefault->getName(),
+            'Product name attribute should not have been changed'
+        );
+
+        // Load product in test store
+        $productTestStore = Mage::getModel('Mage_Catalog_Model_Product');
+        $productTestStore->setStoreId($store->getId())->load($productId);
+        $this->assertEquals(
+            $data['update_default_store']['productData']->description,
+            $productTestStore->getDescription(),
+            'Description attribute was not updated for test store'
+        );
+        $this->assertEquals(
+            $data['update_custom_store']['productData']->name,
+            $productTestStore->getName(),
+            'Product name attribute should not have been changed for test store'
+        );
+    }
+
+    /**
+     * Test create product to test default values for media attributes
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testProductCreateForTestMediaAttributesDefaultValue()
+    {
+        $productData = require dirname(__FILE__) . '/_files/ProductData.php';
+        $productData = $productData['create'];
+
+        // create product for test
+        $productId = Magento_Test_Helper_Api::call($this, 'catalogProductCreate', $productData);
+
+        // test new product id returned
+        $this->assertGreaterThan(0, $productId);
+
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($productId);
+
+        $found = false;
+        foreach ($product->getMediaAttributes() as $mediaAttribute) {
+            $mediaAttrCode = $mediaAttribute->getAttributeCode();
+            $this->assertEquals(
+                $product->getData($mediaAttrCode),
+                'no_selection',
+                'Attribute "' . $mediaAttrCode . '" has no default value'
+            );
+            $found = true;
+        }
+        $this->assertTrue($found, 'Media attrributes not found');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/TagCRUDTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/TagCRUDTest.php
new file mode 100644
index 00000000000..6d7cd6945c3
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/TagCRUDTest.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Product tag API model test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/TagCRUD.php
+ * @magentoDbIsolation enabled
+ */
+class Mage_Catalog_Model_Product_Api_TagCRUDTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test tag CRUD
+     */
+    public function testTagCRUD()
+    {
+        $tagFixture = simplexml_load_file(dirname(__FILE__) . '/_files/_data/xml/TagCRUD.xml');
+        $data = Magento_Test_Helper_Api::simpleXmlToArray($tagFixture->tagData);
+        $expected = Magento_Test_Helper_Api::simpleXmlToArray($tagFixture->expected);
+
+        $data['product_id'] = Mage::registry('productData')->getId();
+        $data['customer_id'] = Mage::registry('customerData')->getId();
+
+        // create test
+        $createdTags = Magento_Test_Helper_Api::call($this, 'catalogProductTagAdd', array('data' => $data));
+
+        $this->assertCount(3, $createdTags);
+
+        // Invalid product ID exception test
+        try {
+            $data['product_id'] = mt_rand(10000, 99999);
+            Magento_Test_Helper_Api::call($this, 'catalogProductTagAdd', array('data' => $data));
+            $this->fail("Didn't receive exception!");
+        } catch (Exception $e) {
+            $this->assertEquals('Requested product does not exist.', $e->getMessage());
+        }
+
+        // Invalid customer ID exception test
+        try {
+            $data['product_id'] = Mage::registry('productData')->getId();
+            $data['customer_id'] = mt_rand(10000, 99999);
+            Magento_Test_Helper_Api::call($this, 'catalogProductTagAdd', array('data' => $data));
+            $this->fail("Didn't receive exception!");
+        } catch (Exception $e) {
+            $this->assertEquals('Requested customer does not exist.', $e->getMessage());
+        }
+
+        // Invalid store ID exception test
+        try {
+            $data['product_id'] = Mage::registry('productData')->getId();
+            $data['customer_id'] = Mage::registry('customerData')->getId();
+            $data['store'] = mt_rand(10000, 99999);
+            Magento_Test_Helper_Api::call($this, 'catalogProductTagAdd', array('data' => $data));
+            $this->fail("Didn't receive exception!");
+        } catch (Exception $e) {
+            $this->assertEquals('Requested store does not exist.', $e->getMessage());
+        }
+
+        // items list test
+        $tagsList = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductTagList',
+            array(
+                'productId' => Mage::registry('productData')->getId(),
+                'store' => 0
+            )
+        );
+        $this->assertInternalType('array', $tagsList);
+        $this->assertNotEmpty($tagsList, "Can't find added tag in list");
+        $this->assertCount((int)$expected['created_tags_count'], $tagsList, "Can't find added tag in list");
+
+        // delete test
+        $tagToDelete = (array)array_shift($tagsList);
+        $tagDelete = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductTagRemove',
+            array('tagId' => $tagToDelete['tag_id'])
+        );
+        $this->assertTrue((bool)$tagDelete, "Can't delete added tag");
+
+        // Delete exception test
+        $this->setExpectedException('SoapFault', 'Requested tag does not exist.');
+        Magento_Test_Helper_Api::call($this, 'catalogProductTagRemove', array('tagId' => $tagToDelete['tag_id']));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/TestCaseAbstract.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/TestCaseAbstract.php
new file mode 100644
index 00000000000..bbee1550e19
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/TestCaseAbstract.php
@@ -0,0 +1,182 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/**
+ * Abstract class for products resource tests
+ */
+abstract class Mage_Catalog_Model_Product_Api_TestCaseAbstract extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Default helper for current test suite
+     *
+     * @var string
+     */
+    protected $_defaultHelper = 'Helper_Catalog_Product_Simple';
+
+    /** @var array */
+    protected $_helpers = array();
+
+    /**
+     * Map common fixtures keys to soap wsdl.
+     *
+     * @var array
+     */
+    protected $_attributesArrayMap = array(
+        'tier_price' => array(
+            'website_id' => 'website',
+            'cust_group' => 'customer_group_id',
+            'price_qty' => 'qty'
+        )
+    );
+
+    /**
+     * Get current test suite helper if class name not specified.
+     *
+     * @param string|null $helperClass
+     * @return mixed
+     */
+    protected function _getHelper($helperClass = null)
+    {
+        if (is_null($helperClass)) {
+            $helperClass = $this->_defaultHelper;
+        }
+
+        if (!isset($this->_helpers[$helperClass])) {
+            $this->_helpers[$helperClass] = new $helperClass;
+        }
+
+        return $this->_helpers[$helperClass];
+    }
+
+    /**
+     * Try to create product using API and check received error messages
+     *
+     * @param array $productData
+     * @param array|string $expectedMessages
+     */
+    protected function _createProductWithErrorMessagesCheck($productData, $expectedMessages)
+    {
+        try {
+            $this->_tryToCreateProductWithApi($productData);
+            $this->fail('SoapFault exception was expected to be raised.');
+        } catch (SoapFault $e) {
+            $this->_checkErrorMessagesInResponse($e, $expectedMessages);
+        }
+    }
+
+    /**
+     * Create product with API
+     *
+     * @param array $productData
+     * @return int
+     */
+    protected function _createProductWithApi($productData)
+    {
+        $productId = (int)$this->_tryToCreateProductWithApi($productData);
+        $this->assertGreaterThan(0, $productId, 'Response does not contain valid product ID.');
+        return $productId;
+    }
+
+    /**
+     * Try to create product with API request
+     *
+     * @param array $productData
+     * @return int
+     */
+    protected function _tryToCreateProductWithApi($productData)
+    {
+        $formattedData = $this->_prepareProductDataForSoap($productData);
+        $response = Magento_Test_Helper_Api::call($this, 'catalogProductCreate', $formattedData);
+        return $response;
+    }
+
+    /**
+     * Map array keys in accordance to soap wsdl.
+     *
+     * @param array $productData
+     * @return array
+     */
+    protected function _prepareProductDataForSoap($productData)
+    {
+        $formattedData = array(
+            'type' => $productData['type_id'],
+            'set' => $productData['attribute_set_id'],
+            'sku' => $productData['sku'],
+            'productData' => array_diff_key(
+                $productData,
+                array_flip(array('type_id', 'attribute_set_id', 'sku'))
+            )
+        );
+        foreach ($formattedData['productData'] as $attrCode => &$attrValue) {
+            if (in_array($attrCode, array_keys($this->_attributesArrayMap)) && is_array($attrValue)) {
+                $map = $this->_attributesArrayMap[$attrCode];
+                foreach ($attrValue as &$arrayItem) {
+                    foreach ($map as $arrayKey => $keyMapValue) {
+                        if (in_array($arrayKey, $arrayItem)) {
+                            $arrayItem[$keyMapValue] = $arrayItem[$arrayKey];
+                            unset($arrayItem[$arrayKey]);
+                        }
+                    }
+                }
+                unset($arrayItem);
+            }
+        }
+        if (isset($formattedData['productData']['tier_price'])) {
+            foreach ($formattedData['productData']['tier_price'] as &$tierPriceItem) {
+                $tierPriceItem = (object)$tierPriceItem;
+            }
+        }
+        $formattedData['productData'] = (object)$formattedData['productData'];
+        return $formattedData;
+    }
+
+    /**
+     * Check if expected messages contained in the SoapFault exception
+     *
+     * @param SoapFault $exception
+     * @param array|string $expectedMessages
+     */
+    protected function _checkErrorMessagesInResponse(SoapFault $exception, $expectedMessages)
+    {
+        $expectedMessages = is_array($expectedMessages) ? $expectedMessages : array($expectedMessages);
+        $receivedMessages = explode("\n", $exception->getMessage());
+        $this->assertMessagesEqual($expectedMessages, $receivedMessages);
+    }
+
+    /**
+     * Assert that two products are equal.
+     *
+     * @param Mage_Catalog_Model_Product $expected
+     * @param Mage_Catalog_Model_Product $actual
+     */
+    public function assertProductEquals(Mage_Catalog_Model_Product $expected, Mage_Catalog_Model_Product $actual)
+    {
+        foreach ($expected->getData() as $attribute => $value) {
+            $this->assertEquals(
+                $value,
+                $actual->getData($attribute),
+                sprintf('Attribute "%s" value does not equal to expected "%s".', $attribute, $value)
+            );
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/AttributeSet.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/AttributeSet.php
new file mode 100644
index 00000000000..b3c09c8ba1a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/AttributeSet.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var Mage_Catalog_Model_Product_Attribute_Set_Api $attrSetApi */
+$attrSetApi = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Set_Api');
+Mage::register(
+    'testAttributeSetId',
+    $attrSetApi->create('Test Attribute Set Fixture ' . mt_rand(1000, 9999), 4)
+);
+
+$attributeSetFixture = simplexml_load_file(__DIR__ . '/_data/xml/AttributeSet.xml');
+$data = Magento_Test_Helper_Api::simpleXmlToArray($attributeSetFixture->attributeEntityToCreate);
+$data['attribute_code'] = $data['attribute_code'] . '_' . mt_rand(1000, 9999);
+
+$testAttributeSetAttrIdsArray = array();
+
+$attrApi = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Api');
+$testAttributeSetAttrIdsArray[0] = $attrApi->create($data);
+Mage::register('testAttributeSetAttrIdsArray', $testAttributeSetAttrIdsArray);
diff --git a/index.php.sample b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/AttributeSet_rollback.php
similarity index 64%
rename from index.php.sample
rename to dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/AttributeSet_rollback.php
index 4070e1621e4..b834c5119e3 100644
--- a/index.php.sample
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/AttributeSet_rollback.php
@@ -18,13 +18,9 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category   Mage
- * @package    Mage
- * @copyright  Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-require_once __DIR__ . '/app/bootstrap.php';
-
-$appOptions = new Mage_Core_Model_App_Options($_SERVER);
-Mage::run($appOptions->getRunCode(), $appOptions->getRunType(), $appOptions->getRunOptions());
+Mage::unregister('testAttributeSetId');
+Mage::unregister('testAttributeSetAttrIdsArray');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOption.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOption.php
new file mode 100644
index 00000000000..5bf7d8d24ed
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOption.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$fixture = simplexml_load_file(__DIR__ . '/_data/xml/CustomOption.xml');
+
+//Create new simple product
+$productData = Magento_Test_Helper_Api::simpleXmlToArray($fixture->fixtureProduct);
+$productData['sku'] = $productData['sku'] . mt_rand(1000, 9999);
+$productData['name'] = $productData['name'] . ' ' . mt_rand(1000, 9999);
+
+$product = Mage::getModel('Mage_Catalog_Model_Product');
+$product->setData($productData)->setStoreId(1)->save();
+Mage::register('productData', $product);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOptionValue.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOptionValue.php
new file mode 100644
index 00000000000..d703eba4c3a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOptionValue.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$fixture = simplexml_load_file(__DIR__ . '/_data/xml/CustomOptionValue.xml');
+
+//Create new simple product
+$productData = Magento_Test_Helper_Api::simpleXmlToArray($fixture->fixtureProduct);
+$productData['sku'] = $productData['sku'] . mt_rand(1000, 9999);
+$productData['name'] = $productData['name'] . ' ' . mt_rand(1000, 9999);
+
+$product = Mage::getModel('Mage_Catalog_Model_Product');
+$product->setData($productData)->save();
+Mage::register('productData', $product);
+
+$customOptionApi = Mage::getModel('Mage_Catalog_Model_Product_Option_Api');
+$data = Magento_Test_Helper_Api::simpleXmlToArray($fixture->fixtureCustomOption);
+// unsetOptions() call helps to prevent duplicate options add
+// during the sequence of $customOptionApi->add() calls in unit test suite
+Mage::getSingleton('Mage_Catalog_Model_Product_Option')->unsetOptions();
+$customOptionApi->add($product->getId(), $data);
+$customOptionsList = $customOptionApi->items($product->getId());
+
+Mage::register('customOptionId', $customOptionsList[0]['option_id']);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOptionValue_rollback.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOptionValue_rollback.php
new file mode 100644
index 00000000000..62cd96c4b32
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOptionValue_rollback.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('productData');
+Mage::unregister('customOptionId');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOption_rollback.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOption_rollback.php
new file mode 100644
index 00000000000..53d97011fbb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/CustomOption_rollback.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('productData');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks.php
new file mode 100644
index 00000000000..cf81d0703e9
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$fixture = simplexml_load_file(__DIR__ . '/_data/xml/LinkCRUD.xml');
+
+//Create new downloadable product
+$productData = Magento_Test_Helper_Api::simpleXmlToArray($fixture->product);
+$productData['sku'] = $productData['sku'] . mt_rand(1000, 9999);
+$productData['name'] = $productData['name'] . ' ' . mt_rand(1000, 9999);
+$linksData = array(
+    array(
+        'title' => 'Test Link 1',
+        'price' => '1',
+        'is_unlimited' => '1',
+        'number_of_downloads' => '0',
+        'is_shareable' => '0',
+        'sample' => array(
+            'type' => 'url',
+            'url' => 'http://www.magentocommerce.com/img/logo.gif',
+        ),
+        'type' => 'url',
+        'link_url' => 'http://www.magentocommerce.com/img/logo.gif',
+    ),
+    array(
+        'title' => 'Test Link 2',
+        'price' => '2',
+        'is_unlimited' => '0',
+        'number_of_downloads' => '10',
+        'is_shareable' => '1',
+        'sample' =>
+        array(
+            'type' => 'url',
+            'url' => 'http://www.magentocommerce.com/img/logo.gif',
+        ),
+        'type' => 'url',
+        'link_url' => 'http://www.magentocommerce.com/img/logo.gif',
+    ),
+);
+
+$product = Mage::getModel('Mage_Catalog_Model_Product');
+$product->setData($productData)
+    ->setStoreId(0)
+    ->setDownloadableData(array('link' => $linksData))
+    ->save();
+Mage::register('downloadable', $product);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks_rollback.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks_rollback.php
new file mode 100644
index 00000000000..61dbcecbae6
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/DownloadableWithLinks_rollback.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('downloadable');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/LinkCRUD.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/LinkCRUD.php
new file mode 100644
index 00000000000..a2aaa61c628
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/LinkCRUD.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+//Add customer
+$fixture = simplexml_load_file(__DIR__ . '/_data/xml/LinkCRUD.xml');
+$customerData = Magento_Test_Helper_Api::simpleXmlToArray($fixture->customer);
+$customerData['email'] = mt_rand(1000, 9999) . '.' . $customerData['email'];
+
+$customer = Mage::getModel('Mage_Customer_Model_Customer');
+$customer->setData($customerData)->save();
+Mage::register('customerData', $customer);
+
+//Create new downloadable product
+$productData = Magento_Test_Helper_Api::simpleXmlToArray($fixture->product);
+$productData['sku'] = $productData['sku'] . mt_rand(1000, 9999);
+$productData['name'] = $productData['name'] . ' ' . mt_rand(1000, 9999);
+
+$product = Mage::getModel('Mage_Catalog_Model_Product');
+$product->setData($productData)->save();
+Mage::register('productData', $product);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/LinkCRUD_rollback.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/LinkCRUD_rollback.php
new file mode 100644
index 00000000000..599c7468b4e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/LinkCRUD_rollback.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('customerData');
+Mage::unregister('productData');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductAttributeData.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductAttributeData.php
new file mode 100644
index 00000000000..f969fbe5305
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductAttributeData.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+return array(
+    'create_text_api' => array(
+        'attribute_code' => 'a_text_api',
+        'scope' => 'store',
+        'frontend_input' => 'text',
+        'default_value' => '',
+        'is_unique' => '0',
+        'is_required' => '0',
+        'apply_to' => array(
+            'simple',
+            'grouped',
+        ),
+        'is_configurable' => '0',
+        'is_searchable' => '1',
+        'is_visible_in_advanced_search' => '0',
+        'is_comparable' => '1',
+        'is_used_for_promo_rules' => '0',
+        'is_visible_on_front' => '1',
+        'used_in_product_listing' => '0',
+        //'label' => 'a_text_api',
+        'frontend_label' => array(
+            array(
+                'store_id' => 0,
+                'label' => 'a_text_api'
+            ),
+            array(
+                'store_id' => 1,
+                'label' => 'a_text_api'
+            ),
+        ),
+    ),
+    'create_select_api' => array(
+        'attribute_code' => 'a_select_api',
+        'scope' => 'store',
+        'frontend_input' => 'select',
+        'default_value' => '',
+        'is_unique' => '0',
+        'is_required' => '0',
+        'apply_to' => array(
+            'simple',
+            'grouped',
+        ),
+        'is_configurable' => '0',
+        'is_searchable' => '1',
+        'is_visible_in_advanced_search' => '0',
+        'is_comparable' => '1',
+        'is_used_for_promo_rules' => '0',
+        'is_visible_on_front' => '1',
+        'used_in_product_listing' => '0',
+        //'label' => 'a_select_api',
+        'frontend_label' => array(
+            array(
+                'store_id' => 0,
+                'label' => 'a_select_api'
+            ),
+            array(
+                'store_id' => 1,
+                'label' => 'a_select_api'
+            ),
+        ),
+    ),
+    'create_text_installer' => array(
+        'code' => 'a_text_ins',
+        'attributeData' => array(
+            'type' => 'varchar',
+            'input' => 'text',
+            'label' => 'a_text_ins',
+            'required' => 0,
+            'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
+            'user_defined' => true,
+
+        ),
+    ),
+    'create_select_installer' => array(
+        'code' => 'a_select_ins',
+        'attributeData' => array(
+            'type' => 'int',
+            'input' => 'select',
+            'label' => 'a_select_ins',
+            'required' => 0,
+            'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_STORE,
+            'user_defined' => true,
+            'option' => array(
+                'values' => array(
+                    'option1',
+                    'option2',
+                    'option3',
+                ),
+            )
+        ),
+    ),
+    'create_select_api_options' => array(
+        array(
+            'label' => array(
+                array(
+                    'store_id' => 0,
+                    'value' => 'option1'
+                ),
+                array(
+                    'store_id' => 1,
+                    'value' => 'option1'
+                ),
+            ),
+            'order' => 0,
+            'is_default' => 1
+        ),
+        array(
+            'label' => array(
+                array(
+                    'store_id' => 0,
+                    'value' => 'option2'
+                ),
+                array(
+                    'store_id' => 1,
+                    'value' => 'option2'
+                ),
+            ),
+            'order' => 0,
+            'is_default' => 1
+        ),
+    ),
+);
+
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductData.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductData.php
new file mode 100644
index 00000000000..57b8ad59b14
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductData.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+return array(
+    'create' => array(
+        'type' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+        'set' => 4,
+        'sku' => 'simple' . uniqid(),
+        'productData' => (object)array(
+            'name' => 'test',
+            'description' => 'description',
+            'short_description' => 'short description',
+            'weight' => 1,
+            'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+            'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+            'price' => 9.99,
+            'tax_class_id' => 2,
+            'stock_data' => array(
+                'manage_stock' => 1,
+                'qty' => 10,
+                'backorders' => 1,
+                'is_in_stock' => '1',
+            )
+        )
+    ),
+    'update' => array(
+        'productData' => (object)array(
+            'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED, //required to see product on backend
+            'name' => 'Simple Product Updated', //test update method
+        )
+    ),
+    'update_custom_store' => array(
+        'productData' => (object)array(
+            'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED, //required to see product on backend
+            'name' => 'Simple Product Updated Custom Store', //test update method
+        ),
+        'store' => 'test_store'
+    ),
+    'update_default_store' => array(
+        'productData' => (object)array(
+            'description' => 'Updated description'
+        )
+    ),
+    'create_with_attributes_soapv2' => array(
+        'type' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+        'set' => 4,
+        'sku' => 'simple' . uniqid(),
+        'productData' => (object)array(
+            'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED, //required to see product on backend
+            'name' => 'Product with attributes',
+            'description' => 'description',
+            'short_description' => 'short description',
+            'weight' => 1,
+            'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+            'price' => 9.99,
+            'tax_class_id' => 2,
+            'additional_attributes' => (object)array(
+                'singleData' => array(
+                    (object)array(
+                        'key' => 'a_text_api',
+                        'value' => 'qqq123'
+                    ),
+                    (object)array(
+                        'key' => 'a_select_api',
+                        'value' => '__PLACEHOLDER__'
+                    ),
+                    (object)array(
+                        'key' => 'a_text_ins',
+                        'value' => 'qqq123'
+                    ),
+                    (object)array(
+                        'key' => 'a_select_ins',
+                        'value' => '__PLACEHOLDER__'
+                    ),
+                ),
+                'multi_data' => array()
+            )
+        )
+    ),
+    'create_full_fledged' => array(
+        'sku' => 'simple' . uniqid(),
+        'attribute_set_id' => 4,
+        'type_id' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+        'name' => 'Simple Product',
+        'website_ids' => array(Mage::app()->getStore()->getWebsiteId()),
+        'description' => '...',
+        'short_description' => '...',
+        'price' => 0.99,
+        'tax_class_id' => 2,
+        'weight' => 1,
+        'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+        'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+        'special_from_date' => false, // to avoid set this attr to '' which leads to unpredictable bugs
+        'stock_data' => array(
+            'manage_stock' => 1,
+            'qty' => 10,
+            'backorders' => 1,
+            'is_in_stock' => '1',
+        )
+    ),
+    'create_full' => array(
+        'soap' => array(
+            'type' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+            'set' => 4,
+            'sku' => 'simple' . uniqid(),
+            'productData' => (object)array(
+                'name' => 'Simple Product',
+                'website_ids' => array(Mage::app()->getStore()->getWebsiteId()),
+                'description' => '...',
+                'short_description' => '...',
+                'price' => 0.99,
+                'tax_class_id' => 2,
+                'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+                'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+                'weight' => 1,
+                'stock_data' => array(
+                    'manage_stock' => 1,
+                    'qty' => 10,
+                    'backorders' => 1,
+                    'is_in_stock' => '1',
+                )
+            )
+        )
+    )
+);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud.php
new file mode 100644
index 00000000000..471627dbe2a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$data = require dirname(__FILE__) . '/ProductAttributeData.php';
+// add product attributes via installer
+$installer = new Mage_Catalog_Model_Resource_Setup('core_setup');
+$installer->addAttribute(
+    'catalog_product',
+    $data['create_text_installer']['code'],
+    $data['create_text_installer']['attributeData']
+);
+$installer->addAttribute(
+    'catalog_product',
+    $data['create_select_installer']['code'],
+    $data['create_select_installer']['attributeData']
+);
+
+//add attributes to default attribute set via installer
+$installer->addAttributeToSet('catalog_product', 4, 'Default', $data['create_text_installer']['code']);
+$installer->addAttributeToSet('catalog_product', 4, 'Default', $data['create_select_installer']['code']);
+
+$attribute = Mage::getModel('Mage_Eav_Model_Entity_Attribute');
+$attribute->loadByCode('catalog_product', $data['create_select_installer']['code']);
+$collection = Mage::getResourceModel('Mage_Eav_Model_Resource_Entity_Attribute_Option_Collection')
+    ->setAttributeFilter($attribute->getId())
+    ->load();
+$options = $collection->toOptionArray();
+$optionValueInstaller = $options[1]['value'];
+
+//add product attributes via api model
+$model = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Api');
+$response1 = $model->create($data['create_text_api']);
+$response2 = $model->create($data['create_select_api']);
+
+//add options
+$model = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Api');
+$model->addOption($response2, $data['create_select_api_options'][0]);
+$model->addOption($response2, $data['create_select_api_options'][1]);
+$options = $model->options($response2);
+$optionValueApi = $options[1]['value'];
+
+//add attributes to default attribute set via api model
+$model = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Set_Api');
+$model->attributeAdd($response1, 4);
+$model->attributeAdd($response2, 4);
+
+$attributes = array($response1, $response2);
+Mage::register('attributes', $attributes);
+Mage::register('optionValueApi', $optionValueApi);
+Mage::register('optionValueInstaller', $optionValueInstaller);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud_rollback.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud_rollback.php
new file mode 100644
index 00000000000..1752cdc13f7
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/ProductWithOptionCrud_rollback.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('attributes');
+Mage::unregister('optionValueApi');
+Mage::unregister('optionValueInstaller');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/TagCRUD.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/TagCRUD.php
new file mode 100644
index 00000000000..591a77187d5
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/TagCRUD.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+//Add customer
+$tagFixture = simplexml_load_file(__DIR__ . '/_data/xml/TagCRUD.xml');
+$customerData = Magento_Test_Helper_Api::simpleXmlToArray($tagFixture->customer);
+$customerData['email'] = mt_rand(1000, 9999) . '.' . $customerData['email'];
+
+$customer = Mage::getModel('Mage_Customer_Model_Customer');
+$customer->setData($customerData)->save();
+Mage::register('customerData', $customer);
+
+//Create new simple product
+$productData = Magento_Test_Helper_Api::simpleXmlToArray($tagFixture->product);
+$productData['sku'] = $productData['sku'] . mt_rand(1000, 9999);
+$productData['name'] = $productData['name'] . ' ' . mt_rand(1000, 9999);
+
+$product = Mage::getModel('Mage_Catalog_Model_Product');
+$product->setData($productData)->save();
+Mage::register('productData', $product);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/TagCRUD_rollback.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/TagCRUD_rollback.php
new file mode 100644
index 00000000000..599c7468b4e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/TagCRUD_rollback.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('customerData');
+Mage::unregister('productData');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/book.pdf b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/book.pdf
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/image.jpg b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/image.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d0e160eef48d9c7463e232c2ba44bd4f9663b5a1
GIT binary patch
literal 157486
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
H-j@C!JvO;X

literal 0
HcmV?d00001

diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.bmp.jpg b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.bmp.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..0c7e587766e481fedade831d2b35bb64aeb401a9
GIT binary patch
literal 6966
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

literal 0
HcmV?d00001

diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.jpg.jpg b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.jpg.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..880a5fc50b998e6450c7dc168fa65ddc4f992877
GIT binary patch
literal 1621
zcmex=<Nrg3ldct+X$%aWo>~kX3=9nH3_^^|42(b)2um@tg6Sk6TN=vF0<txrYM6j*
zLq;YBQ6OCe#70222#{_E;>>myu-@4~c9MTliU*JenF*r<GV)9E-7<4Zic%GVOG;BR
z^A#c(j0_A7tqhH<42=~GO|4AKfeZ#_28Idj3@kvc21bSkObZ~+GXV0Lk=XxlGdMFa
zGckb>5U>CdD+enp3kxe3J3AW(4;K#)Hy1ZIFQ1SAFP|VEH@AS8fS|C5sHi9pzqo{$
zh=h=cs0hdqMrNQM7FJGHR!$LKZe9_R!T$pcf*cG63<k`MN(@YbjLd?J|Bo=p1AWiR
z2nIlxg8?HG(2Z>D9GqO-Km}U`7?>EDnVDFaL9Pa>t_8|7un4jWDH=Mm2?r*!D;0_u
zHBMZ}q3pErplHy=4=Tn<MNOPsV&W2#QmSg|8k$-rre@|AmR8O#u5Rugo?gKrp<&?>
zkx|JhscGpMnOVgprDf$6l~v6xt!?ccon4bAPnkMx`iz;g7A;<~blLJ1D_3pWyk+aQ
z?K^hvI&}ER(PPI?oIG{u@|COCuHU$M>*1rvPo6$|{^I4UkDoq&`TFhqkDtFl{$gZc
zhIk7|V)d6G&|gd}EX*wIAb&A3l>;%eAPcLaA)An6AbVn=u#!<Dhlta}g&PlYDjNrV
z5KSt&$R(y?@=*07$ZKGq5$CZcvU~>j7{Xt-7<iZ&fsw~7$Y9U#Q!?kC?`^@^S<`bD
zTLfO2@Ay8D!<lCt$5+uW^>2zFW$QClygwTC_KB~>rVm$-baG9Q3jWreARv4|=crqC
z+T`Q<#UH&xwqL1n{_xJ8J1T2CCvV@@<u~@OKJh7KVVa)HVTSoL#kC}Q1VsLA*SfP+
zChB6Ty<)3fg{JyyyF#-s_myvL{}a0~=7;hT;Y_JbmBEVEYR7~eU)kDCjbiELmQ?!e
z=p@eDBV=Ls<IB3Knc7DV`300sYh~-Y{@a$pbKl)(lg{s{tczn~h)FLiPkAnJT$FLs
z<Wrw(wtf1%z0TtNvf6AfYkwnGpH=S^@{${DPcF&0qdtAdn{#g$e4HOuv*=s<f*RwG
zvi&VJ$(eR*mTrlDao^_(L(=k-GjdNTFXR*4d^<1ut$%y`X1N|yUG2!7A5FjQUm9U_
zetG6+-j&jNTw>N;bC)nNY4I6;FIxT}x7^Qsmg^O-ok=Y#zA8`rv-*~On*MDs{dTF4
zI{A;Kd%ymj6X6}b+B8yyd6Us*{sYZlWnZ_;`YkG7^8L<z{W)6B_v5*3&A(mvp_yO%
z(APPx$+Rz<<JR*!!$Un2fAm~GR3~?JmUPRuncJP7XHEX2zWrg`?cW}C*X>k)T&~ya
zPRv(peAw~i)~>40winr(t@-xtW<O>9PC@E{{vSn|70J6dO!nUI*r}9pCdlRQ)hUlz
z<c_5E$XZS8o%ig<sV$dcPP<>3cibn}>63O!#iC5<jLN5i3w~`*VEnr3*!^2ulD8#F
zwJXkHoMb(VcmLL^Kg-YmcFC2lPmU4W`Y`<B*44F6EcyxRktz)Jt9~|Gep~Nv_NDFK
z_PMI2E1zFD>eapL=DXY)$&bG6hxNOD@prG=GCS7)jZwpE8^xOeA7YI!USBnDPpRbk
zrS-Y*TXxm$T%I{!tj1ua+58p9CH7~ypSs=f>DfQ8`UiGjKb7D7cp?0z{Koe^YwHv$
z_>ahQ**G1lP}yF#SxByC+rugKyZqd*RE78VFZ=Mh&usq9OL2w&85(!KPS9TCquRLQ
zpMLu(@BIDAkMuYH4))!@we+9qhtlg!HIb`cgm<|f?LF+|DRGDKXY@x2``*ObIaT4C
R)~d{URdFs)cUk@an*i-xbQJ&q

literal 0
HcmV?d00001

diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.php.jpg b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.php.jpg
new file mode 100644
index 00000000000..da4a98d54c1
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.php.jpg
@@ -0,0 +1,41 @@
+<?php
+try {
+    $soap = new SoapClient('http://apia.com/api/soap/?wsdl=1', array('trace' => true));
+
+    $sessionId = $soap->login('admin', '123123q');
+
+    /*$soap->call(
+        $sessionId,
+        'product_attribute.create',
+        array(
+            array(
+                'attribute_code'           => 'mytest1',
+                'scope'                    => 'global',
+                'frontend_input'           => 'select',
+                'is_used_for_promo_rules'  => true,
+                'frontend_label'           => array(
+                    array('store_id' => 0, 'label' => 'My Test Attribute 1')
+                )
+            )
+        )
+    );*/
+    $soap->call(
+        $sessionId,
+        'product_attribute.create',
+        array(
+            array(
+                'attribute_code'           => 'mytest1.entity_id = e.entity_id); DROP TABLE aaa_test;',
+                'scope'                    => 'global',
+                'frontend_input'           => 'select',
+                'is_used_for_promo_rules'  => true,
+                'frontend_label'           => array(
+                    array('store_id' => 0, 'label' => 'My Attribute With SQL Injection')
+                )
+            )
+        )
+    );
+} catch (Exception $e) {
+    echo $e;
+}
+var_dump($soap->__getLastResponseHeaders());
+var_dump($soap->__getLastResponse());
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.png.jpg b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.png.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4d753cf35add75cc57c5dfc2cbff891945e00020
GIT binary patch
literal 2801
zcmV<N3J&#&P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru*#a2=4-_+YWPktw3VumM
zK~!korJ3t*9Mu`df9K4ZnVr4)?$}A}B+i8d?1Wnb6hR{zsTT=)11eQi0=1Qjs;VFO
zQlzTNA3!BU)go1uT2+;Lp@7<|r459JOF}|OAXXgPxjV#hV#jyyeP>QT?0UVI+4Zg&
z=}0?s&YV5Zd7t-r-}j6#_CK$wdFh(BJ`d{X)(uTjK0p`UDj}tRPvJFD+Aqo{7mchW
zKSne#McH@_qUcr??sQoXerpv~!RF>Jd!s?X0)ZB~=<(`cWnoc5eC8&~o0Kc9tS|SD
zEHoh`Kl|<@+_$T@Xiizw{QpxGZffjo<yKc(tI_d(Z@+$InCrLZa{%kKt|}g^>!1ns
zj#&fPp|Q!z`B$N{LdXh?I-Lf?Ko|zq++WuVrctm}093nHoH)OHcX6Hv`uj+x(u`jG
zlz7HN*a4(%vjP?bjV)F;47SqAclLDPdLHM;rwena3bdItKl#yjh(v;<Gg(GPFLU(R
zAV-f6GQE^UhQbKbs;zyxd>3^?ilz(uSvn?}b#YyfV&SO(5HJ;yNDv_emZ`XXXCHlA
zHuCjH_i^&$VcvTCIOoQ0AR|$PW&7%ML$N~R<KX_*8JnEX{}g@{%3aa0Qy3tGz%V41
zsW45&K>s#+d%8F~a)~z&9cN;02BWDNii2StL8&bgq^l*&(ACK*%&s4BE)o}+(6+6T
z@kc&5&0k-8lj%enJdf^{2>Twohi`uE5l);O;^g2tbfg(!+p7lL<;ye;f&nwH<&8z*
z@;Mb0#{rEL0<ASd2wr*pE#5djMBCP_1g}q^EDN)%lRy3AFpqulK6dwS$8l^v{Ah?o
z(!vNwK&dJbcx7jA%*DAe7hCyX?WdLXr5v&}vPm*o7thm7+_=Tx4}D0mIm(%XhnYBg
zj%%lfICJnYz4z?qzlV;|(h{X-!#eKTa~qDACUavPcXk>)Z<PpK6lJLv*(E(4&6uXD
z?4vjm%hFwl#gn+M%h6+}S$Er3#*Uw2&%kzqL5Fb2!EtPk3=U(rwvtSyXlrXGkxUVf
zCm9;PL~3afFSdjcY0CLWk@PmIM!|rEAtf21tL9gQNUZY@ml7%Bi6pagi=d&ue>=~7
z?+JubctVoZaP-s*IME1NYg(Ekq*7@Ti4?JTlJgg?;&~qK!W>?F38S?G=>+S{Tub4d
zyFOE)I^}>1DzyAKD-Et)yGdt9D`#du<=o}#yf?mtYnY^6k6WLPqatDEZ%neO_hAev
zNu@I+lR4mvi!rWGOy%a!X30)YAR|qv*7n*Fc8&6@N=*#HwmEm<Dtqs}gTMXrFg<q<
z@cOTRM|kJ$WRppfm(H<m?;gyF2{x?nU}-5%CX*$d%8*FrEHS^ZL@bsl%;_!8lSwC0
z>$(w!^3QJ8s78hw`0{}g2hkcUlVtb6cD8TX$o~$$Pw$>xI3i0VU=VF<A$H*s&p-Dx
zK_^g{Piu|m=^TArms`_wrE73qbZiMD97ZU$;@EkLR64n!o>bpZ179ftAe71cwQ=qo
z*ukdWZXUjWH#1}7%v~GDP9?c-*JghF!*3IfhH_%SiU=%&&}gQo=Se10r64>HFCIfi
zn#fgx<qM*+rYLScU{yu#Z5Yg@UCx}nh~wCFcC_;JQ;%Yr3Mpj?jSXpFnwo%ZlMT6~
zGg(rpG|6O&-kx>L&Mj0@J(D3jbrZ8|!)Hu6a*AfC-CsRWVH&MjoSdX*V;4aufN7a1
zLn5UpQ3R3KWKk4RH5xB(iP7_8{{EUyBLfb?4pgN{b2vaxTa=ktswR!3U)d&<#g(xM
zhDR<lIW@ylEKWL|!Sg(HnN~|FP|CozEF335BpjlpIl{Wm)|z>I_SR&nG?ul2O&vV`
z`P*`vBjrl-Eh)=PC@c%l^EiIu3?1z)1cL!AQ(+heLWn$-N)tZQR0IMRuIrG=WO3bz
z+O<nMg%?}I2uFSUkBnUB=;%alLkqHBS>5F#aT(omX);XRn&rf)vqU2y0s$MP6jBOI
zvyw{7S*shca2%Ucr$>;HD0m(^okC|a6^nG|W-+48RcnHhA}F7q`B!A3tgJI6!m`on
z6vHEz=<H}A91dbzCQ2E|yeVbTgi=bBGMJrR;1@6bkqZ|;#q8dQ(bAT8-Zb9g0@=A4
zbTStsym$=ly1CdOR*BL=_?DlQDwMyMj)R*{;kq6l92=yyC7Pp>Wnvfxwh#zImh8&g
z?|j6|zj=jtBAMg)^b|&GTh7rf8>6iQqpclpae>Uu>*!PpZ)p*uxpkEiURVC~E9y&}
zGZe<1&jq7IGR1%1{D7bnz;SF$Q(@%&KuSR@p5T`+|Cx8*J6Xx|r3GXOO$0L9gdK^J
znHa}Q#PT5hmZ57L!c-~hm;XqXIoHxsoWHz!keS&9zO?^=f<K%cxx@=E{(+m5GgZ`P
z3cIPrHxaWo^x!V!&Ve**$oDh|=lj3a)s8rlL!bCMUnu0TWz%{Pg3-|{WU|?sievBC
zRg{s|dEi^^$fazwtQxkZ#8}?BvMUx#aOUhqMyBI<%k-#r6$+5m3z(`$h*TakF0WHo
zO_TuD)=_h9Mx+UQQy;2hoo|0%ZznIk_#9id_N>fXBPdmzha#!~UKx{jVt?6^;RrGq
z!i&dz7bqPEq{Qmkj8KZq#CW0asmC7Vh3B3mX4<HxW`6psf01>)B1Y74<XFe4o?(9O
z8wbiW!jkON4&Y8t`Mzvz+`N+3Mw<|ZLZ?&w;Mphn`LmDF8Zfa8ffICyxtgKNHw%lZ
znRWWKYAJ`TEV^Y$Gn!gZ?VbL+Q$_>TwVpu#U7VbVGd!PR(Sv}1o}lFMFZ8piyR}Xl
zRnoZ{Fo_ftS`}xuHg7`)LzSwabtPwoV0dhbSKlAu@=}(B2O$YtBZ_Ap-CKy_{@(zq
z0IC7F)QQW$tYoJKft~%xfK!&+r>lO@c<t~IC$7$ME1lzgyDizfrJa5EY^&Qr>ro?F
zF|f+S!nO(Av8TimUOZL-cG-{8uFLP=ILYu_hL{JAgv}AfxAyfD3EHJ!Z|eAhQw^+P
z-T(N3dTUUj6slt#I+?&r#B=w{rwu+LFuf2b9Cp~$)l7>m2?znoV9^sR4qe!@(oL+l
zw3LnTZMkN)clKj%+ljj{hxWXh6nO33vkXqgnagS{2|Xdj{=56=Yz<d;+A35o050k`
z><6AW(1>gmoF^PXb##H7&3`ZOAD_;;WU?Mxdpc-$3<5H@fVeRE<opD+B;2p)ukFNj
z$X1DjS=LI9Qv>X~gI73pZJz0rhXOVP6%X#(z=qD|+EKU;2bYb?R$ZT0%bM$H{(Wqe
z;n_4X4?+fPZMN9IcY6&Q)t7R}#$-#fR=}TJnBb$Uv)oL&2w;6sv3Ex|-R;peMc|4^
zT%QSR=rsO1z1%c{LnkjXJd<M4)dVH<HCa4#XWyD4aA_o7(^q!UFxa6hlYD$_j+;pj
z1K1E!+`FTjrbuvg%T}?jY*e-y1zT)gjo|&ktBlU1Sa3BVDcIa(v-ghP+ElG!UD>E?
z)dpME?*n+~@+4<&EHah$uqE_FP43#U9?Mc|vhM!@Ol;{PO#WO(00000NkvXXu0mjf
D+Hptq

literal 0
HcmV?d00001

diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/song.mp3 b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/song.mp3
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/test.txt b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/test.txt
new file mode 100644
index 00000000000..77e2760d439
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/test.txt
@@ -0,0 +1 @@
+This is a content of test file.
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/product_configurable_all_fields.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/product_configurable_all_fields.php
new file mode 100644
index 00000000000..a08752ada3a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/product_configurable_all_fields.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$taxClasses = Mage::getResourceModel('Mage_Tax_Model_Resource_Class_Collection')->toArray();
+$taxClass = reset($taxClasses['items']);
+
+return array(
+    'type_id' => Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE,
+    'sku' => 'configurable_' . uniqid(),
+    'name' => 'Test Configurable ' . uniqid(),
+    'description' => 'Test description',
+    'short_description' => 'Test short description',
+    'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+    'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+    'price' => 25.50,
+    'tax_class_id' => $taxClass['class_id']
+);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_all_fields_data.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_all_fields_data.php
new file mode 100644
index 00000000000..c51ef75ab5a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_all_fields_data.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $entityType Mage_Eav_Model_Entity_Type */
+$entityType = Mage::getModel('Mage_Eav_Model_Entity_Type')->loadByCode('catalog_product');
+$taxClasses = Mage::getResourceModel('Mage_Tax_Model_Resource_Class_Collection')->toArray();
+$taxClass = reset($taxClasses['items']);
+
+return array(
+    'type_id' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+    'attribute_set_id' => $entityType->getDefaultAttributeSetId(),
+    'sku' => 'simple' . uniqid(),
+    'name' => 'Test',
+    'description' => 'Test description',
+    'short_description' => 'Test short description',
+    'weight' => 125,
+    'news_from_date' => '02/16/2012',
+    'news_to_date' => '16.02.2012',
+    'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+    'url_key' => '123!"â„–;%:?*()_+{}[]\|<>,.?/abc',
+    'url_key_create_redirect' => 1,
+    'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+    'price' => 25.50,
+    'special_price' => 11.2,
+    'special_from_date' => '02/16/2012',
+    'special_to_date' => '03/17/2012',
+    'group_price' => array(
+        array('website_id' => 0, 'cust_group' => 1, 'price' => 11)
+    ),
+    'tier_price' => array(
+        array('website_id' => 0, 'cust_group' => 1, 'price_qty' => 5.5, 'price' => 11.054)
+    ),
+    'msrp_enabled' => 1,
+    'msrp_display_actual_price_type' => 1,
+    'msrp' => 11.015,
+    'enable_googlecheckout' => 1,
+    'tax_class_id' => $taxClass['class_id'],
+    'meta_title' => 'Test title',
+    'meta_keyword' => 'Test keyword',
+    'meta_description' => str_pad('', 85, 'a4b'),
+    'custom_design' => 'default/default/blank',
+    'custom_design_from' => date('Y-m-d'),
+    'custom_design_to' => date('Y-m-d', time() + 24 * 3600),
+    'custom_layout_update' => '<xml><layout>Test Custom Layout Update</layout></xml>',
+    'page_layout' => 'one_column',
+    'gift_message_available' => 1,
+    'gift_wrapping_available' => 1,
+    'gift_wrapping_price' => 0.99,
+    'stock_data' => array(
+        'manage_stock' => 1,
+        'qty' => 1,
+        'min_qty' => 1.56,
+        'min_sale_qty' => 1,
+        'max_sale_qty' => 1,
+        'is_qty_decimal' => 0,
+        'backorders' => 1,
+        'notify_stock_qty' => -50.99,
+        'enable_qty_increments' => 0,
+        'is_in_stock' => 0
+    )
+);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_data.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_data.php
new file mode 100644
index 00000000000..2497818c49e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_data.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $entityType Mage_Eav_Model_Entity_Type */
+$entityType = Mage::getModel('Mage_Eav_Model_Entity_Type')->loadByCode('catalog_product');
+$taxClasses = Mage::getResourceModel('Mage_Tax_Model_Resource_Class_Collection')->toArray();
+$taxClass = reset($taxClasses['items']);
+
+return array(
+    'type_id' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+    'attribute_set_id' => $entityType->getDefaultAttributeSetId(),
+    'sku' => 'simple' . uniqid(),
+    'weight' => 1,
+    'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+    'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+    'name' => 'Simple Product',
+    'description' => 'Simple Description',
+    'short_description' => 'Simple Short Description',
+    'price' => 99.95,
+    'tax_class_id' => $taxClass['class_id'],
+);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_inventory_use_config.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_inventory_use_config.php
new file mode 100644
index 00000000000..1a350b9be4c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_inventory_use_config.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $entityType Mage_Eav_Model_Entity_Type */
+$entityType = Mage::getModel('Mage_Eav_Model_Entity_Type')->loadByCode('catalog_product');
+$taxClasses = Mage::getResourceModel('Mage_Tax_Model_Resource_Class_Collection')->toArray();
+$taxClass = reset($taxClasses['items']);
+
+return array(
+    'type_id' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+    'attribute_set_id' => $entityType->getDefaultAttributeSetId(),
+    'sku' => 'simple' . uniqid(),
+    'name' => 'Test',
+    'description' => 'Test description',
+    'short_description' => 'Test short description',
+    'weight' => 125,
+    'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+    'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+    'price' => 25.50,
+    'tax_class_id' => $taxClass['class_id'],
+    // Field should not be validated if "Use Config Settings" checkbox is set
+    // thus invalid value should not raise error
+    'stock_data' => array(
+        'manage_stock' => 1,
+        'use_config_manage_stock' => 0,
+        'qty' => 1,
+        'min_qty' => -1,
+        'use_config_min_qty' => 1,
+        'min_sale_qty' => -1,
+        'use_config_min_sale_qty' => 1,
+        'max_sale_qty' => -1,
+        'use_config_max_sale_qty' => 1,
+        'is_qty_decimal' => 0,
+        'backorders' => -1,
+        'use_config_backorders' => 1,
+        'notify_stock_qty' => 'text',
+        'use_config_notify_stock_qty' => 1,
+        'enable_qty_increments' => -100,
+        'use_config_enable_qty_inc' => 1,
+        'is_in_stock' => 0
+    )
+);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_manage_stock_use_config.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_manage_stock_use_config.php
new file mode 100644
index 00000000000..8c0f08a63a7
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_manage_stock_use_config.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $entityType Mage_Eav_Model_Entity_Type */
+$entityType = Mage::getModel('Mage_Eav_Model_Entity_Type')->loadByCode('catalog_product');
+$taxClasses = Mage::getResourceModel('Mage_Tax_Model_Resource_Class_Collection')->toArray();
+$taxClass = reset($taxClasses['items']);
+
+return array(
+    'type_id' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+    'attribute_set_id' => $entityType->getDefaultAttributeSetId(),
+    'sku' => 'simple' . uniqid(),
+    'name' => 'Test',
+    'description' => 'Test description',
+    'short_description' => 'Test short description',
+    'weight' => 125,
+    'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+    'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+    'price' => 25.50,
+    'tax_class_id' => $taxClass['class_id'],
+    // Field should not be validated if "Use Config Settings" checkbox is set
+    // thus invalid value should not raise error
+    'stock_data' => array(
+        'manage_stock' => -1,
+        'use_config_manage_stock' => 1,
+        'qty' => 1,
+        'min_qty' => -1,
+        'min_sale_qty' => -1,
+        'use_config_min_sale_qty' => -1,
+        'max_sale_qty' => -1,
+        'use_config_max_sale_qty' => -1,
+        'is_qty_decimal' => -1,
+        'backorders' => -1,
+        'notify_stock_qty' => 'text',
+        'enable_qty_increments' => -100,
+        'is_in_stock' => -1
+    )
+);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_special_chars_data.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_special_chars_data.php
new file mode 100644
index 00000000000..1264f891ed6
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/simple_product_special_chars_data.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $entityType Mage_Eav_Model_Entity_Type */
+$entityType = Mage::getModel('Mage_Eav_Model_Entity_Type')->loadByCode('catalog_product');
+$taxClasses = Mage::getResourceModel('Mage_Tax_Model_Resource_Class_Collection')->toArray();
+$taxClass = reset($taxClasses['items']);
+
+return array(
+    'type_id' => Mage_Catalog_Model_Product_Type::TYPE_SIMPLE,
+    'attribute_set_id' => $entityType->getDefaultAttributeSetId(),
+    'name' => '!";%:?*()_+{}[]\|<>,.?/',
+    'description' => '!";%:?*()_+{}[]\|<>,.?/',
+    'short_description' => '!";%:?*()_+{}[]\|<>,.?/',
+    'sku' => '!";%:?*()_+{}[]\|<>,.?/' . uniqid(),
+    'weight' => 125,
+    'news_from_date' => '02/16/2012',
+    'news_to_date' => '16.02.2012',
+    'status' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED,
+    'url_key' => '123!";%:?*()_+{}[]\|<>,.?/abc',
+    'visibility' => Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
+    'price' => 25.50,
+    'special_price' => 11.2,
+    'special_from_date' => '02/16/2012',
+    'special_to_date' => '03/17/2012',
+    'group_price' => array(
+        array('website_id' => 0, 'cust_group' => 1, 'price' => 11)
+    ),
+    'tier_price' => array(
+        array('website_id' => 0, 'cust_group' => 1, 'price_qty' => 5.5, 'price' => 11.054)
+    ),
+    'msrp_enabled' => 1,
+    'msrp_display_actual_price_type' => 1,
+    'msrp' => 11.015,
+    'enable_googlecheckout' => 1,
+    'tax_class_id' => $taxClass['class_id'],
+    'meta_title' => '!";%:?*()_+{}[]\|<>,.?/',
+    'meta_keyword' => '!";%:?*()_+{}[]\|<>,.?/',
+    'meta_description' => str_pad('', 8, '!";%:?*_+{}[]\|<>,.?'),
+    'custom_design' => 'default/default/blank',
+    'custom_design_from' => date('Y-m-d'),
+    'custom_design_to' => date('Y-m-d', time() + 24 * 3600),
+    'page_layout' => 'one_column',
+);
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/AttributeSet.xml b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/AttributeSet.xml
new file mode 100644
index 00000000000..94849ef8abe
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/AttributeSet.xml
@@ -0,0 +1,85 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<root>
+    <create>
+        <attributeSetName>Test Attribute Set</attributeSetName>
+        <skeletonSetId>4</skeletonSetId>
+    </create>
+    <attributeEntityToCreate>
+        <attribute_code>a_test_attr_textarea</attribute_code>
+        <scope>store</scope>
+        <frontend_input>textarea</frontend_input>
+        <default_value></default_value>
+        <is_unique>0</is_unique>
+        <is_required>0</is_required>
+        <apply_to>simple</apply_to>
+        <apply_to>grouped</apply_to>
+        <is_configurable>0</is_configurable>
+        <is_searchable>1</is_searchable>
+        <is_visible_in_advanced_search>0</is_visible_in_advanced_search>
+        <is_comparable>1</is_comparable>
+        <is_used_for_promo_rules>0</is_used_for_promo_rules>
+        <is_visible_on_front>1</is_visible_on_front>
+        <used_in_product_listing>0</used_in_product_listing>
+        <additional_fields>
+            <is_html_allowed_on_front>1</is_html_allowed_on_front>
+            <is_wysiwyg_enabled>1</is_wysiwyg_enabled>
+        </additional_fields>
+        <frontend_label>
+            <store_id>0</store_id>
+            <label>aaa</label>
+        </frontend_label>
+        <frontend_label>
+            <store_id>1</store_id>
+            <label>bbb</label>
+        </frontend_label>
+    </attributeEntityToCreate>
+    <groupAdd>
+        <groupName>Test Group</groupName>
+        <existsGroupName>General</existsGroupName>
+    </groupAdd>
+    <relatedProduct>
+        <typeId>simple</typeId>
+        <sku>test_attribute_set_product</sku>
+        <productData>
+            <name>Test attribute set product</name>
+            <websites>1</websites>
+            <short_description>short description</short_description>
+            <description>description</description>
+            <price>222</price>
+            <weight>1</weight>
+            <status>1</status>
+            <visibility>4</visibility>
+            <tax_class_id>2</tax_class_id>
+            <stock_data>
+                <qty>100</qty>
+                <manage_stock>1</manage_stock>
+                <backorders>1</backorders>
+                <is_in_stock>1</is_in_stock>
+            </stock_data>
+        </productData>
+    </relatedProduct>
+</root>
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOption.xml b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOption.xml
new file mode 100644
index 00000000000..b4d8961fd3a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOption.xml
@@ -0,0 +1,147 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<root>
+    <store>default</store>
+    <customOptionsToAdd>
+        <field>
+            <title>Test custom option Text Field</title>
+            <type>field</type>
+            <is_require>1</is_require>
+            <additional_fields>
+                <price>10</price>
+                <price_type>fixed</price_type>
+                <sku>test_custom_option_field_sku</sku>
+                <max_characters>9</max_characters>
+            </additional_fields>
+        </field>
+        <date>
+            <title>Test custom option Date</title>
+            <type>date</type>
+            <is_require>0</is_require>
+            <sort_order>3</sort_order>
+            <additional_fields>
+                <price>10</price>
+                <price_type>percent</price_type>
+                <sku>test_custom_option_date_sku</sku>
+            </additional_fields>
+        </date>
+        <file>
+            <title>Test custom option File</title>
+            <type>file</type>
+            <additional_fields>
+                <price>10</price>
+                <price_type>percent</price_type>
+                <sku>test_custom_option_file_sku</sku>
+                <file_extension>jpg</file_extension>
+                <image_size_x>600</image_size_x>
+                <image_size_y>300</image_size_y>
+            </additional_fields>
+        </file>
+        <multiple>
+            <title>Test custom option Multiselect</title>
+            <type>multiple</type>
+            <is_require>1</is_require>
+            <additional_fields>
+                <title>Test custom option Multiselect Row_1</title>
+                <price>10</price>
+                <price_type>fixed</price_type>
+                <sku>test_custom_option_multiselect_sku_row_1</sku>
+            </additional_fields>
+            <additional_fields>
+                <title>Test custom option Multiselect Row_2</title>
+                <price>20</price>
+                <price_type>fixed</price_type>
+                <sku>test_custom_option_multiselect_sku_row_2</sku>
+                <sort_order>6</sort_order>
+            </additional_fields>
+        </multiple>
+        <checkbox>
+            <title>Test custom option Checkbox</title>
+            <type>checkbox</type>
+            <additional_fields>
+                <title>Test custom option Checkbox Row_1</title>
+                <price_type>fixed</price_type>
+            </additional_fields>
+        </checkbox>
+        <area>
+            <title>Test custom option Text Area</title>
+            <type>area</type>
+            <is_require>1</is_require>
+            <sort_order>10</sort_order>
+            <additional_fields>
+                <price>10</price>
+                <price_type>fixed</price_type>
+                <sku>test_custom_option_area_with_store_id_sku</sku>
+                <max_characters>7</max_characters>
+            </additional_fields>
+        </area>
+    </customOptionsToAdd>
+    <customOptionsToUpdate>
+        <field>
+            <title>Test custom option Text Field Updated</title>
+            <additional_fields>
+                <price>100</price>
+            </additional_fields>
+        </field>
+        <date>
+            <title>Test custom option Date Updated</title>
+            <sort_order>100</sort_order>
+            <additional_fields>
+                <sku>test_custom_option_date_sku_2</sku>
+            </additional_fields>
+        </date>
+        <area>
+            <title>Test custom option Text Area Updated</title>
+            <is_require>0</is_require>
+            <sort_order>20</sort_order>
+            <additional_fields>
+                <max_characters>20</max_characters>
+            </additional_fields>
+        </area>
+    </customOptionsToUpdate>
+    <fixtureProduct>
+        <sku>sku</sku>
+        <attribute_set_id>4</attribute_set_id>
+        <type_id>simple</type_id>
+        <name>Simple Product with Custom Options</name>
+        <description>Simple Product</description>
+        <short_description>Simple Product</short_description>
+        <weight>1</weight>
+        <status>1</status>
+        <visibility>1</visibility>
+        <price>100.00</price>
+        <tax_class_id>0</tax_class_id>
+        <meta_title>Simple Product</meta_title>
+        <meta_keyword>Simple Product</meta_keyword>
+        <meta_description>Simple Product</meta_description>
+        <stock_data>
+            <qty>100</qty>
+            <manage_stock>1</manage_stock>
+            <backorders>1</backorders>
+            <is_in_stock>1</is_in_stock>
+        </stock_data>
+    </fixtureProduct>
+</root>
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOptionTypes.xml b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOptionTypes.xml
new file mode 100644
index 00000000000..3c8461c576b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOptionTypes.xml
@@ -0,0 +1,69 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<root>
+    <customOptionTypes>
+        <types>
+            <label>Field</label>
+            <value>field</value>
+        </types>
+        <types>
+            <label>Area</label>
+            <value>area</value>
+        </types>
+        <types>
+            <label>File</label>
+            <value>file</value>
+        </types>
+        <types>
+            <label>Drop-down</label>
+            <value>drop_down</value>
+        </types>
+        <types>
+            <label>Radio Buttons</label>
+            <value>radio</value>
+        </types>
+        <types>
+            <label>Checkbox</label>
+            <value>checkbox</value>
+        </types>
+        <types>
+            <label>Multiple Select</label>
+            <value>multiple</value>
+        </types>
+        <types>
+            <label>Date</label>
+            <value>date</value>
+        </types>
+        <types>
+            <label>Date &amp; Time</label>
+            <value>date_time</value>
+        </types>
+        <types>
+            <label>Time</label>
+            <value>time</value>
+        </types>
+    </customOptionTypes>
+</root>
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOptionValue.xml b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOptionValue.xml
new file mode 100644
index 00000000000..30b854f93b8
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/CustomOptionValue.xml
@@ -0,0 +1,86 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<root>
+    <store>default</store>
+    <customOptionValues>
+        <value_1>
+            <title>Test custom option value</title>
+            <price>50.00</price>
+            <price_type>fixed</price_type>
+            <sku>test_custom_option_value_sku</sku>
+            <sort_order>0</sort_order>
+        </value_1>
+    </customOptionValues>
+    <customOptionValuesToUpdate>
+        <value_1>
+            <title>Updated test custom option value</title>
+            <price>1000.00</price>
+            <price_type>fixed</price_type>
+            <sku>test_custom_option_value_sku_2222</sku>
+            <sort_order>10</sort_order>
+        </value_1>
+    </customOptionValuesToUpdate>
+    <fixtureCustomOption>
+        <title>Test custom option Multiselect</title>
+        <type>multiple</type>
+        <is_require>1</is_require>
+        <additional_fields>
+            <title>Test custom option Multiselect Row_1</title>
+            <price>10</price>
+            <price_type>fixed</price_type>
+            <sku>test_custom_option_multiselect_sku_row_1</sku>
+        </additional_fields>
+        <additional_fields>
+            <title>Test custom option Multiselect Row_2</title>
+            <price>20</price>
+            <price_type>fixed</price_type>
+            <sku>test_custom_option_multiselect_sku_row_2</sku>
+            <sort_order>6</sort_order>
+        </additional_fields>
+    </fixtureCustomOption>
+    <fixtureProduct>
+        <sku>sku</sku>
+        <attribute_set_id>4</attribute_set_id>
+        <type_id>simple</type_id>
+        <name>Simple Product with Custom Options</name>
+        <description>Simple Product</description>
+        <short_description>Simple Product</short_description>
+        <weight>1</weight>
+        <status>1</status>
+        <visibility>1</visibility>
+        <price>100.00</price>
+        <tax_class_id>0</tax_class_id>
+        <meta_title>Simple Product</meta_title>
+        <meta_keyword>Simple Product</meta_keyword>
+        <meta_description>Simple Product</meta_description>
+        <stock_data>
+            <qty>100</qty>
+            <manage_stock>1</manage_stock>
+            <backorders>1</backorders>
+            <is_in_stock>1</is_in_stock>
+        </stock_data>
+    </fixtureProduct>
+</root>
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/LinkCRUD.xml b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/LinkCRUD.xml
new file mode 100644
index 00000000000..7ea2bb2b332
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/LinkCRUD.xml
@@ -0,0 +1,134 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<root>
+    <product_id>qwe_downloadable_qwe</product_id>
+    <items>
+        <small>
+            <link>
+                <title>Test file</title>
+                <price>123</price>
+                <is_unlimited>1</is_unlimited>
+                <number_of_downloads>111</number_of_downloads>
+                <is_shareable>0</is_shareable>
+                <sample>
+                    <type>file</type>
+                    <file>
+                        <filename>test.txt</filename>
+                    </file>
+                    <url>http://www.magentocommerce.com/img/logo.gif</url>
+                </sample>
+                <type>file</type>
+                <file>
+                    <filename>test.txt</filename>
+                </file>
+                <link_url>http://www.magentocommerce.com/img/logo.gif</link_url>
+            </link>
+            <sample>
+                <title>Test sample file</title>
+                <type>file</type>
+                <file>
+                    <filename>image.jpg</filename>
+                </file>
+                <sample_url>http://www.magentocommerce.com/img/logo.gif</sample_url>
+                <sort_order>3</sort_order>
+            </sample>
+        </small>
+        <big>
+            <link>
+                <title>Test url</title>
+                <price>123</price>
+                <is_unlimited>0</is_unlimited>
+                <number_of_downloads>111</number_of_downloads>
+                <is_shareable>1</is_shareable>
+                <sample>
+                    <type>url</type>
+                    <file>
+                        <filename>book.pdf</filename>
+                    </file>
+                    <url>http://www.magentocommerce.com/img/logo.gif</url>
+                </sample>
+                <type>url</type>
+                <file>
+                    <filename>song.mp3</filename>
+                </file>
+                <link_url>http://www.magentocommerce.com/img/logo.gif</link_url>
+            </link>
+            <sample>
+                <title>Test sample url</title>
+                <type>url</type>
+                <file>
+                    <filename>image.jpg</filename>
+                </file>
+                <sample_url>http://www.magentocommerce.com/img/logo.gif</sample_url>
+                <sort_order>3</sort_order>
+            </sample>
+        </big>
+    </items>
+    <customer>
+        <created_at>2010-01-01 01:01:01</created_at>
+        <store_id>1</store_id>
+        <website_id>1</website_id>
+        <confirmation></confirmation>
+        <created_in>Default Store View</created_in>
+        <default_billing>1</default_billing>
+        <default_shipping>1</default_shipping>
+        <dob></dob>
+        <email>mr.test@test.com</email>
+        <gender></gender>
+        <firstname>Test</firstname>
+        <lastname>Test</lastname>
+        <middlename>Test</middlename>
+        <group_id>1</group_id>
+        <password_hash>a8b291d2f4aaf60d138d3e7ee0c20b1b48e48395cea59ed0c94de6b139a0cd86:4M</password_hash>
+        <prefix></prefix>
+        <reward_update_notification>1</reward_update_notification>
+        <reward_warning_notification>1</reward_warning_notification>
+        <suffix></suffix>
+        <taxvat></taxvat>
+    </customer>
+    <product>
+        <sku>sku_downloadable</sku>
+        <attribute_set_id>4</attribute_set_id>
+        <type_id>downloadable</type_id>
+        <name>Downloadable Product</name>
+        <description>Downloadable Product</description>
+        <short_description>Downloadable Product</short_description>
+        <weight>1</weight>
+        <status>1</status>
+        <visibility>1</visibility>
+        <price>100.00</price>
+        <tax_class_id>0</tax_class_id>
+        <meta_title>Downloadable Product</meta_title>
+        <meta_keyword>Downloadable Product</meta_keyword>
+        <meta_description>Downloadable Product</meta_description>
+        <stock_data>
+            <qty>100</qty>
+            <manage_stock>1</manage_stock>
+            <backorders>1</backorders>
+            <is_in_stock>1</is_in_stock>
+        </stock_data>
+    </product>
+</root>
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/TagCRUD.xml b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/TagCRUD.xml
new file mode 100644
index 00000000000..fb82f993d4a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/xml/TagCRUD.xml
@@ -0,0 +1,80 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<root>
+    <tagData>
+        <product_id></product_id>
+        <customer_id></customer_id>
+        <store>1</store>
+        <tag>First 'Second tag' Third</tag>
+    </tagData>
+    <customer>
+        <created_at>2010-01-01 01:01:01</created_at>
+        <store_id>1</store_id>
+        <website_id>1</website_id>
+        <confirmation></confirmation>
+        <created_in>Default Store View</created_in>
+        <default_billing>1</default_billing>
+        <default_shipping>1</default_shipping>
+        <dob></dob>
+        <email>mr.test@test.com</email>
+        <gender></gender>
+        <firstname>Test</firstname>
+        <lastname>Test</lastname>
+        <middlename>Test</middlename>
+        <group_id>1</group_id>
+        <password_hash>a8b291d2f4aaf60d138d3e7ee0c20b1b48e48395cea59ed0c94de6b139a0cd86:4M</password_hash>
+        <prefix></prefix>
+        <reward_update_notification>1</reward_update_notification>
+        <reward_warning_notification>1</reward_warning_notification>
+        <suffix></suffix>
+        <taxvat></taxvat>
+    </customer>
+    <product>
+        <sku>sku</sku>
+        <attribute_set_id>4</attribute_set_id>
+        <type_id>simple</type_id>
+        <name>Simple Product</name>
+        <description>Simple Product</description>
+        <short_description>Simple Product</short_description>
+        <weight>1</weight>
+        <status>1</status>
+        <visibility>1</visibility>
+        <price>100.00</price>
+        <tax_class_id>0</tax_class_id>
+        <meta_title>Simple Product</meta_title>
+        <meta_keyword>Simple Product</meta_keyword>
+        <meta_description>Simple Product</meta_description>
+        <stock_data>
+            <qty>100</qty>
+            <manage_stock>1</manage_stock>
+            <backorders>1</backorders>
+            <is_in_stock>1</is_in_stock>
+        </stock_data>
+    </product>
+    <expected>
+        <created_tags_count>3</created_tags_count>
+    </expected>
+</root>
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/attribute_set_with_configurable.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/attribute_set_with_configurable.php
new file mode 100644
index 00000000000..af79574338f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/attribute_set_with_configurable.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+if (!Mage::registry('attribute_set_with_configurable')) {
+    define('ATTRIBUTES_COUNT', 2);
+    define('ATTRIBUTE_OPTIONS_COUNT', 3);
+
+    /** @var $entityType Mage_Eav_Model_Entity_Type */
+    $entityType = Mage::getModel('Mage_Eav_Model_Entity_Type')->loadByCode('catalog_product');
+
+    /** @var $attributeSet Mage_Eav_Model_Entity_Attribute_Set */
+    $attributeSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set');
+    $attributeSet->setEntityTypeId($entityType->getEntityTypeId())
+        ->setAttributeSetName('Test Attribute Set ' . uniqid());
+
+    $attributeSet->save();
+    /** @var $entityType Mage_Eav_Model_Entity_Type */
+    $entityType = Mage::getModel('Mage_Eav_Model_Entity_Type')->loadByCode('catalog_product');
+    $attributeSet->initFromSkeleton($entityType->getDefaultAttributeSetId())->save();
+    Mage::register('attribute_set_with_configurable', $attributeSet);
+
+    /** @var $attributeFixture Mage_Catalog_Model_Resource_Eav_Attribute */
+    $attributeFixture = Mage::getModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+
+    $attributeFixture->setEntityTypeId(Mage::getModel('Mage_Eav_Model_Entity')->setType('catalog_product')->getTypeId())
+        ->setAttributeCode('test_attr_' . uniqid())
+        ->setIsUserDefined(true)
+        ->setIsVisibleOnFront(false)
+        ->setIsRequired(false)
+        ->setFrontendLabel(array(0 => 'Test Attr ' . uniqid()))
+        ->setApplyTo(array());
+
+    for ($attributeCount = 1; $attributeCount <= ATTRIBUTES_COUNT; $attributeCount++) {
+        $attribute = clone $attributeFixture;
+        $attribute->setAttributeCode('test_attr_' . uniqid())
+            ->setFrontendLabel(array(0 => 'Test Attr ' . uniqid()))
+            ->setIsGlobal(true)
+            ->setIsConfigurable(true)
+            ->setIsRequired(true)
+            ->setFrontendInput('select')
+            ->setBackendType('int')
+            ->setAttributeSetId($attributeSet->getId())
+            ->setAttributeGroupId($attributeSet->getDefaultGroupId());
+
+        $options = array();
+        for ($optionCount = 0; $optionCount < ATTRIBUTE_OPTIONS_COUNT; $optionCount++) {
+            $options['option_' . $optionCount] = array(
+                0 => 'Test Option #' . $optionCount
+            );
+        }
+        $attribute->setOption(
+            array(
+                'value' => $options
+            )
+        );
+        $attribute->save();
+        Mage::register('eav_configurable_attribute_' . $attributeCount, $attribute);
+        unset($attribute);
+    }
+}
+
+
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/store_on_new_website.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/store_on_new_website.php
new file mode 100644
index 00000000000..00bcf6de816
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/store_on_new_website.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+if (!Mage::registry('website')) {
+    $website = Mage::getModel('Mage_Core_Model_Website');
+    $website->setData(
+        array(
+            'code' => 'test_' . uniqid(),
+            'name' => 'test website',
+            'default_group_id' => 1,
+        )
+    );
+    $website->save();
+    Mage::register('website', $website);
+}
+
+if (!Mage::registry('store_group')) {
+    $defaultCategoryId = 2;
+    $storeGroup = Mage::getModel('Mage_Core_Model_Store_Group');
+    $storeGroup->setData(
+        array(
+            'website_id' => Mage::registry('website')->getId(),
+            'name' => 'Test Store' . uniqid(),
+            'code' => 'store_group_' . uniqid(),
+            'root_category_id' => $defaultCategoryId
+        )
+    )->save();
+    Mage::register('store_group', $storeGroup);
+}
+
+if (!Mage::registry('store_on_new_website')) {
+    $store = Mage::getModel('Mage_Core_Model_Store');
+    $store->setData(
+        array(
+            'group_id' => Mage::registry('store_group')->getId(),
+            'name' => 'Test Store View',
+            'code' => 'store_' . uniqid(),
+            'is_active' => true,
+            'website_id' => Mage::registry('website')->getId()
+        )
+    )->save();
+    Mage::register('store_on_new_website', $store);
+    Mage::app()->reinitStores();
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/store_on_new_website_rollback.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/store_on_new_website_rollback.php
new file mode 100644
index 00000000000..a6b4c2c5801
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/store_on_new_website_rollback.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('website');
+Mage::unregister('store_group');
+Mage::unregister('store_on_new_website');
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/ApiTest.php
new file mode 100644
index 00000000000..04a67f94663
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/ApiTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Product API tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Catalog_Model_Product_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @magentoDataFixture Mage/Catalog/_files/product_special_price.php
+     */
+    public function testGetSpecialPrice()
+    {
+        /** Retrieve the product data. */
+        $productId = 1;
+        $actualProductData = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductGetSpecialPrice',
+            array('productId' => $productId)
+        );
+        /** Assert returned product data. */
+        $this->assertNotEmpty($actualProductData, 'Missing special price response data.');
+
+        /** @var Mage_Catalog_Model_Product $expectedProduct */
+        $expectedProduct = Mage::getModel('Mage_Catalog_Model_Product');
+        $expectedProduct->load($productId);
+        $fieldsToCompare = array(
+            'entity_id' => 'product_id',
+            'sku',
+            'attribute_set_id' => 'set',
+            'type_id' => 'type',
+            'category_ids' => 'categories',
+            'special_price'
+        );
+        /** Assert response product equals to actual product data. */
+        Magento_Test_Helper_Api::checkEntityFields(
+            $this,
+            $expectedProduct->getData(),
+            $actualProductData,
+            $fieldsToCompare
+        );
+    }
+
+    /**
+     * @magentoDataFixture Mage/Catalog/_files/multiple_products.php
+     */
+    public function testItems()
+    {
+        /** Retrieve the list of products. */
+        $actualProductsData = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductList'
+        );
+        /** Assert that products quantity equals to 3. */
+        $this->assertCount(3, $actualProductsData, 'Products quantity is invalid.');
+
+        /** Loading expected product from fixture. */
+        $expectedProduct = Mage::getModel('Mage_Catalog_Model_Product');
+        $expectedProduct->load(10);
+        $fieldsToCompare = array(
+            'entity_id' => 'product_id',
+            'sku',
+            'attribute_set_id' => 'set',
+            'type_id' => 'type',
+            'category_ids',
+        );
+        /** Assert first product from response equals to actual product data. */
+        Magento_Test_Helper_Api::checkEntityFields(
+            $this,
+            $expectedProduct->getData(),
+            reset($actualProductsData),
+            $fieldsToCompare
+        );
+    }
+
+    /**
+     * Test retrieving the list of attributes which are not in default create/update list via API.
+     */
+    public function testGetAdditionalAttributes()
+    {
+        $attributesList = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductListOfAdditionalAttributes',
+            array('simple', 4)
+        );
+        $this->assertGreaterThan(20, count($attributesList), "Attributes quantity seems to be incorrect.");
+        $oldIdAttributeData = reset($attributesList);
+        $oldIdExpectedData = array(
+            'attribute_id' => '89',
+            'code' => 'old_id',
+            'type' => 'text',
+            'required' => '0',
+            'scope' => 'global'
+        );
+        $this->assertEquals($oldIdExpectedData, $oldIdAttributeData, "Attribute data from the list is incorrect.");
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/ApiTest.php
new file mode 100644
index 00000000000..996e4cd2f34
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/ApiTest.php
@@ -0,0 +1,343 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_Catalog
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 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 Mage_Catalog_Model_Product_Attribute_Api.
+ */
+class Mage_Catalog_Model_Product_Attribute_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Catalog_Model_Product_Attribute_Api
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $this->_model = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Api');
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public function testItems()
+    {
+        $items = $this->_model->items(4); /* default product attribute set after installation */
+        $this->assertInternalType('array', $items);
+        $element = current($items);
+        $this->assertArrayHasKey('attribute_id', $element);
+        $this->assertArrayHasKey('code', $element);
+        $this->assertArrayHasKey('type', $element);
+        $this->assertArrayHasKey('required', $element);
+        $this->assertArrayHasKey('scope', $element);
+        foreach ($items as $item) {
+            if ($item['code'] == 'status') {
+                return $item['attribute_id'];
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @depends testItems
+     */
+    public function testOptions($attributeId)
+    {
+        if (!$attributeId) {
+            $this->fail('Invalid attribute ID.');
+        }
+        $options = $this->_model->options($attributeId);
+        $this->assertInternalType('array', $options);
+        $element = current($options);
+        $this->assertArrayHasKey('value', $element);
+        $this->assertArrayHasKey('label', $element);
+    }
+
+    /**
+     * Test types method
+     */
+    public function testTypes()
+    {
+        $expectedTypes = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Source_Inputtype')->toOptionArray();
+        $types = Magento_Test_Helper_Api::call($this, 'catalogProductAttributeTypes');
+        $this->assertEquals($expectedTypes, $types);
+    }
+
+    /**
+     * Test attribute creation.
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testCreate()
+    {
+        $attributeCode = "test_attribute";
+        $dataToCreate = array(
+            "attribute_code" => $attributeCode,
+            "frontend_input" => "text",
+            "scope" => "store",
+            "default_value" => "1",
+            "is_unique" => 0,
+            "is_required" => 0,
+            "apply_to" => array("simple"),
+            "is_configurable" => 0,
+            "is_searchable" => 0,
+            "is_visible_in_advanced_search" => 0,
+            "is_comparable" => 0,
+            "is_used_for_promo_rules" => 0,
+            "is_visible_on_front" => 0,
+            "used_in_product_listing" => 0,
+            "frontend_label" => array(
+                array(
+                    "store_id" => "0",
+                    "label" => "some label",
+                )
+            )
+        );
+        $attributeId = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeCreate',
+            array(
+                'data' => (object)$dataToCreate
+            )
+        );
+        $this->assertGreaterThan(0, $attributeId, 'Attribute create was not successful.');
+
+        $this->_verifyAttribute($attributeCode, $dataToCreate);
+    }
+
+    /**
+     * Test attribute update.
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php
+     */
+    public function testUpdate()
+    {
+        $attributeCode = 'select_attribute';
+        $dataToUpdate = array(
+            "scope" => "global",
+            "default_value" => "2",
+            "is_unique" => 1,
+            "is_required" => 1,
+            "apply_to" => array("simple", "configurable"),
+            "is_configurable" => 1,
+            "is_searchable" => 1,
+            "is_visible_in_advanced_search" => 1,
+            "is_comparable" => 1,
+            "is_visible_on_front" => 1,
+            "used_in_product_listing" => 1,
+            "frontend_label" => array(
+                array(
+                    "store_id" => "0",
+                    "label" => "Label Updated"
+                )
+            )
+        );
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeUpdate',
+            array(
+                'attribute' => $attributeCode,
+                'data' => (object)$dataToUpdate,
+            )
+        );
+        $this->assertTrue($result, 'Attribute update was not successful.');
+
+        $this->_verifyAttribute($attributeCode, $dataToUpdate);
+    }
+
+    /**
+     * Test attribute info.
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php
+     */
+    public function testInfo()
+    {
+        $attributeCode = 'select_attribute';
+        $attributeInfo = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeInfo',
+            array(
+                'attribute' => $attributeCode,
+            )
+        );
+        $this->assertNotEmpty($attributeInfo, 'Attribute info was not retrieved.');
+
+        $fieldsToCompare = array(
+            'attribute_id',
+            'attribute_code',
+            'frontend_input',
+            'is_unique',
+            'is_required',
+            'is_configurable',
+            'is_searchable',
+            'is_visible_in_advanced_search',
+            'is_comparable',
+            'is_used_for_promo_rules',
+            'is_visible_on_front',
+            'used_in_product_listing',
+        );
+        $this->_verifyAttribute($attributeCode, $attributeInfo, $fieldsToCompare);
+    }
+
+    /**
+     * Verify given attribute data.
+     *
+     * @param string $attributeCode
+     * @param array $actualData
+     * @param array $fieldsToCompare
+     */
+    protected function _verifyAttribute($attributeCode, array $actualData, array $fieldsToCompare = array())
+    {
+        /** @var Mage_Catalog_Model_Resource_Eav_Attribute $expectedAttribute */
+        $expectedAttribute = Mage::getResourceModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+        $expectedAttribute->loadByCode('catalog_product', $attributeCode);
+        $expectedIsGlobal = $actualData['scope'] == 'global' ? 1 : 0;
+        $this->assertEquals($expectedIsGlobal, $expectedAttribute->getIsGlobal(), 'Attribute scope is incorrect.');
+        $this->assertEquals(
+            $expectedAttribute->getApplyTo(),
+            $actualData['apply_to'],
+            'Attribute "Apply To" is incorrect.'
+        );
+
+        $frontendLabels = $actualData['frontend_label'];
+        $frontendLabel = reset($frontendLabels);
+        $this->assertEquals(
+            $expectedAttribute->getFrontendLabel(),
+            $frontendLabel['label'],
+            'Attribute fronted label is incorrect.'
+        );
+        unset($actualData['scope']);
+        unset($actualData['apply_to']);
+        unset($actualData['frontend_label']);
+        if (empty($fieldsToCompare)) {
+            $fieldsToCompare = array_keys($actualData);
+        }
+
+        Magento_Test_Helper_Api::checkEntityFields(
+            $this,
+            $expectedAttribute->getData(),
+            $actualData,
+            $fieldsToCompare
+        );
+    }
+
+    /**
+     * Test attribute removal.
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php
+     */
+    public function testRemove()
+    {
+        $attributeCode = 'select_attribute';
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeRemove',
+            array(
+                'attribute' => $attributeCode,
+            )
+        );
+        $this->assertTrue($result, 'Attribute was not removed.');
+
+        // Verify that attribute was deleted
+        /** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
+        $attribute = Mage::getResourceModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+        $attribute->loadByCode('catalog_product', $attributeCode);
+        $this->assertNull($attribute->getId(), 'Attribute was not deleted from storage.');
+    }
+
+    /**
+     * Test adding an option to an attribute.
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php
+     */
+    public function testAddOption()
+    {
+        $attributeCode = 'select_attribute';
+        $optionLabel = "Option Label";
+
+        $data = (object)array(
+            "label" => array(
+                (object)array(
+                    "store_id" => array("0"),
+                    "value" => $optionLabel
+                )
+            ),
+            "order" => "10",
+            "is_default" => "1"
+        );
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeAddOption',
+            array(
+                'attribute' => $attributeCode,
+                'data' => $data,
+            )
+        );
+        $this->assertTrue($result, 'Attribute option was not added.');
+        /** @var Mage_Catalog_Model_Resource_Eav_Attribute $expectedAttribute */
+        $expectedAttribute = Mage::getModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+        $expectedAttribute->loadByCode('catalog_product', $attributeCode);
+        $options = $expectedAttribute->getSource()->getAllOptions();
+        $this->assertCount(3, $options, 'Exactly 3 options should be in attribute.');
+        $option = end($options);
+        $this->assertEquals($optionLabel, $option['label'], 'Incorrect option label saved.');
+    }
+
+    /**
+     * Test removing an option from an attribute.
+     *
+     * @magentoDataFixture Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php
+     */
+    public function testRemoveOption()
+    {
+        $attributeCode = 'select_attribute';
+        /** @var Mage_Catalog_Model_Resource_Eav_Attribute $attribute */
+        $attribute = Mage::getModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+        $attribute->loadByCode('catalog_product', $attributeCode);
+        $options = $attribute->getSource()->getAllOptions();
+        $this->assertCount(2, $options, 'Incorrect options count in fixture.');
+        $optionToDelete = end($options);
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductAttributeRemoveOption',
+            array(
+                'attribute' => $attributeCode,
+                'optionId' => $optionToDelete['value'],
+            )
+        );
+        $this->assertTrue($result, 'Attribute option was not removed.');
+        // Verify option was removed from storage.
+        /** @var Mage_Catalog_Model_Resource_Eav_Attribute $attrAfterRemove */
+        $attrAfterRemove = Mage::getModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+        $attrAfterRemove->loadByCode('catalog_product', $attributeCode);
+        $optionsAfterRemove = $attrAfterRemove->getSource()->getAllOptions();
+        $this->assertCount(1, $optionsAfterRemove, 'Attribute option was not removed from storage.');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
index 9f405eecb96..e07a5d69221 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
@@ -52,11 +52,12 @@ class Mage_Catalog_Model_Product_Attribute_Backend_MediaTest extends PHPUnit_Fra
         $fixtureDir = realpath(dirname(__FILE__).'/../../../../_files');
         self::$_mediaDir = Mage::getSingleton('Mage_Catalog_Model_Product_Media_Config')->getBaseMediaPath();
 
+        $ioFile = new Varien_Io_File();
         if (!is_dir(self::$_mediaTmpDir)) {
-            mkdir(self::$_mediaTmpDir, 0777, true);
+            $ioFile->mkdir(self::$_mediaTmpDir, 0777, true);
         }
         if (!is_dir(self::$_mediaDir)) {
-            mkdir(self::$_mediaDir, 0777, true);
+            $ioFile->mkdir(self::$_mediaDir, 0777, true);
         }
 
         copy($fixtureDir . "/magento_image.jpg", self::$_mediaTmpDir . "/magento_image.jpg");
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Media/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Media/ApiTest.php
new file mode 100644
index 00000000000..10dc22865f0
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Media/ApiTest.php
@@ -0,0 +1,176 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_Catalog
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 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 Mage_Catalog_Model_Product_Attribute_Media_Api.
+ *
+ * @magentoDataFixture Mage/Catalog/_files/product_simple.php
+ * @magentoDataFixture productMediaFixture
+ */
+class Mage_Catalog_Model_Product_Attribute_Media_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Catalog_Model_Product_Attribute_Media_Api
+     */
+    protected $_model;
+
+    /**
+     * @var string
+     */
+    protected static $_filesDir;
+
+    /**
+     * @var string
+     */
+    protected static $_mediaTmpDir;
+
+    protected function setUp()
+    {
+        $this->_model = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Media_Api');
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public static function setUpBeforeClass()
+    {
+        self::$_filesDir = realpath(__DIR__ . '/../../../../_files');
+        self::$_mediaTmpDir = Mage::getSingleton('Mage_Catalog_Model_Product_Media_Config')->getBaseTmpMediaPath();
+        $ioFile = new Varien_Io_File();
+        $ioFile->mkdir(self::$_mediaTmpDir . "/m/a", 0777, true);
+        copy(self::$_filesDir . '/magento_image.jpg', self::$_mediaTmpDir . '/m/a/magento_image.jpg');
+    }
+
+    public static function tearDownAfterClass()
+    {
+        Varien_Io_File::rmdirRecursive(self::$_mediaTmpDir . "/m/a");
+        /** @var $config Mage_Catalog_Model_Product_Media_Config */
+        $config = Mage::getSingleton('Mage_Catalog_Model_Product_Media_Config');
+        Varien_Io_File::rmdirRecursive($config->getBaseMediaPath());
+    }
+
+    public static function productMediaFixture()
+    {
+        /** @var $product Mage_Catalog_Model_Product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load(1);
+        $product->setTierPrice(array());
+        $product->setData('media_gallery', array('images' => array(array('file' => '/m/a/magento_image.jpg',),)));
+        $product->save();
+    }
+
+    /**
+     * @covers Mage_Catalog_Model_Product_Attribute_Media_Api::items
+     * @covers Mage_Catalog_Model_Product_Attribute_Media_Api::info
+     */
+    public function testItemsAndInfo()
+    {
+        $items = $this->_model->items(1);
+        $this->assertNotEmpty($items);
+        $this->assertEquals(1, count($items));
+        $item = current($items);
+        $this->assertArrayHasKey('file', $item);
+        $this->assertArrayHasKey('label', $item);;
+        $this->assertArrayHasKey('url', $item);
+
+        $info = $this->_model->info(1, $item['file']);
+        $this->assertArrayHasKey('file', $info);
+        $this->assertArrayHasKey('label', $info);;
+        $this->assertArrayHasKey('url', $info);
+        return $item['file'];
+    }
+
+    /**
+     * @depends testItemsAndInfo
+     */
+    public function testCreate()
+    {
+        $data = array(
+            'file' => array(
+                'mime'      => 'image/jpeg',
+                'content'   => base64_encode(file_get_contents(self::$_filesDir.'/magento_small_image.jpg'))
+            )
+        );
+        $this->_model->create(1, $data);
+        $items = $this->_model->items(1);
+        $this->assertEquals(2, count($items));
+    }
+
+    public function createFaultDataProvider()
+    {
+        return array(
+            array('floor' => 'ceiling'),
+            array('file' => array('mime' => 'test')),
+            array('file' => array('mime' => 'image/jpeg', 'content' => 'not valid'))
+        );
+    }
+
+    /**
+     * @dataProvider createFaultDataProvider
+     * @expectedException Mage_Api_Exception
+     */
+    public function testCreateFault($data)
+    {
+        $this->_model->create(1, $data);
+    }
+
+    /**
+     * @depends testItemsAndInfo
+     */
+    public function testUpdate($file)
+    {
+        $data = array(
+            'file' => array(
+                'mime'      => 'image/jpeg',
+                'content'   => base64_encode(file_get_contents(self::$_filesDir.'/magento_small_image.jpg'))
+            )
+        );
+        $this->assertTrue($this->_model->update(1, $file, $data));
+    }
+
+    /**
+     * @depends testItemsAndInfo
+     * @expectedException Mage_Api_Exception
+     */
+    public function testRemove($file)
+    {
+        $this->assertTrue($this->_model->remove(1, $file));
+        $this->_model->info(1, $file);
+    }
+
+    public function testTypes()
+    {
+        $types = $this->_model->types(4);
+        $this->assertNotEmpty($types);
+        $this->assertInternalType('array', $types);
+        $type = current($types);
+        $this->assertArrayHasKey('code', $type);
+        $this->assertArrayHasKey('scope', $type);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2Test.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2Test.php
new file mode 100644
index 00000000000..fbcc8b53921
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/Api/V2Test.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.
+ *
+ * @category    Magento
+ * @package     Magento_Catalog
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 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 Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2.
+ */
+class Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2Test extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $this->_model = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Tierprice_Api_V2');
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    /**
+     * @expectedException Mage_Api_Exception
+     */
+    public function testPrepareTierPricesInvalidData()
+    {
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $this->_model->prepareTierPrices($product, array(1));
+    }
+
+    public function testPrepareTierPricesInvalidWebsite()
+    {
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $data = $this->_model->prepareTierPrices(
+            $product,
+            array((object) array('qty' => 3, 'price' => 8, 'website' => 100))
+        );
+        $this->assertEquals(
+            array(array('website_id' => 0, 'cust_group' => 32000, 'price_qty' => 3, 'price' => 8)),
+            $data
+        );
+    }
+
+    public function testPrepareTierPrices()
+    {
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+
+        $this->assertNull($this->_model->prepareTierPrices($product));
+
+        $data = $this->_model->prepareTierPrices($product,
+            array((object) array('qty' => 3, 'price' => 8))
+        );
+        $this->assertEquals(
+            array(array('website_id' => 0, 'cust_group' => 32000, 'price_qty' => 3, 'price' => 8)),
+            $data
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/ApiTest.php
new file mode 100644
index 00000000000..3bf9a21046f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/Tierprice/ApiTest.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.
+ *
+ * @category    Magento
+ * @package     Magento_Catalog
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 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 Mage_Catalog_Model_Product_Attribute_Tierprice_Api
+ *
+ * @magentoDataFixture Mage/Catalog/_files/product_simple.php
+ */
+class Mage_Catalog_Model_Product_Attribute_Tierprice_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Mage_Catalog_Model_Product_Attribute_Tierprice_Api
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $this->_model = Mage::getModel('Mage_Catalog_Model_Product_Attribute_Tierprice_Api');
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public function testInfo()
+    {
+        $info = $this->_model->info(1);
+        $this->assertInternalType('array', $info);
+        $this->assertEquals(2, count($info));
+        $element = current($info);
+        $this->assertArrayHasKey('customer_group_id', $element);
+        $this->assertArrayHasKey('website', $element);
+        $this->assertArrayHasKey('qty', $element);
+        $this->assertArrayHasKey('price', $element);
+    }
+
+    public function testUpdate()
+    {
+        Mage::app()->setCurrentStore(Mage::app()->getStore(Mage_Core_Model_App::ADMIN_STORE_ID));
+        $this->_model->update(1, array(array('qty' => 3, 'price' => 8)));
+        $info = $this->_model->info(1);
+        $this->assertEquals(1, count($info));
+    }
+
+    /**
+     * @expectedException Mage_Api_Exception
+     */
+    public function testPrepareTierPricesInvalidData()
+    {
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $this->_model->prepareTierPrices($product, array(1));
+    }
+
+    public function testPrepareTierPricesInvalidWebsite()
+    {
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $data = $this->_model->prepareTierPrices($product, array(array('qty' => 3, 'price' => 8, 'website' => 100)));
+        $this->assertEquals(
+            array(array('website_id' => 0, 'cust_group' => 32000, 'price_qty' => 3, 'price' => 8)),
+            $data
+        );
+    }
+
+    public function testPrepareTierPrices()
+    {
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+
+        $this->assertNull($this->_model->prepareTierPrices($product));
+
+        $data = $this->_model->prepareTierPrices($product,
+            array(array('qty' => 3, 'price' => 8))
+        );
+        $this->assertEquals(
+            array(array('website_id' => 0, 'cust_group' => 32000, 'price_qty' => 3, 'price' => 8)),
+            $data
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php
new file mode 100644
index 00000000000..e02ee451fb4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Attribute/_files/select_attribute.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * "dropdown" fixture of product EAV attribute.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var Mage_Eav_Model_Entity_Type $entityType */
+$entityType = Mage::getModel('Mage_Eav_Model_Entity_Type');
+$entityType->loadByCode('catalog_product');
+$defaultSetId = $entityType->getDefaultAttributeSetId();
+/** @var Mage_Eav_Model_Entity_Attribute_Set $defaultSet */
+$defaultSet = Mage::getModel('Mage_Eav_Model_Entity_Attribute_Set');
+$defaultSet->load($defaultSetId);
+$defaultGroupId = $defaultSet->getDefaultGroupId();
+$optionData = array(
+    'value' => array(
+        'option_1' => array(0 => 'Fixture Option'),
+    ),
+    'order' => array(
+        'option_1' => 1,
+    )
+);
+
+/** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
+$attribute = Mage::getResourceModel('Mage_Catalog_Model_Resource_Eav_Attribute');
+$attribute->setAttributeCode('select_attribute')
+    ->setEntityTypeId($entityType->getEntityTypeId())
+    ->setAttributeGroupId($defaultGroupId)
+    ->setAttributeSetId($defaultSetId)
+    ->setFrontendInput('select')
+    ->setFrontendLabel('Select Attribute')
+    ->setBackendType('int')
+    ->setIsUserDefined(1)
+    ->setOption($optionData)
+    ->save();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Link/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Link/ApiTest.php
new file mode 100644
index 00000000000..749d2262ea3
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Link/ApiTest.php
@@ -0,0 +1,208 @@
+<?php
+/**
+ * Catalog product link API test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Catalog/_files/multiple_products.php
+ */
+class Mage_Catalog_Model_Product_Link_ApiTest extends PHPUnit_Framework_TestCase
+{
+    const LINK_TYPE_UP_SELL = 'up_sell';
+    const LINK_TYPE_RELATED = 'related';
+
+    protected $_mainProductId = 10;
+    protected $_upSellProductId = 11;
+    protected $_relatedProductId = 12;
+
+    /**
+     * Test 'types' method of catalog product link API.
+     */
+    public function testTypes()
+    {
+        /** Add up-sell and related products. */
+        $types = Magento_Test_Helper_Api::call($this, 'catalogProductLinkTypes');
+        $expectedTypes = array('related', 'up_sell', 'cross_sell', 'grouped');
+        $this->assertEquals($expectedTypes, $types);
+    }
+
+    /**
+     * Test 'attributes' method of catalog product link API.
+     */
+    public function testAttributes()
+    {
+        $attributes = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductLinkAttributes',
+            array(self::LINK_TYPE_UP_SELL)
+        );
+        $this->assertEquals(
+            array(array('code' => 'position', 'type' => 'int')),
+            $attributes,
+            "Attributes list is invalid."
+        );
+    }
+
+    /**
+     * Test 'assign' method of catalog product link API.
+     */
+    public function testAssign()
+    {
+        /** Add up-sell and related products. */
+        $upSellResult = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductLinkAssign',
+            array(
+                self::LINK_TYPE_UP_SELL,
+                $this->_mainProductId,
+                $this->_upSellProductId
+            )
+        );
+        $this->assertTrue($upSellResult, "Up-sell link creation was unsuccessful.");
+        $relatedResult = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductLinkAssign',
+            array(
+                self::LINK_TYPE_RELATED,
+                $this->_mainProductId,
+                $this->_relatedProductId
+            )
+        );
+        $this->assertTrue($relatedResult, "Related link creation was unsuccessful.");
+        /** @var Mage_Catalog_Model_Product $product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($this->_mainProductId);
+
+        /** Check created 'related' product link */
+        $actualRelated = $product->getRelatedLinkCollection()->getItems();
+        $this->assertCount(1, $actualRelated, "One link of 'related' type must exist.");
+        /** @var Mage_Catalog_Model_Product_Link $relatedProductLink */
+        $relatedProductLink = reset($actualRelated);
+        $this->assertEquals(
+            $this->_relatedProductId,
+            $relatedProductLink->getLinkedProductId(),
+            'Related product ID is invalid'
+        );
+
+        /** Check created 'up-sell' product link */
+        $actualUpSell = $product->getUpSellLinkCollection()->getItems();
+        $this->assertCount(1, $actualUpSell, "One link of 'up-sell' type must exist.");
+        /** @var Mage_Catalog_Model_Product_Link $upSellProductLink */
+        $upSellProductLink = reset($actualUpSell);
+        $this->assertEquals(
+            $this->_upSellProductId,
+            $upSellProductLink->getLinkedProductId(),
+            'Up-sell product ID is invalid'
+        );
+    }
+
+    /**
+     * Test 'items' method of catalog product API.
+     *
+     * @depends testAssign
+     */
+    public function testList()
+    {
+        $upSellProducts = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductLinkList',
+            array(
+                self::LINK_TYPE_UP_SELL,
+                $this->_mainProductId
+            )
+        );
+        $this->assertCount(1, $upSellProducts, "One link of 'up-sell' type must exist.");
+        $expectedFields = array('product_id', 'type', 'set', 'sku', 'position');
+        $productData = reset($upSellProducts);
+        $missingFields = array_diff($expectedFields, array_keys($productData));
+        $this->assertEmpty(
+            $missingFields,
+            sprintf("The following fields must be present in response: %s.", implode(', ', $missingFields))
+        );
+        $this->assertEquals($this->_upSellProductId, $productData['product_id'], "Up-sell product ID is invalid.");
+    }
+
+    /**
+     * Test 'update' method of catalog product API.
+     *
+     * @depends testList
+     */
+    public function testUpdate()
+    {
+        $positionForUpdate = 5;
+        $isUpdated = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductLinkUpdate',
+            array(
+                self::LINK_TYPE_RELATED,
+                $this->_mainProductId,
+                $this->_relatedProductId,
+                (object)array('position' => $positionForUpdate)
+            )
+        );
+        $this->assertTrue($isUpdated, "Related link update was unsuccessful.");
+
+        /** Check created 'related' product link */
+        /** @var Mage_Catalog_Model_Product $product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($this->_mainProductId);
+        $actualRelated = $product->getRelatedLinkCollection()->getItems();
+        $this->assertCount(1, $actualRelated, "One link of 'related' type must exist.");
+        /** @var Mage_Catalog_Model_Product_Link $relatedProductLink */
+        $relatedProductLink = reset($actualRelated);
+        $this->assertEquals(
+            $positionForUpdate,
+            $relatedProductLink->getPosition(),
+            'Product link position was not updated.'
+        );
+    }
+
+    /**
+     * Test for 'remove' method of catalog product API
+     *
+     * @depends testUpdate
+     */
+    public function testRemove()
+    {
+        $isRemoved = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductLinkRemove',
+            array(
+                self::LINK_TYPE_UP_SELL,
+                $this->_mainProductId,
+                $this->_upSellProductId
+            )
+        );
+        $this->assertTrue($isRemoved, "Related link remove was unsuccessful.");
+
+        /** @var Mage_Catalog_Model_Product $product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load($this->_mainProductId);
+
+        /** Check that 'related' product link was not removed */
+        $actualRelated = $product->getRelatedLinkCollection()->getItems();
+        $this->assertCount(1, $actualRelated, "One link of 'related' type must exist.");
+
+        /** Check that 'up-sell' product link was actually removed from DB */
+        $actualUpSell = $product->getUpSellLinkCollection()->getItems();
+        $this->assertCount(0, $actualUpSell, "No links of 'up-sell' type must exist.");
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Option/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Option/ApiTest.php
new file mode 100644
index 00000000000..e5c70c11fc6
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Option/ApiTest.php
@@ -0,0 +1,407 @@
+<?php
+/**
+ * Product custom options API model test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Catalog/Model/Product/Api/_files/CustomOption.php
+ * @magentoDbIsolation enabled
+ */
+class Mage_Catalog_Model_Product_Option_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var array
+     */
+    protected static $_createdOptionAfter;
+
+    /** @var SimpleXmlElement */
+    protected static $_customOptionFixture;
+
+    public static function setUpBeforeClass()
+    {
+        self::$_customOptionFixture = self::_loadXmlFixture('CustomOption.xml');
+    }
+
+    /**
+     * Product Custom Option CRUD test
+     */
+    public function testCustomOptionCRUD()
+    {
+        $customOptions = Magento_Test_Helper_Api::simpleXmlToArray(self::$_customOptionFixture->customOptionsToAdd);
+        $store = (string)self::$_customOptionFixture->store;
+
+        $this->_testCreate($store, $customOptions);
+        $this->_testRead($store, $customOptions);
+        $optionsToUpdate = Magento_Test_Helper_Api::simpleXmlToArray(
+            self::$_customOptionFixture->customOptionsToUpdate
+        );
+        $this->_testUpdate($optionsToUpdate);
+    }
+
+    /**
+     * Test creating custom options
+     *
+     * @param string $store
+     * @param array $customOptions
+     */
+    protected function _testCreate($store, $customOptions)
+    {
+        $fixtureProductId = Mage::registry('productData')->getId();
+        $createdOptionBefore = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionList',
+            array(
+                'productId' => $fixtureProductId,
+                'store' => $store
+            )
+        );
+        $this->assertEmpty($createdOptionBefore);
+
+        foreach ($customOptions as $option) {
+            if (isset($option['additional_fields'])
+                and !is_array(reset($option['additional_fields']))
+            ) {
+                $option['additional_fields'] = array($option['additional_fields']);
+            }
+
+            $addedOptionResult = Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductCustomOptionAdd',
+                array(
+                    'productId' => $fixtureProductId,
+                    'data' => (object)$option,
+                    'store' => $store
+                )
+            );
+            $this->assertTrue((bool)$addedOptionResult);
+        }
+    }
+
+    /**
+     * Test reading custom options
+     *
+     * @param string $store
+     * @param array $customOptions
+     */
+    protected function _testRead($store, $customOptions)
+    {
+        $fixtureProductId = Mage::registry('productData')->getId();
+        self::$_createdOptionAfter = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionList',
+            array(
+                'productId' => $fixtureProductId,
+                'store' => $store
+            )
+        );
+
+        $this->assertTrue(is_array(self::$_createdOptionAfter));
+        $this->assertEquals(count($customOptions), count(self::$_createdOptionAfter));
+
+        foreach (self::$_createdOptionAfter as $option) {
+            $this->assertEquals($customOptions[$option->type]['title'], $option->title);
+        }
+    }
+
+    /**
+     * Test updating custom option
+     *
+     * @param array $optionsToUpdate
+     */
+    protected function _testUpdate($optionsToUpdate)
+    {
+        $updateCounter = 0;
+        foreach (self::$_createdOptionAfter as $option) {
+            $option = (array)$option;
+            $optionInfo = Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductCustomOptionInfo',
+                array(
+                    'optionId' => $option['option_id']
+                )
+            );
+
+            $this->assertTrue(is_array($optionInfo));
+            $this->assertGreaterThan(3, count($optionInfo));
+
+            if (isset($optionsToUpdate[$option['type']])) {
+                $toUpdateValues = $optionsToUpdate[$option['type']];
+                if (isset($toUpdateValues['additional_fields'])
+                    and !is_array(reset($toUpdateValues['additional_fields']))
+                ) {
+                    $toUpdateValues['additional_fields'] = array($toUpdateValues['additional_fields']);
+                }
+
+                $updateOptionResult = Magento_Test_Helper_Api::call(
+                    $this,
+                    'catalogProductCustomOptionUpdate',
+                    array(
+                        'optionId' => $option['option_id'],
+                        'data' => $toUpdateValues
+                    )
+                );
+                $this->assertTrue((bool)$updateOptionResult);
+                $updateCounter++;
+
+                $this->_testOptionsAfterUpdate($option['option_id'], $toUpdateValues);
+            }
+        }
+
+        $this->assertCount($updateCounter, $optionsToUpdate);
+    }
+
+    /**
+     * Check that options has been updated correctly
+     *
+     * @param int $optionId
+     * @param array $toUpdateValues
+     */
+    protected function _testOptionsAfterUpdate($optionId, $toUpdateValues)
+    {
+        $optionAfterUpdate = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionInfo',
+            array(
+                'optionId' => $optionId
+            )
+        );
+
+        foreach ($toUpdateValues as $key => $value) {
+            if (is_string($value)) {
+                self::assertEquals($value, $optionAfterUpdate[$key]);
+            }
+        }
+
+        if (isset($toUpdateValues['additional_fields'])) {
+            $updateFields = reset($toUpdateValues['additional_fields']);
+            $actualFields = reset($optionAfterUpdate['additional_fields']);
+            foreach ($updateFields as $key => $value) {
+                if (is_string($value)) {
+                    self::assertEquals($value, $actualFields[$key]);
+                }
+            }
+        }
+    }
+
+    /**
+     * Product Custom Option ::types() method test
+     */
+    public function testCustomOptionTypes()
+    {
+        $attributeSetFixture = $this->_loadXmlFixture('CustomOptionTypes.xml');
+        $customOptionsTypes = Magento_Test_Helper_Api::simpleXmlToArray($attributeSetFixture);
+
+        $optionTypes = Magento_Test_Helper_Api::call($this, 'catalogProductCustomOptionTypes', array());
+        $this->assertEquals($customOptionsTypes['customOptionTypes']['types'], $optionTypes);
+    }
+
+    /**
+     * Update custom option
+     *
+     * @param int $optionId
+     * @param array $option
+     * @param int $store
+     *
+     * @return boolean
+     */
+    protected function _updateOption($optionId, $option, $store = null)
+    {
+        if (isset($option['additional_fields'])
+            and !is_array(reset($option['additional_fields']))
+        ) {
+            $option['additional_fields'] = array($option['additional_fields']);
+        }
+
+        return Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionUpdate',
+            array(
+                'optionId' => $optionId,
+                'data' => $option,
+                'store' => $store
+            )
+        );
+    }
+
+    /**
+     * Test option add exception: product_not_exists
+     */
+    public function testCustomOptionAddExceptionProductNotExists()
+    {
+        $customOptions = Magento_Test_Helper_Api::simpleXmlToArray(self::$_customOptionFixture->customOptionsToAdd);
+
+        $option = reset($customOptions);
+        if (isset($option['additional_fields'])
+            and !is_array(reset($option['additional_fields']))
+        ) {
+            $option['additional_fields'] = array($option['additional_fields']);
+        }
+        $this->setExpectedException('SoapFault');
+        Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionAdd',
+            array(
+                'productId' => 'invalid_id',
+                'data' => $option
+            )
+        );
+    }
+
+    /**
+     * Test option add without additional fields exception: invalid_data
+     */
+    public function testCustomOptionAddExceptionAdditionalFieldsNotSet()
+    {
+        $fixtureProductId = Mage::registry('productData')->getId();
+        $customOptions = Magento_Test_Helper_Api::simpleXmlToArray(self::$_customOptionFixture->customOptionsToAdd);
+
+        $option = $customOptions['field'];
+        $option['additional_fields'] = array();
+
+        $this->setExpectedException('SoapFault', 'Provided data is invalid.');
+        Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionAdd',
+            array('productId' => $fixtureProductId, 'data' => $option)
+        );
+    }
+
+    /**
+     * Test option date_time add with store id exception: store_not_exists
+     */
+    public function testCustomOptionDateTimeAddExceptionStoreNotExist()
+    {
+        $fixtureProductId = Mage::registry('productData')->getId();
+        $customOptions = Magento_Test_Helper_Api::simpleXmlToArray(self::$_customOptionFixture->customOptionsToAdd);
+
+        $option = reset($customOptions);
+        if (isset($option['additional_fields'])
+            and !is_array(reset($option['additional_fields']))
+        ) {
+            $option['additional_fields'] = array($option['additional_fields']);
+        }
+        $this->setExpectedException('SoapFault');
+        Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionAdd',
+            array(
+                'productId' => $fixtureProductId,
+                'data' => $option,
+                'store' => 'some_store_name'
+            )
+        );
+    }
+
+    /**
+     * Test product custom options list exception: product_not_exists
+     */
+    public function testCustomOptionListExceptionProductNotExists()
+    {
+        $store = (string)self::$_customOptionFixture->store;
+
+        $this->setExpectedException('SoapFault');
+        Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionList',
+            array(
+                'productId' => 'unknown_id',
+                'store' => $store
+            )
+        );
+    }
+
+    /**
+     * Test product custom options list exception: store_not_exists
+     */
+    public function testCustomOptionListExceptionStoreNotExists()
+    {
+        $fixtureProductId = Mage::registry('productData')->getId();
+
+        $this->setExpectedException('SoapFault');
+        Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionList',
+            array(
+                'productId' => $fixtureProductId,
+                'store' => 'unknown_store_name'
+            )
+        );
+    }
+
+    /**
+     * Test option add with invalid type
+     *
+     * @expectedException SoapFault
+     */
+    public function testCustomOptionUpdateExceptionInvalidType()
+    {
+        $optionsToUpdate = Magento_Test_Helper_Api::simpleXmlToArray(
+            self::$_customOptionFixture->customOptionsToUpdate
+        );
+        $option = (array)reset(self::$_createdOptionAfter);
+
+        $toUpdateValues = $optionsToUpdate[$option['type']];
+        $toUpdateValues['type'] = 'unknown_type';
+
+        $this->_updateOption($option['option_id'], $toUpdateValues);
+    }
+
+    /**
+     * Test option remove and exception
+     *
+     * @expectedException SoapFault
+     * @depends testCustomOptionUpdateExceptionInvalidType
+     */
+    public function testCustomOptionRemove()
+    {
+        // Remove
+        foreach (self::$_createdOptionAfter as $option) {
+            $removeOptionResult = Magento_Test_Helper_Api::call(
+                $this,
+                'catalogProductCustomOptionRemove',
+                // @codingStandardsIgnoreStart
+                array(
+                    'optionId' => $option->option_id
+                )
+                // @codingStandardsIgnoreEnd
+            );
+            $this->assertTrue((bool)$removeOptionResult);
+        }
+
+        // Delete exception test
+        Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductCustomOptionRemove',
+            array('optionId' => mt_rand(99999, 999999))
+        );
+    }
+
+    /**
+     * Load XML from fixture
+     *
+     * @param string $fileName
+     * @return SimpleXMLElement
+     */
+    protected static function _loadXmlFixture($fileName)
+    {
+        return simplexml_load_file(dirname(__FILE__) . '/../Api/_files/_data/xml/' . $fileName);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ApiTest.php b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ApiTest.php
new file mode 100644
index 00000000000..90663482448
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Type/ApiTest.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_Catalog
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Catalog_Model_Product_Type_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @param string $class
+     * @dataProvider itemsDataProvider
+     */
+    public function testItems($class)
+    {
+        /** @var $model Mage_Catalog_Model_Product_Type_Api */
+        $model = Mage::getModel($class);
+        $result = $model->items();
+        $this->assertInternalType('array', $result);
+        $this->assertNotEmpty($result);
+        foreach ($result as $item) {
+            $this->assertArrayHasKey('type', $item);
+            $this->assertArrayHasKey('label', $item);
+        }
+    }
+
+    public function itemsDataProvider()
+    {
+        return array(
+            array('Mage_Catalog_Model_Product_Type_Api'),
+            array('Mage_Catalog_Model_Product_Type_Api_V2'), // a dummy class, doesn't require separate test suite
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/_files/categories.php b/dev/tests/integration/testsuite/Mage/Catalog/_files/categories.php
index 81b9e237d30..1f3f62ecdfc 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/_files/categories.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/_files/categories.php
@@ -116,6 +116,9 @@ $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE)
     ->setSku('simple')
     ->setPrice(10)
     ->setWeight(18)
+    ->setStockData(array(
+        'use_config_manage_stock' => 0,
+    ))
     ->setCategoryIds(array(2,3,4))
     ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
     ->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
@@ -131,6 +134,9 @@ $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE)
     ->setSku('12345') // SKU intentionally contains digits only
     ->setPrice(45.67)
     ->setWeight(56)
+    ->setStockData(array(
+        'use_config_manage_stock' => 0,
+    ))
     ->setCategoryIds(array(5))
     ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
     ->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/_files/product_simple.php b/dev/tests/integration/testsuite/Mage/Catalog/_files/product_simple.php
index 6d468eb3466..cfcb75336eb 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/_files/product_simple.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/_files/product_simple.php
@@ -27,6 +27,7 @@
 
 /** @var $product Mage_Catalog_Model_Product */
 $product = Mage::getModel('Mage_Catalog_Model_Product');
+$product->isObjectNew(true);
 $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE)
     ->setId(1)
     ->setAttributeSetId(4)
@@ -34,6 +35,9 @@ $product->setTypeId(Mage_Catalog_Model_Product_Type::TYPE_SIMPLE)
     ->setName('Simple Product')
     ->setSku('simple')
     ->setPrice(10)
+    ->setWeight(1)
+    ->setShortDescription("Short description")
+    ->setTaxClassId(0)
     ->setTierPrice(
         array(
             array(
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system.php b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system.php
index 3346813b313..a5321101b07 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system.php
@@ -26,11 +26,11 @@
  */
 
 $model = new Mage_Catalog_Model_Resource_Eav_Attribute(
-    new Mage_Core_Model_Event_Manager(),
-    new Mage_Core_Model_Cache()
+    Mage::getModel('Mage_Core_Model_Event_Manager'),
+    Mage::getModel('Mage_Core_Model_Cache')
 );
 $model->setName('system_attribute')
     ->setId(2)
     ->setEntityTypeId(4)
     ->setIsUserDefined(0);
-$model->save();
\ No newline at end of file
+$model->save();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system_with_applyto_data.php b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system_with_applyto_data.php
index 118200afc08..d79842026b3 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system_with_applyto_data.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_system_with_applyto_data.php
@@ -26,12 +26,12 @@
  */
 
 $model = new Mage_Catalog_Model_Resource_Eav_Attribute(
-    new Mage_Core_Model_Event_Manager(),
-    new Mage_Core_Model_Cache()
+    Mage::getModel('Mage_Core_Model_Event_Manager'),
+    Mage::getModel('Mage_Core_Model_Cache')
 );
 $model->setName('system_attribute')
     ->setId(3)
     ->setEntityTypeId(4)
     ->setIsUserDefined(0)
     ->setApplyTo(array('simple', 'configurable'));
-$model->save();
\ No newline at end of file
+$model->save();
diff --git a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_user_defined.php b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_user_defined.php
index 3d1476a02be..ea22b15b484 100644
--- a/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_user_defined.php
+++ b/dev/tests/integration/testsuite/Mage/Catalog/controllers/_files/attribute_user_defined.php
@@ -26,8 +26,8 @@
  */
 
 $model = new Mage_Catalog_Model_Resource_Eav_Attribute(
-    new Mage_Core_Model_Event_Manager(),
-    new Mage_Core_Model_Cache()
+    Mage::getModel('Mage_Core_Model_Event_Manager'),
+    Mage::getModel('Mage_Core_Model_Cache')
 );
 $model->setName('user_attribute')
     ->setId(1)
diff --git a/dev/tests/integration/testsuite/Mage/CatalogInventory/Model/Stock/Item/ApiTest.php b/dev/tests/integration/testsuite/Mage/CatalogInventory/Model/Stock/Item/ApiTest.php
new file mode 100644
index 00000000000..4b8a911376d
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/CatalogInventory/Model/Stock/Item/ApiTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Stock item API test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Catalog/_files/multiple_products.php
+ */
+class Mage_CatalogInventory_Model_Stock_Item_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test list method.
+     */
+    public function testList()
+    {
+        $productsId = array(10, 11, 12);
+        /** Retrieve products stock data. */
+        $productsStockData = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogInventoryStockItemList',
+            array($productsId)
+        );
+        /** Assert product stock data retrieving was successful. */
+        $this->assertNotEmpty($productsStockData, 'Product stock data retrieving was unsuccessful.');
+        /** Assert retrieved product stock data is correct. */
+        $expectedData = array(
+            'product_id' => '10',
+            'sku' => 'simple1',
+            'qty' => 100,
+            'is_in_stock' => '1'
+        );
+        $stockData = reset($productsStockData);
+        $this->assertEquals($expectedData, $stockData, 'Product stock data is incorrect.');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/CatalogSearch/controllers/ResultControllerTest.php b/dev/tests/integration/testsuite/Mage/CatalogSearch/controllers/ResultControllerTest.php
index b45f3e28d30..0b2b6941ca3 100644
--- a/dev/tests/integration/testsuite/Mage/CatalogSearch/controllers/ResultControllerTest.php
+++ b/dev/tests/integration/testsuite/Mage/CatalogSearch/controllers/ResultControllerTest.php
@@ -29,7 +29,6 @@ class Mage_CatalogSearch_ResultControllerTest extends Magento_Test_TestCase_Cont
 {
     /**
      * @magentoDataFixture Mage/CatalogSearch/_files/query.php
-     * @magentoConfigFixture current_store design/theme/full_name default/demo
      * @magentoConfigFixture current_store general/locale/code de_DE
      */
     public function testIndexActionTranslation()
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/AbstractTest.php
new file mode 100644
index 00000000000..80f8debd833
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/AbstractTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Abstract checkout API testcase.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+ */
+abstract class Mage_Checkout_Model_Cart_AbstractTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Retrieve quote created in fixture.
+     *
+     * @return Mage_Sales_Model_Quote
+     */
+    protected function _getQuote()
+    {
+        /** @var $session Mage_Checkout_Model_Session */
+        $session = Mage::getModel('Mage_Checkout_Model_Session');
+        /** @var Mage_Sales_Model_Quote $quote */
+        $quote = $session->getQuote();
+        return $quote;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Api/_files/license_agreement.php b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Api/_files/license_agreement.php
new file mode 100644
index 00000000000..8f86488487d
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Api/_files/license_agreement.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Fixture for licenseAgreement method.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/** @var Mage_Checkout_Model_Agreement $agreement */
+$agreement = Mage::getModel('Mage_Checkout_Model_Agreement');
+$agreement->setData(
+    array(
+        'name' => 'Agreement name',
+        'is_active' => '1',
+        'is_html' => '0',
+        'checkbox_text' => 'License text',
+        'content' => 'Some content',
+        'stores' => array(0)
+    )
+);
+$agreement->save();
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/ApiTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/ApiTest.php
new file mode 100644
index 00000000000..52871420909
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/ApiTest.php
@@ -0,0 +1,445 @@
+<?php
+/**
+ * Checkout API tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDbIsolation enabled
+ */
+class Mage_Checkout_Model_Cart_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test for product add to shopping cart.
+     *
+     * @magentoDataFixture Mage/Catalog/_files/product_simple_duplicated.php
+     * @magentoDataFixture Mage/Checkout/_files/quote.php
+     */
+    public function testProductAddToCart()
+    {
+        /** @var Mage_Sales_Model_Resource_Quote_Collection $quoteCollection */
+        $quoteCollection = Mage::getModel('Mage_Sales_Model_Resource_Quote_Collection');
+        $quote = $quoteCollection->getFirstItem();
+        $productSku = 'simple-1';
+
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartProductAdd',
+            array(
+                'quoteId' => $quote->getId(),
+                'productsData' => array(
+                    (object)array('sku' => $productSku, 'qty' => 1)
+                )
+            )
+        );
+
+        $this->assertTrue($soapResult, 'Error during product add to cart via API call');
+    }
+
+    /**
+     * Test for product with custom options add to shopping cart.
+     *
+     * @magentoDataFixture Mage/Catalog/_files/product_with_options.php
+     * @magentoDataFixture Mage/Checkout/_files/quote.php
+     */
+    public function testProductWithCustomOptionsAddToCart()
+    {
+        // Create custom option for product
+        $customOptionId = null;
+        $customOptionTitle = 'test_option_code_1';
+        $customOptionValue = 'option_value';
+        /** @var Mage_Catalog_Model_Product $product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load(1);
+        /** @var Mage_Sales_Model_Resource_Quote_Collection $quoteCollection */
+        $quoteCollection = Mage::getModel('Mage_Sales_Model_Resource_Quote_Collection');
+        $quote = $quoteCollection->getFirstItem();
+
+        // Find ID of created custom option for future use
+        /** @var $productOption Mage_Catalog_Model_Product_Option */
+        $productOption = Mage::getModel('Mage_Catalog_Model_Product_Option');
+
+        foreach ($productOption->getProductOptionCollection($product) as $option) {
+            if ($option['default_title'] == $customOptionTitle) {
+                $customOptionId = $option['option_id'];
+                break;
+            }
+        }
+        if (null === $customOptionId) {
+            $this->fail('Can not find custom option ID that been created');
+        }
+
+        $customOptionsData = array($customOptionId => $customOptionValue);
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartProductAdd',
+            array(
+                'quoteId' => $quote->getId(),
+                'productsData' => array(
+                    (object)array('sku' => $product->getSku(), 'qty' => 1, 'options' => $customOptionsData)
+                )
+            )
+        );
+
+        $this->assertTrue($soapResult, 'Error during product with custom options add to cart via API call');
+
+        /** @var $quoteItemOption Mage_Sales_Model_Resource_Quote_Item_Option_Collection */
+        $quoteItemOption = Mage::getResourceModel('Mage_Sales_Model_Resource_Quote_Item_Option_Collection');
+        $itemOptionValue = null;
+
+        foreach ($quoteItemOption->getOptionsByProduct($product) as $row) {
+            if ('option_' . $customOptionId == $row['code']) {
+                $itemOptionValue = $row['value'];
+                break;
+            }
+        }
+        if (null === $itemOptionValue) {
+            $this->fail('Custom option value not found in DB after API call');
+        }
+        $this->assertEquals(
+            $customOptionValue,
+            $itemOptionValue,
+            'Custom option value in DB does not match value passed by API'
+        );
+    }
+
+    /**
+     * Test for product list from shopping cart API method.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+     */
+    public function testCartProductList()
+    {
+        /** @var Mage_Catalog_Model_Product $product */
+        $product = Mage::getModel('Mage_Catalog_Model_Product');
+        $product->load(1);
+        /** @var Mage_Sales_Model_Resource_Quote_Collection $quoteCollection */
+        $quoteCollection = Mage::getModel('Mage_Sales_Model_Resource_Quote_Collection');
+        $quote = $quoteCollection->getFirstItem();
+
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartProductList',
+            array('quoteId' => $quote->getId())
+        );
+
+        $this->assertInternalType('array', $soapResult, 'Product List call result is not an array');
+
+        if (0 === key($soapResult)) {
+            $this->assertCount(1, $soapResult, 'Product List call result contain not exactly one product');
+
+            $soapResult = $soapResult[0]; //workaround for different result structure
+        }
+        $this->assertArrayHasKey('sku', $soapResult, 'Product List call result does not contain a product sku');
+        $this->assertEquals($product->getSku(), $soapResult['sku'], 'Product Sku does not match fixture');
+    }
+
+    /**
+     * Test for product list from shopping cart API method
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_check_payment.php
+     * @magentoAppIsolation enabled
+     */
+    public function testCreateOrder()
+    {
+        // Set order increment id prefix
+        $prefix = '01';
+        Magento_Test_Helper_Eav::setIncrementIdPrefix('order', $prefix);
+
+        $quote = $this->_getQuoteFixture();
+        $orderIncrementId = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartOrder',
+            array(
+                'quoteId' => $quote->getId()
+            )
+        );
+
+        $this->assertTrue(is_string($orderIncrementId), 'Increment Id is not a string');
+        $this->assertStringStartsWith($prefix, $orderIncrementId, 'Increment Id returned by API is not correct');
+    }
+
+    /**
+     * Test order creation with payment method
+     *
+     * @magentoConfigFixture current_store payment/ccsave/active 1
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_ccsave_payment.php
+     * @magentoAppIsolation enabled
+     */
+    public function testCreateOrderWithPayment()
+    {
+        $quote = $this->_getQuoteFixture();
+        $paymentMethod = array(
+            'method' => 'ccsave',
+            'cc_owner' => 'user',
+            'cc_type' => 'VI',
+            'cc_exp_month' => 5,
+            'cc_exp_year' => 2016,
+            'cc_number' => '4584728193062819',
+            'cc_cid' => '000',
+        );
+
+        $orderIncrementId = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartOrderWithPayment',
+            array(
+                'quoteId' => $quote->getId(),
+                'store' => null,
+                'agreements' => null,
+                'paymentData' => (object)$paymentMethod
+            )
+        );
+
+        $this->assertTrue(is_string($orderIncrementId), 'Increment Id is not a string');
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::getModel('Mage_Sales_Model_Order')->loadByIncrementId($orderIncrementId);
+        $this->assertEquals('ccsave', $order->getPayment()->getMethod());
+    }
+
+    /**
+     * Test order creation with not available payment method
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_ccsave_payment.php
+     * @magentoAppIsolation enabled
+     */
+    public function testCreateOrderWithNotAvailablePayment()
+    {
+        $quote = $this->_getQuoteFixture();
+        $paymentMethod = array(
+            'method' => 'paypal_direct',
+            'cc_owner' => 'user',
+            'cc_type' => 'VI',
+            'cc_exp_month' => 5,
+            'cc_exp_year' => 2016,
+            'cc_number' => '4584728193062819',
+            'cc_cid' => '000',
+        );
+
+        $errorCode = 1075;
+        $errorMessage = 'The requested Payment Method is not available.';
+        try {
+            Magento_Test_Helper_Api::call(
+                $this,
+                'shoppingCartOrderWithPayment',
+                array(
+                    'quoteId' => $quote->getId(),
+                    'store' => null,
+                    'agreements' => null,
+                    'paymentData' => (object)$paymentMethod
+                )
+            );
+            $this->fail('Expected error exception was not raised.');
+        } catch (SoapFault $e) {
+            $this->_assertError($errorCode, $errorMessage, $e->faultcode, $e->faultstring);
+        }
+    }
+
+    /**
+     * Test order creation with payment method data empty
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_ccsave_payment.php
+     * @magentoAppIsolation enabled
+     */
+    public function testCreateOrderWithEmptyPaymentData()
+    {
+        $quote = $this->_getQuoteFixture();
+        $errorCode = 1071;
+        $errorMessage = 'Payment method data is empty.';
+        try {
+            Magento_Test_Helper_Api::call(
+                $this,
+                'shoppingCartOrderWithPayment',
+                array(
+                    'quoteId' => $quote->getId(),
+                    'store' => null,
+                    'agreements' => null,
+                    'paymentData' => array()
+                )
+            );
+            $this->fail('Expected error exception was not raised.');
+        } catch (SoapFault $e) {
+            $this->_assertError($errorCode, $errorMessage, $e->faultcode, $e->faultstring);
+        }
+    }
+
+    /**
+     * Test order creation with invalid payment method data
+     *
+     * @magentoConfigFixture current_store payment/ccsave/active 1
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_ccsave_payment.php
+     * @magentoAppIsolation enabled
+     */
+    public function testCreateOrderWithInvalidPaymentData()
+    {
+        $quote = $this->_getQuoteFixture();
+        $paymentMethod = array(
+            'method' => 'ccsave',
+            'cc_owner' => 'user',
+            'cc_type' => 'VI',
+            'cc_exp_month' => 5,
+            'cc_exp_year' => 2010,
+            'cc_number' => '4584728193062819',
+            'cc_cid' => '000',
+        );
+        $errorCode = 1075;
+        $errorMessage = 'Incorrect credit card expiration date.';
+        try {
+            Magento_Test_Helper_Api::call(
+                $this,
+                'shoppingCartOrderWithPayment',
+                array(
+                    'quoteId' => $quote->getId(),
+                    'store' => null,
+                    'agreements' => null,
+                    'paymentData' => (object)$paymentMethod
+                )
+            );
+            $this->fail('Expected error exception was not raised.');
+        } catch (SoapFault $e) {
+            $this->_assertError($errorCode, $errorMessage, $e->faultcode, $e->faultstring);
+        }
+    }
+
+    /**
+     * Assert that error code and message equals expected
+     *
+     * @param int $expectedCode
+     * @param string $expectedMessage
+     * @param int $actualCode
+     * @param string $actualMessage
+     */
+    protected function _assertError($expectedCode, $expectedMessage, $actualCode, $actualMessage)
+    {
+        $this->assertEquals($expectedCode, $actualCode);
+        $this->assertEquals($expectedMessage, $actualMessage);
+    }
+
+    /**
+     * Test info method.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_check_payment.php
+     */
+    public function testInfo()
+    {
+        /** @var Mage_Checkout_Model_Cart $quote */
+        $quote = $this->_getQuoteFixture();
+        $quoteId = $quote->getId();
+        /** Retrieve quote info. */
+        $quoteInfo = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartInfo',
+            array($quoteId)
+        );
+        /** Assert quote info retrieving was successful. */
+        $this->assertNotEmpty($quoteInfo, 'Quote info retrieving was unsuccessful.');
+        /** Assert base fields are present in the response. */
+        $expectedFields = array('shipping_address', 'billing_address', 'items', 'payment');
+        $missingFields = array_diff($expectedFields, array_keys($quoteInfo));
+        $this->assertEmpty(
+            $missingFields,
+            sprintf("The following fields must be present in response: %s.", implode(', ', $missingFields))
+        );
+        /** Assert retrieved quote id is correct. */
+        $this->assertEquals($quoteId, $quoteInfo['quote_id'], 'Quote Id retrieving was unsuccessful.');
+    }
+
+    /**
+     * Test totals method.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_check_payment.php
+     */
+    public function testTotals()
+    {
+        if (Magento_Test_Bootstrap::getInstance()->getDbVendorName() != 'mysql') {
+            $this->markTestIncomplete('Legacy API is expected to support MySQL only.');
+        }
+        /** @var Mage_Checkout_Model_Cart $quote */
+        $quote = $this->_getQuoteFixture();
+        $quoteId = $quote->getId();
+        /** Retrieve quote info. */
+        $quoteTotals = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartTotals',
+            array($quoteId)
+        );
+        /** Assert quote totals retrieving were successful. */
+        $this->assertNotEmpty($quoteTotals, 'Quote totals retrieving were unsuccessful.');
+        /** Assert totals titles. */
+        $expectedQuotesTitles = array('Subtotal', 'Grand Total');
+        $actualQuotesTitles = array();
+        $grandTotal = null;
+        foreach ($quoteTotals as $quoteTotal) {
+            $actualQuotesTitles[] = $quoteTotal['title'];
+            if ($quoteTotal['title'] == 'Grand Total') {
+                $grandTotal = $quoteTotal;
+            }
+        }
+        $missingQuotesTitles = array_diff($expectedQuotesTitles, $actualQuotesTitles);
+        $this->assertEmpty(
+            $missingQuotesTitles,
+            sprintf("The following quotes titles must be present in response: %s.", implode(', ', $missingQuotesTitles))
+        );
+        /** Assert grand total is retrieved correct. */
+        $expectedGrandTotal = array('title' => 'Grand Total', 'amount' => 20);
+        $this->assertEquals($expectedGrandTotal, $grandTotal, 'Grand total retrieving was unsuccessful.');
+    }
+
+    /**
+     * Test licenseAgreement method.
+     *
+     * @magentoConfigFixture current_store checkout/options/enable_agreements 1
+     * @magentoDataFixture Mage/Checkout/Model/Cart/Api/_files/license_agreement.php
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_check_payment.php
+     */
+    public function testLicenseAgreement()
+    {
+        /** @var Mage_Checkout_Model_Cart $quote */
+        $quote = $this->_getQuoteFixture();
+        $quoteId = $quote->getId();
+        /** Retrieve quote license agreement. */
+        $licenseAgreement = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartLicense',
+            array($quoteId)
+        );
+        /** Assert quote license agreement retrieving were successful. */
+        $this->assertNotEmpty($licenseAgreement, 'Quote license agreement retrieving was unsuccessful.');
+        /** Assert license info is retrieved correct. */
+        /** @var Mage_Checkout_Model_Agreement $agreement */
+        $agreement = Mage::getModel('Mage_Checkout_Model_Agreement')->load('Agreement name', 'name');
+        $agreementData = $agreement->getData();
+        unset($agreementData['store_id']);
+        $this->assertEquals($agreementData, reset($licenseAgreement), 'License agreement data is incorrect.');
+    }
+
+    /**
+     * Retrieve the quote object created in fixture.
+     *
+     * @return Mage_Sales_Model_Quote
+     */
+    protected function _getQuoteFixture()
+    {
+        /** @var Mage_Sales_Model_Resource_Quote_Collection $quoteCollection */
+        $quoteCollection = Mage::getModel('Mage_Sales_Model_Resource_Quote_Collection');
+        /** @var Mage_Sales_Model_Quote $quote */
+        $quote = $quoteCollection->getFirstItem();
+        return $quote;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Coupon/ApiTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Coupon/ApiTest.php
new file mode 100644
index 00000000000..89f3cbc7438
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Coupon/ApiTest.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Coupon API tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+ * @magentoDataFixture Mage/Checkout/_files/discount_10percent.php
+ */
+class Mage_Checkout_Model_Cart_Coupon_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /** @var Mage_Catalog_Model_Product */
+    protected $_product;
+    /** @var Mage_Sales_Model_Quote */
+    protected $_quote;
+    /** @var Mage_SalesRule_Model_Rule */
+    protected $_salesRule;
+
+    /**
+     * We can't put this code inside setUp() as it will be called before fixtures execution
+     */
+    protected function _init()
+    {
+        $this->_product = Mage::getModel('Mage_Catalog_Model_Product')->load(1);
+        $this->_quote = Mage::getModel('Mage_Sales_Model_Resource_Quote_Collection')->getFirstItem();
+        $this->_salesRule = Mage::getModel('Mage_SalesRule_Model_Rule')->load('Test Coupon', 'name');
+    }
+
+    /**
+     * Test coupon code applying.
+     */
+    public function testCartCouponAdd()
+    {
+        $this->_init();
+
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartCouponAdd',
+            array(
+                'quoteId' => $this->_quote->getId(),
+                'couponCode' => $this->_salesRule->getCouponCode()
+            )
+        );
+
+        $this->assertTrue($soapResult, 'Coupon code was not applied');
+        /** @var $discountedQuote Mage_Sales_Model_Quote */
+        $discountedQuote = $this->_quote->load($this->_quote->getId());
+        $discountedPrice = sprintf('%01.2f', $this->_product->getPrice() * (1 - 10 / 100));
+
+        $this->assertEquals(
+            $discountedQuote->getSubtotalWithDiscount(),
+            $discountedPrice,
+            'Quote subtotal price does not match discounted item price'
+        );
+    }
+
+    /**
+     * Test coupon code removing
+     */
+    public function testCartCouponRemove()
+    {
+        $this->_init();
+        $originalPrice = $this->_product->getPrice();
+
+        // Apply coupon
+        $this->_quote->setCouponCode($this->_salesRule->getCouponCode())
+            ->collectTotals()
+            ->save();
+
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartCouponRemove',
+            array('quoteId' => $this->_quote->getId())
+        );
+
+        $this->assertTrue($soapResult, 'Coupon code was not removed');
+
+        /** @var $quoteWithoutDiscount Mage_Sales_Model_Quote */
+        $quoteWithoutDiscount = $this->_quote->load($this->_quote->getId());
+
+        $this->assertEquals(
+            $originalPrice,
+            $quoteWithoutDiscount->getSubtotalWithDiscount(),
+            'Quote subtotal price does not match its original price after discount removal'
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Customer/ApiTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Customer/ApiTest.php
new file mode 100644
index 00000000000..e26ed7e4e3a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Customer/ApiTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Checkout Cart Customer API tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+ */
+class Mage_Checkout_Model_Cart_Customer_ApiTest extends Mage_Checkout_Model_Cart_AbstractTest
+{
+    /**
+     * Test setting customer to a quote.
+     */
+    public function testSet()
+    {
+        $quote = $this->_getQuote();
+
+        $customerData = array(
+            'firstname' => 'testFirstname',
+            'lastname' => 'testLastName',
+            'email' => 'testEmail@mail.com',
+            'mode' => 'guest',
+            'website_id' => '0'
+        );
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartCustomerSet',
+            array(
+                'quoteId' => $quote->getId(),
+                'customerData' => (object)$customerData,
+            )
+        );
+        $this->assertTrue($result);
+
+        $quote->load($quote->getId());
+        $expectedQuoteData = array(
+            'customer_firstname' => 'testFirstname',
+            'customer_lastname' => 'testLastName',
+            'customer_email' => 'testEmail@mail.com',
+        );
+        $diff = array_diff_assoc($expectedQuoteData, $quote->getData());
+        $this->assertEmpty($diff, 'Customer data in quote is incorrect.');
+    }
+
+    /**
+     * Test setting customer address data to a quote.
+     */
+    public function testSetAddresses()
+    {
+        $quote = $this->_getQuote();
+
+        $billingAddress = array(
+            'mode' => 'billing',
+            'firstname' => 'first name',
+            'lastname' => 'last name',
+            'street' => 'street address',
+            'city' => 'city',
+            'postcode' => 'postcode',
+            'country_id' => 'US',
+            'region_id' => 1,
+            'telephone' => '123456789',
+            'is_default_billing' => 1
+        );
+        $shippingAddress = array(
+            'mode' => 'shipping',
+            'firstname' => 'testFirstname',
+            'lastname' => 'testLastname',
+            'company' => 'testCompany',
+            'street' => 'testStreet',
+            'city' => 'testCity',
+            'postcode' => 'testPostcode',
+            'country_id' => 'US',
+            'region_id' => 1,
+            'telephone' => '0123456789',
+            'is_default_shipping' => 0,
+        );
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartCustomerAddresses',
+            array(
+                'quoteId' => $quote->getId(),
+                'customerAddressData' => array(
+                    (object)$billingAddress,
+                    (object)$shippingAddress,
+                ),
+            )
+        );
+        $this->assertTrue($result);
+
+        $quote->load($quote->getId());
+        $billingDiff = array_diff($billingAddress, $quote->getBillingAddress()->getData());
+        $this->assertEmpty($billingDiff, 'Billing address in quote is incorrect.');
+        $shippingDiff = array_diff($shippingAddress, $quote->getShippingAddress()->getData());
+        $this->assertEmpty($shippingDiff, 'Shipping address in quote is incorrect.');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Payment/ApiTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Payment/ApiTest.php
new file mode 100644
index 00000000000..cbe942177e4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Payment/ApiTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Cart payment methods API tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Checkout_Model_Cart_Payment_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test retrieving list of available payment methods for a particular quote
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote.php
+     */
+    public function testShoppingCartPaymentList()
+    {
+        $paymentMethods = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartPaymentList',
+            array(
+                'quoteId' => $this->_getQuote()->getId(),
+            )
+        );
+
+        $this->assertCount(1, $paymentMethods, 'Exactly one payment method was expected.');
+        $this->assertEquals('free', $paymentMethods[0]['code'], '"free" method expected');
+    }
+
+    /**
+     * Test setting payment method for the cart
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_address_saved.php
+     */
+    public function testShoppingCartPaymentMethod()
+    {
+        $paymentMethod = array(
+            'po_number' => null,
+            'method' => 'checkmo',
+            'cc_cid' => null,
+            'cc_owner' => null,
+            'cc_number' => null,
+            'cc_type' => null,
+            'cc_exp_year' => null,
+            'cc_exp_month' => null
+        );
+
+        $result = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartPaymentMethod',
+            array(
+                'quoteId' => $this->_getQuote()->getId(),
+                'paymentData' => (object)$paymentMethod,
+            )
+        );
+
+        $this->assertTrue($result, 'Unable to set payment method');
+    }
+
+    /**
+     * Returns quote generated by fixture
+     *
+     * @return Mage_Sales_Model_Quote
+     */
+    protected function _getQuote()
+    {
+        /** @var Mage_Sales_Model_Resource_Quote_Collection $quoteCollection */
+        $quoteCollection = Mage::getModel('Mage_Sales_Model_Resource_Quote_Collection');
+        /** @var $quote Mage_Sales_Model_Quote */
+        $quote = $quoteCollection->getFirstItem();
+
+        return $quote;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Product/ApiTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Product/ApiTest.php
new file mode 100644
index 00000000000..c637eb37237
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Product/ApiTest.php
@@ -0,0 +1,142 @@
+<?php
+/**
+ * Checkout Cart Product API tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Checkout_Model_Cart_Product_ApiTest extends Mage_Checkout_Model_Cart_AbstractTest
+{
+    /**
+     * Test quote item update.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+     */
+    public function testUpdate()
+    {
+        $quote = $this->_getQuote();
+        $quoteItems = $quote->getAllItems();
+        /** @var Mage_Sales_Model_Quote_Item $quoteItem */
+        $quoteItem = reset($quoteItems);
+        $this->assertEquals(1, $quoteItem->getQty(), 'Quote item should have qty = 1.');
+
+        $qtyToUpdate = 5;
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartProductUpdate',
+            array(
+                'quoteId' => $quote->getId(),
+                'productsData' => array(
+                    (object)array(
+                        'sku' => 'simple',
+                        'qty' => $qtyToUpdate,
+                    )
+                )
+            )
+        );
+
+        $this->assertTrue($soapResult, 'Error during product update in cart via API call');
+        /** @var Mage_Sales_Model_Quote $quoteAfterUpdate */
+        $quoteAfterUpdate = Mage::getModel('Mage_Sales_Model_Quote');
+        $quoteAfterUpdate->load($quote->getId());
+        $quoteItemsUpdated = $quoteAfterUpdate->getAllItems();
+        /** @var Mage_Sales_Model_Quote_Item $quoteItem */
+        $quoteItemUpdated = reset($quoteItemsUpdated);
+        $this->assertEquals($qtyToUpdate, $quoteItemUpdated->getQty(), 'Incorrect quote item quantity after update.');
+    }
+
+    /**
+     * Test quote item remove.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+     */
+    public function testRemove()
+    {
+        $quote = $this->_getQuote();
+        $this->assertCount(1, $quote->getAllItems(), 'Quote should have exactly 1 item.');
+
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartProductRemove',
+            array(
+                'quoteId' => $quote->getId(),
+                'productsData' => array(
+                    (object)array(
+                        'sku' => 'simple',
+                    )
+                )
+            )
+        );
+
+        $this->assertTrue($soapResult, 'Error during product remove from cart via API call');
+        /** @var Mage_Sales_Model_Quote $quoteAfterUpdate */
+        $quoteAfterUpdate = Mage::getModel('Mage_Sales_Model_Quote');
+        $quoteAfterUpdate->load($quote->getId());
+        $this->assertCount(0, $quoteAfterUpdate->getAllItems(), 'Quote item was not deleted.');
+    }
+
+    /**
+     * Test quote item moving from inactive quote to active customer quote.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+     * @magentoDataFixture Mage/Customer/_files/customer.php
+     * @magentoDbIsolation enabled
+     * @magentoConfigIsolation enabled
+     */
+    public function testMoveToCustomerQuote()
+    {
+        /** Prepare data. */
+        $inactiveQuote = $this->_getQuote();
+        $this->assertCount(1, $inactiveQuote->getAllItems(), 'Quote should have exactly 1 item.');
+        $inactiveQuote->setIsActive(0)->setCustomerId(1)->save();
+        $activeQuote = Mage::getModel('Mage_Sales_Model_Quote');
+        $activeQuote->setData(array(
+            'store_id' => 1,
+            'is_active' => 1,
+            'is_multi_shipping' => 0,
+            'customer_id' => 1
+        ));
+        $activeQuote->save();
+
+        /** Move products from inactive quote via API. */
+        $isSuccessful = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartProductMoveToCustomerQuote',
+            array(
+                'quoteId' => $inactiveQuote->getId(),
+                'productsData' => array(
+                    (object)array(
+                        'product_id' => '1'
+                    )
+                )
+            )
+        );
+        $this->assertTrue($isSuccessful, "Product was not moved from inactive quote to active one.");
+
+        /** Ensure that data was saved to DB correctly. */
+        /** @var Mage_Sales_Model_Quote $quoteAfterMove */
+        $quoteAfterMove = Mage::getModel('Mage_Sales_Model_Quote');
+        $quoteAfterMove->load($activeQuote->getId());
+        /** @var Mage_Sales_Model_Resource_Quote_Item_Collection $itemsCollection */
+        $itemsCollection = $quoteAfterMove->getItemsCollection(false);
+        $this->assertCount(1, $itemsCollection->getItems(), 'Product was not moved from inactive quote to active one.');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Shipping/ApiTest.php b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Shipping/ApiTest.php
new file mode 100644
index 00000000000..d6167a2c097
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/Model/Cart/Shipping/ApiTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Tests for shipping method in shopping cart API.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Checkout/_files/quote_with_check_payment.php
+ */
+class Mage_Checkout_Model_Cart_Shipping_ApiTest extends PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        /** Collect rates before requesting them via API. */
+        $this->_getQuoteFixture()->getShippingAddress()->setCollectShippingRates(true)->collectTotals()->save();
+        parent::setUp();
+    }
+
+    /**
+     * Test retrieving of shipping methods applicable to the shopping cart.
+     *
+     */
+    public function testGetShippingMethodsList()
+    {
+        /** Retrieve the list of available shipping methods via API. */
+        $shippingMethodsList = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartShippingList',
+            array(
+                $this->_getQuoteFixture()->getId()
+            )
+        );
+
+        /** Verify the API call results. */
+        $this->assertCount(1, $shippingMethodsList, 'There is exactly 1 shipping method expected.');
+        $expectedItemData = array(
+            'code' => 'flatrate_flatrate',
+            'carrier' => 'flatrate',
+            'carrier_title' => 'Flat Rate',
+            'method' => 'flatrate',
+            'method_title' => 'Fixed',
+            'method_description' => null,
+            'price' => 10
+        );
+        Magento_Test_Helper_Api::checkEntityFields($this, $expectedItemData, reset($shippingMethodsList));
+    }
+
+    /**
+     * Test assigning shipping method to quote.
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testSetShippingMethod()
+    {
+        /** Prepare data. */
+        $this->_getQuoteFixture()->getShippingAddress()->setShippingMethod(null)->save();
+        /** @var Mage_Sales_Model_Quote $quoteBefore */
+        $quoteBefore = Mage::getModel('Mage_Sales_Model_Quote')->load($this->_getQuoteFixture()->getId());
+        $this->assertNull(
+            $quoteBefore->getShippingAddress()->getShippingMethod(),
+            "There should be no shipping method assigned to quote before assigning via API."
+        );
+
+        /** Retrieve the list of available shipping methods via API. */
+        $shippingMethod = 'flatrate_flatrate';
+        $isAdded = Magento_Test_Helper_Api::call(
+            $this,
+            'shoppingCartShippingMethod',
+            array(
+                $this->_getQuoteFixture()->getId(),
+                $shippingMethod
+            )
+        );
+        $this->assertTrue($isAdded, "Shipping method was not assigned to the quote.");
+
+        /** Ensure that data was saved to DB. */
+        /** @var Mage_Sales_Model_Quote $quoteAfter */
+        $quoteAfter = Mage::getModel('Mage_Sales_Model_Quote')->load($this->_getQuoteFixture()->getId());
+        $this->assertEquals(
+            $shippingMethod,
+            $quoteAfter->getShippingAddress()->getShippingMethod(),
+            "Shipping method was assigned to quote incorrectly."
+        );
+    }
+
+    /**
+     * Retrieve the quote object created in fixture.
+     *
+     * @return Mage_Sales_Model_Quote
+     */
+    protected function _getQuoteFixture()
+    {
+        /** @var Mage_Sales_Model_Resource_Quote_Collection $quoteCollection */
+        $quoteCollection = Mage::getModel('Mage_Sales_Model_Resource_Quote_Collection');
+        /** @var Mage_Sales_Model_Quote $quote */
+        $quote = $quoteCollection->getFirstItem();
+        return $quote;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/_files/discount_10percent.php b/dev/tests/integration/testsuite/Mage/Checkout/_files/discount_10percent.php
new file mode 100644
index 00000000000..6fe060ac454
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/_files/discount_10percent.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * SalesRule 10% discount coupon
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var Mage_SalesRule_Model_Rule $salesRule */
+$salesRule = Mage::getModel('Mage_SalesRule_Model_Rule');
+
+$data = array(
+    'name' => 'Test Coupon',
+    'is_active' => true,
+    'website_ids' => array(Mage::app()->getStore()->getWebsiteId()),
+    'customer_group_ids' => array(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID),
+    'coupon_type' => Mage_SalesRule_Model_Rule::COUPON_TYPE_SPECIFIC,
+    'coupon_code' => uniqid(),
+    'simple_action' => Mage_SalesRule_Model_Rule::BY_PERCENT_ACTION,
+    'discount_amount' => 10,
+    'discount_step' => 1,
+);
+
+$salesRule->loadPost($data)->setUseAutoGeneration(false)->save();
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/_files/quote.php b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote.php
new file mode 100644
index 00000000000..f22b6c2f60a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote.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.
+ *
+ * @category    Magento
+ * @package     Mage_Checkout
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$quote = Mage::getModel('Mage_Sales_Model_Quote');
+$quote->setData(array(
+    'store_id' => 1,
+    'is_active' => 0,
+    'is_multi_shipping' => 0
+));
+$quote->save();
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_address.php b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_address.php
new file mode 100644
index 00000000000..6ce6910e660
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_address.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.
+ *
+ * @category    Magento
+ * @package     Mage_Checkout
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+require __DIR__ . '/../../Customer/_files/customer.php';
+require __DIR__ . '/../../Customer/_files/customer_address.php';
+require __DIR__ . '/../../Catalog/_files/products.php';
+
+/** @var Mage_Sales_Model_Quote_Address $quoteShippingAddress */
+$quoteShippingAddress = Mage::getModel('Mage_Sales_Model_Quote_Address');
+$quoteShippingAddress->importCustomerAddress($customerAddress);
+
+/** @var Mage_Sales_Model_Quote $quote */
+$quote = Mage::getModel('Mage_Sales_Model_Quote');
+$quote->setStoreId(1)
+    ->setIsActive(false)
+    ->setIsMultiShipping(false)
+    ->assignCustomerWithAddressChange($customer)
+    ->setShippingAddress($quoteShippingAddress)
+    ->setBillingAddress($quoteShippingAddress)
+    ->setCheckoutMethod($customer->getMode())
+    ->setPasswordHash($customer->encryptPassword($customer->getPassword()))
+    ->addProduct($product->load($product->getId()), 2);
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_address_saved.php b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_address_saved.php
new file mode 100644
index 00000000000..c8ebe691aff
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_address_saved.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Save quote_with_address fixture
+ *
+ * The quote is not saved inside the original fixture. It is later saved inside child fixtures, but along with some
+ * additional data which may break some tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+require 'quote_with_address.php';
+
+$quote->collectTotals()->save();
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_ccsave_payment.php b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_ccsave_payment.php
new file mode 100644
index 00000000000..aa4ce46a90c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_ccsave_payment.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.
+ *
+ * @category    Magento
+ * @package     Mage_Checkout
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+require 'quote_with_address.php';
+/** @var Mage_Sales_Model_Quote $quote */
+
+$quote->getShippingAddress()->setShippingMethod('flatrate_flatrate');
+$quote->getPayment()->setMethod('ccsave');
+
+$quote->collectTotals();
+$quote->save();
+
+$quoteService = new Mage_Sales_Model_Service_Quote($quote);
+$quoteService->getQuote()->getPayment()->setMethod('ccsave');
diff --git a/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_check_payment.php b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_check_payment.php
new file mode 100644
index 00000000000..530f7f4f8a1
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_check_payment.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Checkout
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+require 'quote_with_address.php';
+/** @var Mage_Sales_Model_Quote $quote */
+
+/** @var $rate Mage_Sales_Model_Quote_Address_Rate */
+$rate = Mage::getModel('Mage_Sales_Model_Quote_Address_Rate');
+$rate->setCode('freeshipping_freeshipping');
+$rate->getPrice(1);
+
+$quote->getShippingAddress()->setShippingMethod('freeshipping_freeshipping');
+$quote->getShippingAddress()->addShippingRate($rate);
+$quote->getPayment()->setMethod('checkmo');
+
+$quote->collectTotals();
+$quote->save();
+
+$quoteService = new Mage_Sales_Model_Service_Quote($quote);
+$quoteService->getQuote()->getPayment()->setMethod('checkmo');
diff --git a/app/code/core/Mage/Core/Block/Template/Smarty.php b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_check_payment_rollback.php
similarity index 87%
rename from app/code/core/Mage/Core/Block/Template/Smarty.php
rename to dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_check_payment_rollback.php
index f08d18c79e0..ee4e5738b19 100644
--- a/app/code/core/Mage/Core/Block/Template/Smarty.php
+++ b/dev/tests/integration/testsuite/Mage/Checkout/_files/quote_with_check_payment_rollback.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Rollback for quote_with_check_payment.php fixture.
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -18,14 +20,8 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Mage
- * @package     Mage_Core
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-
-class Mage_Core_Block_Template_Smarty extends Mage_Core_Block_Template
-{
-    
-}
+Mage::unregister('quote');
diff --git a/dev/tests/integration/testsuite/Mage/Cms/Helper/Wysiwyg/ImagesTest.php b/dev/tests/integration/testsuite/Mage/Cms/Helper/Wysiwyg/ImagesTest.php
new file mode 100644
index 00000000000..f86f6758869
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Cms/Helper/Wysiwyg/ImagesTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Cms_Helper_Wysiwyg_ImagesTest extends PHPUnit_Framework_TestCase
+{
+    public function testGetStorageRoot()
+    {
+        /** @var $dir Mage_Core_Model_Dir */
+        $dir = Mage::getObjectManager()->get('Mage_Core_Model_Dir');
+        $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
+        $helper = new Mage_Cms_Helper_Wysiwyg_Images($filesystem);
+        $this->assertStringStartsWith($dir->getDir(Mage_Core_Model_Dir::MEDIA), $helper->getStorageRoot());
+    }
+
+    public function testGetCurrentUrl()
+    {
+        $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
+        $helper = new Mage_Cms_Helper_Wysiwyg_Images($filesystem);
+        $this->assertStringStartsWith('http://localhost/', $helper->getCurrentUrl());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Cms/Model/Wysiwyg/Images/StorageTest.php b/dev/tests/integration/testsuite/Mage/Cms/Model/Wysiwyg/Images/StorageTest.php
index 38f91035eb6..0b48561e6ae 100644
--- a/dev/tests/integration/testsuite/Mage/Cms/Model/Wysiwyg/Images/StorageTest.php
+++ b/dev/tests/integration/testsuite/Mage/Cms/Model/Wysiwyg/Images/StorageTest.php
@@ -65,4 +65,14 @@ class Mage_Cms_Model_Wysiwyg_Images_StorageTest extends PHPUnit_Framework_TestCa
             return;
         }
     }
+
+    public function testGetThumbsPath()
+    {
+        $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
+        $model = new Mage_Cms_Model_Wysiwyg_Images_Storage($filesystem);
+        $this->assertStringStartsWith(
+            realpath(Magento_Test_Bootstrap::getInstance()->getInstallDir()),
+            $model->getThumbsPath()
+        );
+    }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php
index a35eadadb08..43508972b1f 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Block/AbstractTest.php
@@ -424,14 +424,19 @@ class Mage_Core_Block_AbstractTest extends PHPUnit_Framework_TestCase
     public function testGetChildData()
     {
         $parent = $this->_createBlockWithLayout('parent', 'parent');
-        $block = $this->_createBlockWithLayout('block', 'block', 'Mage_Core_Block_Text');
-        $block->setSomeValue('value');
+        $block = $this->_createBlockWithLayout('block', 'block');
+        $block->setSomeProperty('some_value');
         $parent->setChild('block1', $block);
-        $this->assertEquals(
-            array('type' => 'Mage_Core_Block_TextMock', 'some_value' => 'value'),
-            $parent->getChildData('block1')
-        );
-        $this->assertEquals('value', $parent->getChildData('block1', 'some_value'));
+
+        // all child data
+        $actualChildData = $parent->getChildData('block1');
+        $this->assertArrayHasKey('some_property', $actualChildData);
+        $this->assertEquals('some_value', $actualChildData['some_property']);
+
+        // specific child data key
+        $this->assertEquals('some_value', $parent->getChildData('block1', 'some_property'));
+
+        // non-existing child block
         $this->assertNull($parent->getChildData('unknown_block'));
     }
 
@@ -637,27 +642,6 @@ class Mage_Core_Block_AbstractTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(1800, $this->_block->getCacheLifetime());
     }
 
-    /**
-     * App isolation is enabled, because config options object is affected
-     *
-     * @magentoAppIsolation enabled
-     * @magentoDbIsolation enabled
-     */
-    public function testGetVar()
-    {
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__DIR__) . '/Model/_files/design/'
-        ));
-        $themeUtility->registerThemes()->setDesignTheme('test/default', 'frontend');
-
-        $this->assertEquals('Core Value1', $this->_block->getVar('var1'));
-        $this->assertEquals('value1', $this->_block->getVar('var1', 'Namespace_Module'));
-        $this->_block->setModuleName('Namespace_Module');
-        $this->assertEquals('value1', $this->_block->getVar('var1'));
-        $this->assertEquals(false, $this->_block->getVar('unknown_var'));
-    }
-
     /**
      * Create <N> sample blocks
      *
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/TemplateTest.php b/dev/tests/integration/testsuite/Mage/Core/Block/TemplateTest.php
index d467916cd9e..858e287fb0b 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/TemplateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Block/TemplateTest.php
@@ -60,30 +60,6 @@ class Mage_Core_Block_TemplateTest extends PHPUnit_Framework_TestCase
         $this->assertEquals('value', $this->_block->getTemplate());
     }
 
-    /**
-     * @magentoConfigFixture frontend/design/theme/full_name default/demo
-     * @magentoConfigFixture adminhtml/design/theme/full_name default/basic
-     * @magentoAppIsolation enabled
-     */
-    public function testGetTemplateFile()
-    {
-        Mage::app()->getConfig()->getOptions()->setDesignDir(__DIR__ . DIRECTORY_SEPARATOR . '_files');
-
-        // with template
-        $template = 'dummy.phtml';
-        $this->_block->setTemplate($template);
-        $file = $this->_block->getTemplateFile();
-        $this->assertContains('frontend', $file);
-        $this->assertStringEndsWith($template, $file);
-
-
-        // change area
-        $this->_block->setArea('adminhtml');
-        $file = $this->_block->getTemplateFile();
-        $this->assertContains('adminhtml', $file);
-        $this->assertStringEndsWith($template, $file);
-    }
-
     public function testGetArea()
     {
         $this->assertEquals('frontend', $this->_block->getArea());
@@ -93,22 +69,6 @@ class Mage_Core_Block_TemplateTest extends PHPUnit_Framework_TestCase
         $this->assertEquals('another_area', $this->_block->getArea());
     }
 
-    /**
-     * @magentoAppIsolation enabled
-     * @covers Mage_Core_Block_Template::assign
-     * @covers Mage_Core_Block_Template::setScriptPath
-     * @covers Mage_Core_Block_Template::fetchView
-     */
-    public function testAssign()
-    {
-        Mage::app()->getConfig()->getOptions()->setDesignDir(dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files');
-
-        $this->_block->assign(array('varOne' => 'value1', 'varTwo' => 'value2'))
-            ->setScriptPath(__DIR__ . DIRECTORY_SEPARATOR . '_files');
-        $template = __DIR__ . DIRECTORY_SEPARATOR . '_files/template_test_assign.phtml';
-        $this->assertEquals('value1, value2', $this->_block->fetchView($template));
-    }
-
     public function testGetDirectOutput()
     {
         $this->assertFalse($this->_block->getDirectOutput());
@@ -124,34 +84,6 @@ class Mage_Core_Block_TemplateTest extends PHPUnit_Framework_TestCase
         $this->assertFalse($this->_block->getShowTemplateHints());
     }
 
-    /**
-     * @covers Mage_Core_Block_Template::fetchView
-     * @covers Mage_Core_Block_Abstract::setLayout
-     * @covers Mage_Core_Block_Abstract::getLayout
-     * @see testAssign
-     */
-    public function testFetchView()
-    {
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->setDirectOutput(true);
-        $this->_block->setLayout($layout);
-        $this->assertTrue($this->_block->getDirectOutput());
-
-        $this->assertEmpty($this->_block->fetchView(__DIR__ . DS . uniqid('invalid_filename.phtml')));
-    }
-
-    /**
-     * @magentoAppIsolation enabled
-     */
-    public function testRenderView()
-    {
-        $this->assertEmpty($this->_block->renderView());
-        Mage::app()->getConfig()->getOptions()->setDesignDir(__DIR__ . DIRECTORY_SEPARATOR . '_files');
-        Mage::getDesign()->setDesignTheme('default/demo');
-        $this->_block->setTemplate('dummy.phtml');
-        $this->assertEquals('1234567890', $this->_block->renderView());
-    }
-
     /**
      * @covers Mage_Core_Block_Template::_toHtml
      * @covers Mage_Core_Block_Abstract::toHtml
diff --git a/dev/tests/integration/testsuite/Mage/Core/Controller/RequestHttpTest.php b/dev/tests/integration/testsuite/Mage/Core/Controller/RequestHttpTest.php
index af7170b7de1..06d50829979 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Controller/RequestHttpTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Controller/RequestHttpTest.php
@@ -93,18 +93,12 @@ class Mage_Core_Controller_RequestHttpTest extends PHPUnit_Framework_TestCase
     public function testIsDirectAccessFrontendName()
     {
         $this->assertFalse($this->_model->isDirectAccessFrontendName('test'));
-        $this->assertFalse(
-            $this->_model->isDirectAccessFrontendName('api'),
-            "Mage_Core_Controller_RequestHttp should not be used in API area."
-        );
+        $this->assertTrue($this->_model->isDirectAccessFrontendName('api'));
     }
 
     public function testGetDirectFrontNames()
     {
-        $this->assertEmpty(
-            $this->_model->getDirectFrontNames(),
-            "After API module removal there should not be areas with direct front name."
-        );
+        $this->assertContains('api', array_keys($this->_model->getDirectFrontNames()));
     }
 
     public function testGetOriginalRequest()
diff --git a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/ActionTest.php b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/ActionTest.php
index 9a9fbde137b..0418d124ad5 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/ActionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Controller/Varien/ActionTest.php
@@ -276,11 +276,10 @@ class Mage_Core_Controller_Varien_ActionTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * @magentoConfigFixture               install/design/theme/full_name   default/basic
-     * @magentoConfigFixture               adminhtml/design/theme/full_name default/basic
-     * @magentoConfigFixture current_store design/theme/full_name           default/demo
-     * @magentoAppIsolation  enabled
-     *
+     * @magentoConfigFixture install/design/theme/full_name default/basic
+     * @magentoConfigFixture frontend/design/theme/full_name default/demo
+     * @magentoConfigFixture adminhtml/design/theme/full_name default/basic
+     * @magentoAppIsolation enabled
      * @dataProvider controllerAreaDesignDataProvider
      *
      * @param string $controllerClass
@@ -291,6 +290,7 @@ class Mage_Core_Controller_Varien_ActionTest extends PHPUnit_Framework_TestCase
     public function testPreDispatch($controllerClass, $expectedArea, $expectedStore, $expectedDesign)
     {
         Mage::getConfig()->setCurrentAreaCode($expectedArea);
+
         /** @var $controller Mage_Core_Controller_Varien_Action */
         $controller = Mage::getObjectManager()->create($controllerClass,
             array(
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/App/AreaTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/App/AreaTest.php
index 9eb4c5facdc..1a8700ecedf 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/App/AreaTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/App/AreaTest.php
@@ -60,30 +60,6 @@ class Mage_Core_Model_App_AreaTest extends PHPUnit_Framework_TestCase
         $this->assertSame($design, Mage::getDesign());
     }
 
-    /**
-     * @magentoConfigFixture adminhtml/design/theme/full_name default/basic
-     * @magentoAppIsolation enabled
-     */
-    public function testDetectDesignGlobalConfig()
-    {
-        /** @var $model Mage_Core_Model_App_Area */
-        $model = Mage::getModel('Mage_Core_Model_App_Area', array('areaCode' => 'adminhtml'));
-        $model->detectDesign();
-        $theme = Mage::getDesign()->getConfigurationDesignTheme('adminhtml', array('useId' => false));
-        $this->assertEquals('default/basic', $theme);
-    }
-
-    /**
-     * @magentoConfigFixture current_store design/theme/full_name default/blank
-     * @magentoAppIsolation enabled
-     */
-    public function testDetectDesignStoreConfig()
-    {
-        $this->_model->detectDesign();
-        $theme = Mage::getDesign()->getConfigurationDesignTheme('frontend', array('useId' => false));
-        $this->assertEquals('default/blank', $theme);
-    }
-
     // @codingStandardsIgnoreStart
     /**
      * @magentoConfigFixture current_store design/theme/ua_regexp a:1:{s:1:"_";a:2:{s:6:"regexp";s:10:"/firefox/i";s:5:"value";s:14:"default/modern";}}
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/AppTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/AppTest.php
index 394cd9a1e8a..ffa98abf307 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/AppTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/AppTest.php
@@ -62,13 +62,12 @@ class Mage_Core_Model_AppTest extends PHPUnit_Framework_TestCase
     /**
      * @covers Mage_Core_Model_App::_initCache
      *
-     * @magentoConfigFixture global/cache/id_prefix test
      * @magentoAppIsolation enabled
      */
     public function testInit()
     {
         $this->assertNull($this->_model->getConfig());
-        $this->_model->init('');
+        $this->_model->init(Magento_Test_Bootstrap::getInstance()->getInitParams());
         $this->assertInstanceOf('Mage_Core_Model_Config', $this->_model->getConfig());
         $this->assertNotEmpty($this->_model->getConfig()->getNode());
         $this->assertContains(Mage_Core_Model_App::ADMIN_STORE_ID, array_keys($this->_model->getStores(true)));
@@ -77,7 +76,19 @@ class Mage_Core_Model_AppTest extends PHPUnit_Framework_TestCase
         $objectManager = Mage::getObjectManager();
         /** @var $cache Mage_Core_Model_Cache */
         $cache = $objectManager->get('Mage_Core_Model_Cache');
-        $this->assertAttributeEquals('test', '_idPrefix', $cache);
+        $appCache = $this->_model->getCacheInstance();
+        $this->assertSame($appCache, $cache);
+    }
+
+    /**
+     * @magentoAppIsolation enabled
+     */
+    public function testBaseInit()
+    {
+        $this->assertNull($this->_model->getConfig());
+        $this->_model->baseInit(Magento_Test_Bootstrap::getInstance()->getInitParams());
+        $this->assertInstanceOf('Mage_Core_Model_Config', $this->_model->getConfig());
+        $this->assertNotEmpty($this->_model->getConfig()->getNode());
     }
 
     /**
@@ -88,11 +99,11 @@ class Mage_Core_Model_AppTest extends PHPUnit_Framework_TestCase
         if (!Magento_Test_Bootstrap::canTestHeaders()) {
             $this->markTestSkipped('Can\'t test application run without sending headers');
         }
-
-        $_SERVER['HTTP_HOST'] = 'localhost';
-        $this->_mageModel->getRequest()->setRequestUri('core/index/index');
-        $this->_mageModel->run(array());
-        $this->assertTrue($this->_mageModel->getRequest()->isDispatched());
+        $request = new Magento_Test_Request();
+        $request->setRequestUri('core/index/index');
+        $this->_mageModel->setRequest($request);
+        $this->_mageModel->run(Magento_Test_Bootstrap::getInstance()->getInitParams());
+        $this->assertTrue($request->isDispatched());
     }
 
     public function testIsInstalled()
@@ -100,20 +111,6 @@ class Mage_Core_Model_AppTest extends PHPUnit_Framework_TestCase
         $this->assertTrue($this->_mageModel->isInstalled());
     }
 
-    /**
-     * @magentoAppIsolation enabled
-     * @expectedException Magento_Exception
-     * @expectedExceptionMessage Application is not installed yet, please complete the installation first.
-     */
-    public function testRequireInstalledInstance()
-    {
-        $this->_model->baseInit(array(
-            Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA
-                => sprintf(Mage_Core_Model_Config::CONFIG_TEMPLATE_INSTALL_DATE, 'invalid')
-        ));
-        $this->_model->requireInstalledInstance();
-    }
-
     public function testGetCookie()
     {
         $this->assertInstanceOf('Mage_Core_Model_Cookie', $this->_model->getCookie());
@@ -396,7 +393,7 @@ class Mage_Core_Model_AppTest extends PHPUnit_Framework_TestCase
     {
         $objectManager = Mage::getObjectManager();
         $this->_model  = $objectManager->get('Mage_Core_Model_App');
-        $this->_model->loadDiConfiguration('frontend');
+        $this->_model->getConfig()->loadDiConfiguration('frontend');
         $testInstance  = $objectManager->create('Mage_Backend_Block_Widget_Grid_ColumnSet');
         $this->assertAttributeInstanceOf('Mage_DesignEditor_Model_Url_NavigationMode', '_urlBuilder', $testInstance);
     }
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Config/OptionsTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Config/OptionsTest.php
deleted file mode 100644
index eb0b2b8c92a..00000000000
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Config/OptionsTest.php
+++ /dev/null
@@ -1,151 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Magento
- * @package     Mage_Core
- * @subpackage  integration_tests
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-class Mage_Core_Model_Config_OptionsTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var Mage_Core_Model_Config_Options
-     */
-    protected $_model;
-
-    protected static $_keys = array(
-        'app_dir'     => 'app',
-        'base_dir'    => 'base',
-        'code_dir'    => 'code',
-        'design_dir'  => 'design',
-        'etc_dir'     => 'etc',
-        'lib_dir'     => 'lib',
-        'locale_dir'  => 'locale',
-        'pub_dir'     => 'pub',
-        'js_dir'      => 'js',
-        'media_dir'   => 'media',
-        'var_dir'     => 'var',
-        'tmp_dir'     => 'tmp',
-        'cache_dir'   => 'cache',
-        'log_dir'     => 'log',
-        'session_dir' => 'session',
-        'upload_dir'  => 'upload',
-        'export_dir'  => 'export',
-    );
-
-    protected function setUp()
-    {
-        $this->_model = Mage::getModel('Mage_Core_Model_Config_Options');
-    }
-
-    protected function tearDown()
-    {
-        $this->_model = null;
-    }
-
-    public function testConstruct()
-    {
-        $data = $this->_model->getData();
-        foreach (array_keys(self::$_keys) as $key) {
-            $this->assertArrayHasKey($key, $data);
-            unset($data[$key]);
-        }
-        $this->assertEmpty($data);
-    }
-
-    public function testGetDir()
-    {
-        foreach (self::$_keys as $full => $partial) {
-            $this->assertEquals($this->_model->getData($full), $this->_model->getDir($partial));
-        }
-    }
-
-    /**
-     * @expectedException Mage_Core_Exception
-     */
-    public function testGetDirException()
-    {
-        $this->_model->getDir('invalid');
-    }
-
-    /**
-     * @covers Mage_Core_Model_Config_Options::getAppDir
-     * @covers Mage_Core_Model_Config_Options::getBaseDir
-     * @covers Mage_Core_Model_Config_Options::getCodeDir
-     * @covers Mage_Core_Model_Config_Options::getDesignDir
-     * @covers Mage_Core_Model_Config_Options::getEtcDir
-     * @covers Mage_Core_Model_Config_Options::getLibDir
-     * @covers Mage_Core_Model_Config_Options::getMediaDir
-     * @covers Mage_Core_Model_Config_Options::getVarDir
-     * @covers Mage_Core_Model_Config_Options::getTmpDir
-     * @covers Mage_Core_Model_Config_Options::getCacheDir
-     * @covers Mage_Core_Model_Config_Options::getLogDir
-     * @covers Mage_Core_Model_Config_Options::getSessionDir
-     * @covers Mage_Core_Model_Config_Options::getUploadDir
-     * @covers Mage_Core_Model_Config_Options::getExportDir
-     * @dataProvider getGettersDataProvider
-     * @param string $method
-     */
-    public function testGetters($method)
-    {
-        $dir = $this->_model->$method();
-        $this->assertFileExists($dir, "Method '{$method}()' returned directory that doesn't exist: '{$dir}'");
-    }
-
-    /**
-     * @return array
-     */
-    public function getGettersDataProvider()
-    {
-        return array(
-            array('getAppDir'),
-            array('getBaseDir'),
-            array('getCodeDir'),
-            array('getDesignDir'),
-            array('getEtcDir'),
-            array('getLibDir'),
-            array('getMediaDir'),
-            array('getVarDir'),
-            array('getTmpDir'),
-            array('getCacheDir'),
-            array('getLogDir'),
-            array('getSessionDir'),
-            array('getUploadDir'),
-            array('getExportDir'),
-        );
-    }
-
-    public function testCreateDirIfNotExists()
-    {
-        $var = $this->_model->getVarDir();
-
-        $sampleDir = uniqid($var);
-        $this->assertTrue($this->_model->createDirIfNotExists($sampleDir));
-        $this->assertTrue($this->_model->createDirIfNotExists($sampleDir));
-        rmdir($sampleDir);
-
-        $sampleFile = "{$var}/" . uniqid('file') . '.txt';
-        file_put_contents($sampleFile, '1');
-        $this->assertFalse($this->_model->createDirIfNotExists($sampleFile));
-        unlink($sampleFile);
-    }
-}
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ConfigFactoryTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ConfigFactoryTest.php
index a61dbfb6cc7..77afd5eaad2 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/ConfigFactoryTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/ConfigFactoryTest.php
@@ -33,20 +33,13 @@
  */
 class Mage_Core_Model_ConfigFactoryTest extends PHPUnit_Framework_TestCase
 {
-    protected static $_options = array();
-
     /** @var Mage_Core_Model_Config */
     protected $_model;
 
-    public static function setUpBeforeClass()
-    {
-        self::$_options = Magento_Test_Bootstrap::getInstance()->getAppOptions();
-    }
-
     public function setUp()
     {
         $this->_model = Mage::getModel('Mage_Core_Model_Config');
-        $this->_model->init(self::$_options);
+        $this->_model->init();
     }
 
     protected function tearDown()
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ConfigTest.php
index 8241dc7adf8..27a6830eba6 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/ConfigTest.php
@@ -34,11 +34,9 @@
  */
 class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
 {
-    protected static $_options = array();
-
-    public static function setUpBeforeClass()
+    protected function setUp()
     {
-        self::$_options = Magento_Test_Bootstrap::getInstance()->getAppOptions();
+        Mage::app()->getCacheInstance()->banUse('config');
     }
 
     public function testGetResourceModel()
@@ -46,24 +44,11 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
         $this->assertInstanceOf('Mage_Core_Model_Resource_Config', $this->_createModel(true)->getResourceModel());
     }
 
-    public function testGetOptions()
-    {
-        $this->assertInstanceOf('Mage_Core_Model_Config_Options', $this->_createModel(true)->getOptions());
-    }
-
-    public function testSetOptions()
-    {
-        $model = $this->_createModel();
-        $key = uniqid('key');
-        $model->setOptions(array($key  => 'value'));
-        $this->assertEquals('value', $model->getOptions()->getData($key));
-    }
-
     public function testInit()
     {
         $model = $this->_createModel();
         $this->assertFalse($model->getNode());
-        $model->init(self::$_options);
+        $model->init();
         $this->assertInstanceOf('Varien_Simplexml_Element', $model->getNode());
     }
 
@@ -71,7 +56,6 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
     {
         $model = $this->_createModel();
         $this->assertFalse($model->getNode());
-        $model->setOptions(self::$_options);
         $model->loadBase();
         $this->assertInstanceOf('Varien_Simplexml_Element', $model->getNode('global'));
     }
@@ -79,16 +63,18 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
     /**
      * @param string $etcDir
      * @param array $configOptions
-     * @param string $expectedNode
      * @param string $expectedValue
+     * @param string $expectedNode
      * @dataProvider loadBaseLocalConfigDataProvider
      */
-    public function testLoadBaseLocalConfig($etcDir, array $configOptions, $expectedNode, $expectedValue)
-    {
-        $configOptions['etc_dir'] = __DIR__ . "/_files/local_config/{$etcDir}";
-        /** @var $model Mage_Core_Model_Config */
-        $model = Mage::getModel('Mage_Core_Model_Config');
-        $model->setOptions($configOptions);
+    public function testLoadBaseLocalConfig($etcDir, array $configOptions, $expectedValue,
+        $expectedNode = 'global/resources/core_setup/connection/model'
+    ) {
+        $configOptions[Mage_Core_Model_App::INIT_OPTION_DIRS] = array(
+            Mage_Core_Model_Dir::CONFIG => __DIR__ . "/_files/local_config/{$etcDir}",
+        );
+        $model = $this->_createModelWithApp($configOptions);
+
         $model->loadBase();
         $this->assertInstanceOf('Varien_Simplexml_Element', $model->getNode($expectedNode));
         $this->assertEquals($expectedValue, (string)$model->getNode($expectedNode));
@@ -99,53 +85,61 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
      */
     public function loadBaseLocalConfigDataProvider()
     {
+        $extraConfigData = '
+            <root>
+                <global>
+                    <resources>
+                        <core_setup>
+                            <connection>
+                                <model>overridden</model>
+                            </connection>
+                        </core_setup>
+                    </resources>
+                </global>
+            </root>
+        ';
         return array(
             'no local config file & no custom config file' => array(
-                'no_local_config_no_custom_config',
-                array(Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_FILE => ''),
-                'a/value',
+                'no_local_config',
+                array(),
                 'b',
             ),
             'no local config file & custom config file' => array(
-                'no_local_config_custom_config',
-                array(Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_FILE => 'custom/local.xml'),
-                'a',
-                '',
+                'no_local_config',
+                array(Mage_Core_Model_Config::INIT_OPTION_EXTRA_FILE => 'custom/local.xml'),
+                'b',
             ),
             'no local config file & custom config data' => array(
-                'no_local_config_no_custom_config',
-                array(
-                    Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA
-                        => '<root><a><value>overridden</value></a></root>'
-                ),
-                'a/value',
+                'no_local_config',
+                array(Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA => $extraConfigData),
                 'overridden',
             ),
             'local config file & no custom config file' => array(
-                'local_config_no_custom_config',
-                array(Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_FILE => ''),
-                'value',
+                'local_config',
+                array(),
                 'local',
             ),
             'local config file & custom config file' => array(
-                'local_config_custom_config',
-                array(Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_FILE => 'custom/local.xml'),
-                'value',
+                'local_config',
+                array(Mage_Core_Model_Config::INIT_OPTION_EXTRA_FILE => 'custom/local.xml'),
                 'custom',
             ),
-            'local config file & invalid custom config file' => array(
-                'local_config_custom_config',
-                array(Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_FILE => 'custom/invalid.pattern.xml'),
-                'value',
+            'local config file & prohibited custom config file' => array(
+                'local_config',
+                array(Mage_Core_Model_Config::INIT_OPTION_EXTRA_FILE => 'custom/prohibited.filename.xml'),
                 'local',
             ),
             'local config file & custom config data' => array(
-                'local_config_custom_config',
+                'local_config',
+                array(Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA => $extraConfigData),
+                'overridden',
+            ),
+            'local config file & custom config file & custom config data' => array(
+                'local_config',
                 array(
-                    Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_FILE => 'custom/local.xml',
-                    Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA => '<root><value>overridden</value></root>',
+                    Mage_Core_Model_Config::INIT_OPTION_EXTRA_FILE => 'custom/local.xml',
+                    Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA => $extraConfigData,
                 ),
-                'value',
                 'overridden',
             ),
         );
@@ -156,45 +150,56 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
         if (date_default_timezone_get() != 'UTC') {
             $this->markTestSkipped('Test requires "UTC" to be the default timezone.');
         }
-        /** @var $model Mage_Core_Model_Config */
-        $model = Mage::getModel('Mage_Core_Model_Config');
-        $model->setOptions(array(
-            Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA
+
+        $options = array(
+            Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA
                 => sprintf(Mage_Core_Model_Config::CONFIG_TEMPLATE_INSTALL_DATE, 'Fri, 21 Dec 2012 00:00:00 +0000')
-        ));
+        );
+        $model = $this->_createModelWithApp($options);
+
         $model->loadBase();
         $this->assertEquals(1356048000, $model->getInstallDate());
     }
 
     public function testLoadBaseInstallDateInvalid()
     {
-        /** @var $model Mage_Core_Model_Config */
-        $model = Mage::getModel('Mage_Core_Model_Config');
-        $model->setOptions(array(
-            Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA
+        $options = array(
+            Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA
                 => sprintf(Mage_Core_Model_Config::CONFIG_TEMPLATE_INSTALL_DATE, 'invalid')
-        ));
+        );
+        $model = $this->_createModelWithApp($options);
+
         $model->loadBase();
         $this->assertEmpty($model->getInstallDate());
     }
 
     public function testLoadLocales()
     {
-        $model = Mage::getModel('Mage_Core_Model_Config');
-        $model->init(array(
-            'locale_dir' => dirname(__FILE__) . '/_files/locale'
-        ));
+        $options = array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::LOCALE => __DIR__ . '/_files/locale',
+            )
+        );
+        $model = $this->_createModelWithApp($options);
+
+        $model->loadBase();
         $model->loadLocales();
         $this->assertInstanceOf('Mage_Core_Model_Config_Element', $model->getNode('global/locale'));
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testLoadModulesCache()
     {
-        $model = $this->_createModel();
-        $model->setOptions(array(
-            Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA
+        $options = array(
+            Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA
                 => sprintf(Mage_Core_Model_Config::CONFIG_TEMPLATE_INSTALL_DATE, 'Wed, 21 Nov 2012 03:26:00 +0000')
-        ));
+        );
+        $model = $this->_createModelWithApp($options);
+
+        Mage::app()->getCacheInstance()->allowUse('config');
+
         $model->loadBase();
         $this->assertTrue($model->loadModulesCache());
         $this->assertInstanceOf('Mage_Core_Model_Config_Element', $model->getNode());
@@ -203,7 +208,6 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
     public function testLoadModules()
     {
         $model = $this->_createModel();
-        $model->setOptions(self::$_options);
         $model->loadBase();
         $this->assertFalse($model->getNode('modules'));
         $model->loadModules();
@@ -214,11 +218,12 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
 
     public function testLoadModulesLocalConfigPrevails()
     {
-        $model = $this->_createModel();
-        $model->setOptions(array(
-            Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA
+        $options = array(
+            Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA
                 => '<config><modules><Mage_Core><active>false</active></Mage_Core></modules></config>'
-        ));
+        );
+        $model = $this->_createModelWithApp($options);
+
         $model->loadBase();
         $model->loadModules();
 
@@ -231,7 +236,6 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
     {
         $model = $this->_createModel();
         $this->assertFalse($model->isLocalConfigLoaded());
-        $model->setOptions(self::$_options);
         $model->loadBase();
         $this->assertTrue($model->isLocalConfigLoaded());
     }
@@ -246,7 +250,6 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
 
         try {
             $model = $this->_createModel();
-            $model->setOptions(self::$_options);
             $model->loadBase();
             $model->loadModules();
 
@@ -262,15 +265,21 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
 
     public function testReinitBaseConfig()
     {
-        $model = $this->_createModel();
-        $options = self::$_options;
-        $options[Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA] = '<config><test>old_value</test></config>';
-        $model->setOptions($options);
+        $options = Magento_Test_Bootstrap::getInstance()->getInitParams();
+        $options[Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA] = '<config><test>old_value</test></config>';
+
+        $objectManager = new Magento_Test_ObjectManager();
+        $model = $this->_createModelWithApp($options, $objectManager);
+
+        /** @var $app Mage_Core_Model_App */
+        $app = $objectManager->get('Mage_Core_Model_App');
+
         $model->loadBase();
         $this->assertEquals('old_value', $model->getNode('test'));
 
-        $options[Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA] = '<config><test>new_value</test></config>';
-        $model->setOptions($options);
+        $options[Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA] = '<config><test>new_value</test></config>';
+        $app->init($options);
+
         $model->reinit();
         $this->assertEquals('new_value', $model->getNode('test'));
     }
@@ -280,8 +289,13 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
         $this->assertInstanceOf('Varien_Cache_Core', $this->_createModel()->getCache());
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testSaveCache()
     {
+        Mage::app()->getCacheInstance()->allowUse('config');
+
         $model = $this->_createModel(true);
         $model->removeCache();
         $this->assertFalse($model->loadCache());
@@ -291,8 +305,13 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
         $this->assertInstanceOf('Mage_Core_Model_Config_Element', $model->getNode());
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testRemoveCache()
     {
+        Mage::app()->getCacheInstance()->allowUse('config');
+
         $model = $this->_createModel();
         $model->removeCache();
         $this->assertFalse($model->loadCache());
@@ -309,7 +328,7 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
     {
         $model = $this->_createModel();
         $this->assertFalse($model->getNode());
-        $model->init(self::$_options);
+        $model->init();
         $this->assertInstanceOf('Mage_Core_Model_Config_Element', $model->getNode());
         $this->assertInstanceOf('Mage_Core_Model_Config_Element', $model->getNode(null, 'store', 1));
         $this->assertInstanceOf('Mage_Core_Model_Config_Element', $model->getNode(null, 'website', 1));
@@ -317,8 +336,7 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
 
     public function testSetNode()
     {
-        $model = $this->_createModel();
-        $model->init(self::$_options);
+        $model = $this->_createModel(true);
         /* some existing node should be used */
         $model->setNode('admin/routers/adminhtml/use', 'test');
         $this->assertEquals('test', (string) $model->getNode('admin/routers/adminhtml/use'));
@@ -344,26 +362,11 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
         }
     }
 
-    public function testGetTempVarDir()
-    {
-        $this->assertTrue(is_dir($this->_createModel()->getTempVarDir()));
-    }
-
-    public function testGetDistroServerVars()
+    public function testGetDistroBaseUrl()
     {
         $_SERVER['SCRIPT_NAME'] = __FILE__;
         $_SERVER['HTTP_HOST'] = 'example.com';
-        $vars = $this->_createModel()->getDistroServerVars();
-        $this->assertArrayHasKey('root_dir', $vars);
-        $this->assertArrayHasKey('app_dir', $vars);
-        $this->assertArrayHasKey('var_dir', $vars);
-        $this->assertArrayHasKey('base_url', $vars);
-        $this->assertEquals('http://example.com/', $vars['base_url']);
-    }
-
-    public function testSubstDistroServerVars()
-    {
-        $this->assertEquals('http://localhost/', $this->_createModel()->substDistroServerVars('{{base_url}}'));
+        $this->assertEquals('http://example.com/', $this->_createModel()->getDistroBaseUrl());
     }
 
     public function testGetModuleConfig()
@@ -373,27 +376,6 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
         $this->assertInstanceOf('Mage_Core_Model_Config_Element', $model->getModuleConfig('Mage_Core'));
     }
 
-    public function testGetVarDir()
-    {
-        $dir = $this->_createModel()->getVarDir();
-        $this->assertTrue(is_dir($dir));
-        $this->assertTrue(is_writable($dir));
-    }
-
-    public function testCreateDirIfNotExists()
-    {
-        $model = $this->_createModel();
-        $dir = $model->getVarDir() . DIRECTORY_SEPARATOR . uniqid('dir');
-        try {
-            $this->assertFalse(is_dir($dir));
-            $this->assertTrue($model->createDirIfNotExists($dir));
-            rmdir($dir);
-        } catch (Exception $e) {
-            rmdir($dir);
-            throw $e;
-        }
-    }
-
     public function testGetModuleDir()
     {
         $model = $this->_createModel(true);
@@ -531,17 +513,37 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
         $this->assertObjectHasAttribute('password', $fieldset);
     }
 
+    /**
+     * Creates Mage_Core_Model_Config model with initialized Mage_Core_Model_App
+     *
+     * @param array $appOptions
+     * @param Magento_Test_ObjectManager $objectManager
+     * @return Mage_Core_Model_Config
+     */
+    protected function _createModelWithApp(array $appOptions, Magento_Test_ObjectManager $objectManager = null)
+    {
+        $baseOptions = Magento_Test_Bootstrap::getInstance()->getInitParams();
+        $appOptions = array_replace_recursive($baseOptions, $appOptions);
+        $objectManager = $objectManager ?: new Magento_Test_ObjectManager();
+        /** @var $app Mage_Core_Model_App */
+        $app = $objectManager->get('Mage_Core_Model_App');
+        $app->init($appOptions);
+        return $objectManager->create('Mage_Core_Model_Config');
+    }
+
     /**
      * Instantiate Mage_Core_Model_Config and initialize (load configuration) if needed
      *
      * @param bool $initialize
+     * @param array $arguments
      * @return Mage_Core_Model_Config
      */
-    protected function _createModel($initialize = false)
+    protected function _createModel($initialize = false, array $arguments = array())
     {
-        $model = Mage::getModel('Mage_Core_Model_Config');
+        /** @var $model Mage_Core_Model_Config */
+        $model = Mage::getModel('Mage_Core_Model_Config', $arguments);
         if ($initialize) {
-            $model->init(self::$_options);
+            $model->init();
         }
         return $model;
     }
@@ -557,13 +559,12 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
 
     /**
      * Check if areas loaded correctly from configuration
-     *
-     * @magentoAppIsolation enabled
-     * @magentoDataFixture Mage/Core/_files/load_configuration.php
      */
     public function testGetAreas()
     {
-        $allowedAreas = Mage::app()->getConfig()->getAreas();
+        $model = $this->_createModel(true, array('sourceData' => __DIR__ . '/../_files/etc/config.xml'));
+
+        $allowedAreas = $model->getAreas();
         $this->assertNotEmpty($allowedAreas, 'Areas are not initialized');
 
         $this->assertArrayHasKey('test_area1', $allowedAreas, 'Test area #1 is not loaded');
@@ -590,13 +591,12 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
 
     /**
      * Check if routers loaded correctly from configuration
-     *
-     * @magentoAppIsolation enabled
-     * @magentoDataFixture Mage/Core/_files/load_configuration.php
      */
     public function testGetRouters()
     {
-        $loadedRouters = Mage::app()->getConfig()->getRouters();
+        $model = $this->_createModel(true, array('sourceData' => __DIR__ . '/../_files/etc/config.xml'));
+
+        $loadedRouters = $model->getRouters();
         $this->assertArrayHasKey('test_router1', $loadedRouters, 'Test router #1 is not initialized in test area.');
         $this->assertArrayHasKey('test_router2', $loadedRouters, 'Test router #2 is not initialized in test area.');
 
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/FallbackTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/FallbackTest.php
index 1b146602498..0970a81696f 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/FallbackTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/FallbackTest.php
@@ -27,6 +27,53 @@
 
 class Mage_Core_Model_Design_FallbackTest extends PHPUnit_Framework_TestCase
 {
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testConstructException()
+    {
+        $dirs = new Mage_Core_Model_Dir(__DIR__);
+        Mage::getObjectManager()->create(
+            'Mage_Core_Model_Design_Fallback',
+            array(
+                'dirs' => $dirs,
+                'params' => array()
+            )
+        );
+    }
+
+    /**
+     * @covers Mage_Core_Model_Design_Fallback::getArea
+     * @covers Mage_Core_Model_Design_Fallback::getTheme
+     * @covers Mage_Core_Model_Design_Fallback::getLocale
+     */
+    public function testGetters()
+    {
+        $theme = 't';
+        $themeModel = $this->getMock('Mage_Core_Model_Theme', array('getThemeCode'), array(), '', false);
+        $themeModel->expects($this->any())
+            ->method('getThemeCode')
+            ->will($this->returnValue($theme));
+
+        $dirs = new Mage_Core_Model_Dir(__DIR__);
+        $stub = array(
+            'themeConfig' => 'stub',
+            'area' => 'a',
+            'themeModel' => $themeModel,
+            'locale' => 'l',
+        );
+        $model = Mage::getObjectManager()->create(
+            'Mage_Core_Model_Design_Fallback',
+            array(
+                'dirs' => $dirs,
+                'params' => $stub
+            )
+        );
+        $this->assertEquals('a', $model->getArea());
+        $this->assertEquals($theme, $model->getTheme());
+        $this->assertEquals('l', $model->getLocale());
+    }
+
     /**
      * Build a model to test
      *
@@ -37,15 +84,14 @@ class Mage_Core_Model_Design_FallbackTest extends PHPUnit_Framework_TestCase
      */
     protected function _buildModel($area, $themePath, $locale)
     {
-        $testDir = implode(DS, array(dirname( __DIR__), '_files', 'fallback'));
-        Mage::getConfig()->getOptions()->addData(array(
-            'js_dir'     => implode(DS, array($testDir, 'pub', 'js')),
-            'design_dir' => $testDir . DIRECTORY_SEPARATOR .  'design'
-        ));
+        // Prepare config with directories
+        $baseDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .  '_files' . DIRECTORY_SEPARATOR . 'fallback';
+        $viewDir = $baseDir . DIRECTORY_SEPARATOR . 'design';
+        $dirs = new Mage_Core_Model_Dir($baseDir, array(), array(Mage_Core_Model_Dir::THEMES => $viewDir));
 
         /** @var $collection Mage_Core_Model_Theme_Collection */
         $collection = Mage::getModel('Mage_Core_Model_Theme_Collection');
-        $themeModel = $collection->setBaseDir($testDir . DIRECTORY_SEPARATOR .  'design')
+        $themeModel = $collection->setBaseDir($viewDir)
             ->addDefaultPattern()
             ->addFilter('theme_path', $themePath)
             ->addFilter('area', $area)
@@ -58,7 +104,8 @@ class Mage_Core_Model_Design_FallbackTest extends PHPUnit_Framework_TestCase
             'themeModel' => $themeModel,
         );
 
-        return Mage::getObjectManager()->create('Mage_Core_Model_Design_Fallback', array('data' => $params));
+        return Mage::getObjectManager()->create('Mage_Core_Model_Design_Fallback',
+            array('dirs' => $dirs, 'params' => $params));
     }
 
     /**
@@ -311,7 +358,7 @@ class Mage_Core_Model_Design_FallbackTest extends PHPUnit_Framework_TestCase
             ),
             'lib file in js lib' => array(
                 'mage/script.js', 'frontend', 'package/custom_theme',
-                '%s/pub/js/mage/script.js',
+                '%s/pub/lib/mage/script.js',
             ),
         );
     }
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageFallbackTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageFallbackTest.php
index 66d9b67199d..09099bcc2ee 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageFallbackTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageFallbackTest.php
@@ -27,25 +27,24 @@
 
 /**
  * Tests for the view layer fallback mechanism
- *
- * @magentoDbIsolation enabled
+ * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
  */
 class Mage_Core_Model_Design_PackageFallbackTest extends PHPUnit_Framework_TestCase
 {
     /**
      * @var Mage_Core_Model_Design_Package
      */
-    protected $_model;
+    protected $_model = null;
 
     protected function setUp()
     {
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'design',
-            Mage::getModel('Mage_Core_Model_Design_Package')
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES => dirname(__DIR__) . '/_files/design'
+            )
         ));
-        $themeUtility->registerThemes()->setDesignTheme('test/default', 'frontend');;
-        $this->_model = $themeUtility->getDesign();
+        $this->_model = new Mage_Core_Model_Design_Package(Mage::getObjectManager()->create('Magento_Filesystem'));
+        $this->_model->setDesignTheme('test/default');
     }
 
     protected function tearDown()
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageMergingTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageMergingTest.php
index e5eaf439f44..f3d9e53f360 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageMergingTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageMergingTest.php
@@ -26,7 +26,7 @@
  */
 
 /**
- * @magentoDbIsolation enabled
+ * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
  */
 class Mage_Core_Model_Design_PackageMergingTest extends PHPUnit_Framework_TestCase
 {
@@ -51,19 +51,20 @@ class Mage_Core_Model_Design_PackageMergingTest extends PHPUnit_Framework_TestCa
 
     public static function setUpBeforeClass()
     {
-        self::$_themePublicDir = Mage::app()->getConfig()->getOptions()->getMediaDir() . '/theme';
+        self::$_themePublicDir = Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA) . '/theme';
         self::$_viewPublicMergedDir = self::$_themePublicDir . '/_merged';
     }
 
     protected function setUp()
     {
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'design',
-            Mage::getModel('Mage_Core_Model_Design_Package')
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES => dirname(__DIR__) . '/_files/design'
+            )
         ));
-        $themeUtility->registerThemes()->setDesignTheme('package/default', 'frontend');
-        $this->_model = $themeUtility->getDesign();
+        $filesystem = Mage::getObjectManager()->create('Magento_Filesystem');
+        $this->_model = new Mage_Core_Model_Design_Package($filesystem);
+        $this->_model->setDesignTheme('package/default');
     }
 
     protected function tearDown()
@@ -94,7 +95,6 @@ class Mage_Core_Model_Design_PackageMergingTest extends PHPUnit_Framework_TestCa
      * @magentoConfigFixture current_store dev/css/merge_css_files 1
      * @magentoConfigFixture current_store dev/js/merge_files 1
      * @magentoConfigFixture current_store dev/static/sign 0
-     * @magentoAppIsolation enabled
      */
     public function testMergeFiles($contentType, $files, $expectedFilename, $related = array())
     {
@@ -122,7 +122,6 @@ class Mage_Core_Model_Design_PackageMergingTest extends PHPUnit_Framework_TestCa
      * @magentoConfigFixture current_store dev/css/merge_css_files 1
      * @magentoConfigFixture current_store dev/js/merge_files 1
      * @magentoConfigFixture current_store dev/static/sign 1
-     * @magentoAppIsolation enabled
      */
     public function testMergeFilesSigned($contentType, $files, $expectedFilename, $related = array())
     {
@@ -189,7 +188,6 @@ class Mage_Core_Model_Design_PackageMergingTest extends PHPUnit_Framework_TestCa
 
     /**
      * @magentoConfigFixture current_store dev/js/merge_files 1
-     * @magentoAppIsolation enabled
      */
     public function testMergeFilesModification()
     {
@@ -209,7 +207,6 @@ class Mage_Core_Model_Design_PackageMergingTest extends PHPUnit_Framework_TestCa
 
     /**
      * @magentoConfigFixture current_store dev/js/merge_files 1
-     * @magentoAppIsolation enabled
      */
     public function testCleanMergedJsCss()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackagePublicationTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackagePublicationTest.php
index 47c25d82fff..d3ac6c4df5b 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackagePublicationTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackagePublicationTest.php
@@ -25,62 +25,35 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-/**
- * @magentoDbIsolation enabled
- */
 class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_TestCase
 {
-    /**
-     * Path to the public directory for view files
-     *
-     * @var string
-     */
-    protected static $_themePublicDir;
-
-    /**
-     * Path for temporary fixture files. Used to test publishing changed files.
-     *
-     * @var string
-     */
-    protected static $_fixtureTmpDir;
-
     /**
      * @var Mage_Core_Model_Design_Package
      */
     protected $_model;
 
-    public static function setUpBeforeClass()
-    {
-        self::$_themePublicDir = Mage::app()->getConfig()->getOptions()->getMediaDir() . '/theme';
-        self::$_fixtureTmpDir = Magento_Test_Bootstrap::getInstance()->getTmpDir() . '/publication';
-    }
-
     protected function setUp()
     {
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'design',
-            Mage::getModel('Mage_Core_Model_Design_Package')
-        ));
-        $themeUtility->registerThemes()->setDesignTheme('test/default', 'frontend');
-        $this->_model = $themeUtility->getDesign();
+        $this->_model = Mage::getModel('Mage_Core_Model_Design_Package');
     }
 
     protected function tearDown()
     {
         $filesystem = Mage::getObjectManager()->create('Magento_Filesystem');
-        $filesystem->delete(self::$_fixtureTmpDir);
-        $filesystem->delete(self::$_themePublicDir . '/adminhtml');
-        $filesystem->delete(self::$_themePublicDir . '/frontend');
+        $publicDir = $this->_model->getPublicDir();
+        $filesystem->delete($publicDir . '/adminhtml');
+        $filesystem->delete($publicDir . '/frontend');
     }
 
     /**
      * @magentoAppIsolation enabled
      */
-    public function testGetPublicThemeDir()
+    public function testGetPublicDir()
     {
-        Mage::app()->getConfig()->getOptions()->setMediaDir(__DIR__);
-        $this->assertEquals(__DIR__ . DIRECTORY_SEPARATOR . 'theme', $this->_model->getPublicDir());
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = Mage::getObjectManager()->get('Mage_Core_Model_Dir');
+        $expectedPublicDir = $dirs->getDir(Mage_Core_Model_Dir::MEDIA) . DIRECTORY_SEPARATOR . 'theme';
+        $this->assertEquals($expectedPublicDir, $this->_model->getPublicDir());
     }
 
     /**
@@ -92,6 +65,8 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
      */
     protected function _testGetViewUrl($file, $expectedUrl, $locale = null)
     {
+        $this->_initTestTheme();
+
         Mage::app()->getLocale()->setLocale($locale);
         $url = $this->_model->getViewFileUrl($file);
         $this->assertStringEndsWith($expectedUrl, $url);
@@ -100,7 +75,9 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
     }
 
     /**
-     * @magentoConfigFixture default/design/theme/allow_view_files_duplication 1
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoConfigFixture global/design/theme/allow_view_files_duplication 1
+     * @magentoAppIsolation enabled
      * @dataProvider getViewUrlFilesDuplicationDataProvider
      */
     public function testGetViewUrlFilesDuplication($file, $expectedUrl, $locale = null)
@@ -139,7 +116,9 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
     }
 
     /**
-     * @magentoConfigFixture default/design/theme/allow_view_files_duplication 0
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoConfigFixture global/design/theme/allow_view_files_duplication 0
+     * @magentoAppIsolation enabled
      * @dataProvider testGetViewUrlNoFilesDuplicationDataProvider
      */
     public function testGetViewUrlNoFilesDuplication($file, $expectedUrl, $locale = null)
@@ -170,10 +149,14 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
     }
 
     /**
-     * @magentoConfigFixture default/design/theme/allow_view_files_duplication 0
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoConfigFixture global/design/theme/allow_view_files_duplication 0
+     * @magentoAppIsolation enabled
      */
     public function testGetViewUrlNoFilesDuplicationWithCaching()
     {
+        $this->_initTestTheme();
+        $this->_model->setDesignTheme('test/default');
         Mage::app()->getLocale()->setLocale('en_US');
         $theme = $this->_model->getDesignTheme();
         $themeDesignParams = array('themeModel' => $theme);
@@ -218,12 +201,16 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
      * Test on vulnerability for protected files
      *
      * @expectedException Magento_Exception
+     * @expectedExceptionMessage because it does not reside in a public directory
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoAppIsolation enabled
      * @dataProvider getProtectedFiles
      * @param array $designParams
      * @param string $filePath
      */
     public function testTemplatePublicationVulnerability($designParams, $filePath)
     {
+        $this->_initTestTheme();
         $this->_model->getViewFileUrl($filePath, $designParams);
     }
 
@@ -261,12 +248,15 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
      * @param string $file
      * @param $designParams
      * @param string $expectedFile
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoAppIsolation enabled
      * @dataProvider publishViewFileDataProvider
      */
     public function testPublishViewFile($file, $designParams, $expectedFile)
     {
-        $expectedFile = self::$_themePublicDir . '/' . $expectedFile;
-        $this->_deleteFiles[] = $expectedFile;
+        $this->_initTestTheme();
+
+        $expectedFile = $this->_model->getPublicDir() . '/' . $expectedFile;
 
         // test doesn't make sense if the original file doesn't exist or the target file already exists
         $originalFile = $this->_model->getViewFile($file, $designParams);
@@ -310,9 +300,12 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
 
     /**
      * Publication of CSS files located in the theme (development mode)
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
      */
     public function testPublishCssFileFromTheme()
     {
+        $this->_initTestTheme();
         $expectedFiles = array(
             'css/file.css',
             'recursive.css',
@@ -326,7 +319,7 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
             'Namespace_Module/absolute_valid_module.gif',
             'Mage_Page/favicon.ico', // non-fixture file from real module
         );
-        $publishedDir = self::$_themePublicDir . '/frontend/package/default/en_US';
+        $publishedDir = $this->_model->getPublicDir() . '/frontend/package/default/en_US';
         $this->assertFileNotExists($publishedDir, 'Please verify isolation from previous test(s).');
         $this->_model->getViewFileUrl('css/file.css', array(
             'package' => 'package',
@@ -341,6 +334,8 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
 
     /**
      * Publication of CSS files located in the module
+     *
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
      * @dataProvider publishCssFileFromModuleDataProvider
      */
     public function testPublishCssFileFromModule(
@@ -348,7 +343,7 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
     ) {
         $this->_model->getViewFileUrl($cssViewFile, $designParams);
 
-        $expectedCssFile = self::$_themePublicDir . '/' . $expectedCssFile;
+        $expectedCssFile = $this->_model->getPublicDir() . '/' . $expectedCssFile;
         $this->assertFileExists($expectedCssFile);
         $actualCssContent = file_get_contents($expectedCssFile);
 
@@ -363,7 +358,7 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
         }
 
         foreach ($expectedRelatedFiles as $expectedFile) {
-            $expectedFile = self::$_themePublicDir . '/' . $expectedFile;
+            $expectedFile = $this->_model->getPublicDir() . '/' . $expectedFile;
             $this->assertFileExists($expectedFile);
         }
     }
@@ -413,6 +408,9 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
 
     /**
      * Test that modified CSS file and changed resources are re-published in developer mode
+     *
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Mage/Core/_files/media_for_change.php
      */
     public function testPublishResourcesAndCssWhenChangedCssDevMode()
     {
@@ -424,6 +422,9 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
 
     /**
      * Test that modified CSS file and changed resources are not re-published in usual mode
+     *
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Mage/Core/_files/media_for_change.php
      */
     public function testNotPublishResourcesAndCssWhenChangedCssUsualMode()
     {
@@ -440,11 +441,17 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
      */
     protected function _testPublishResourcesAndCssWhenChangedCss($expectedPublished)
     {
-        $fixtureViewPath = self::$_fixtureTmpDir . '/frontend/test/default/';
-        $publishedPath = self::$_themePublicDir . '/frontend/test/default/en_US/';
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES =>
+                    Magento_Test_Bootstrap::getInstance()->getInstallDir() . '/media_for_change'
+            )
+        ));
+        $this->_model->setDesignTheme('test/default');
+        $themePath = $this->_model->getDesignTheme()->getFullPath();
+        $fixtureViewPath = Magento_Test_Bootstrap::getInstance()->getInstallDir() . "/media_for_change/$themePath/";
+        $publishedPath = $this->_model->getPublicDir() . "/$themePath/en_US/";
 
-        // Prepare temporary fixture directory and publish files from it
-        $this->_copyFixtureViewToTmpDir($fixtureViewPath);
         $this->_model->getViewFileUrl('style.css', array('locale' => 'en_US'));
 
         // Change main file and referenced files - everything changed and referenced must appear
@@ -472,9 +479,10 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
         }
     }
 
-
     /**
      * Test changed resources, referenced in non-modified CSS file, are re-published
+     *
+     * @magentoDataFixture Mage/Core/_files/media_for_change.php
      * @magentoAppIsolation enabled
      */
     public function testPublishChangedResourcesWhenUnchangedCssDevMode()
@@ -488,6 +496,8 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
 
     /**
      * Test changed resources, referenced in non-modified CSS file, are re-published
+     *
+     * @magentoDataFixture Mage/Core/_files/media_for_change.php
      * @magentoAppIsolation enabled
      */
     public function testNotPublishChangedResourcesWhenUnchangedCssUsualMode()
@@ -506,11 +516,17 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
      */
     protected function _testPublishChangedResourcesWhenUnchangedCss($expectedPublished)
     {
-        $fixtureViewPath = self::$_fixtureTmpDir . '/frontend/test/default/';
-        $publishedPath = self::$_themePublicDir . '/frontend/test/default/en_US/';
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES =>
+                    Magento_Test_Bootstrap::getInstance()->getInstallDir() . '/media_for_change'
+            )
+        ));
+        $this->_model->setDesignTheme('test/default');
+        $themePath = $this->_model->getDesignTheme()->getFullPath();
+        $fixtureViewPath = Magento_Test_Bootstrap::getInstance()->getInstallDir() . "/media_for_change/$themePath/";
+        $publishedPath = $this->_model->getPublicDir() . "/$themePath/en_US/";
 
-        // Prepare temporary fixture directory and publish files from it
-        $this->_copyFixtureViewToTmpDir($fixtureViewPath);
         $this->_model->getViewFileUrl('style.css', array('locale' => 'en_US'));
 
         // Change referenced files
@@ -530,22 +546,16 @@ class Mage_Core_Model_Design_PackagePublicationTest extends PHPUnit_Framework_Te
     }
 
     /**
-     * Prepare design directory with initial css and resources
-     *
-     * @param string $fixtureViewPath
+     * Init the model with a test theme from fixture themes dir
+     * Init application with custom view dir, @magentoAppIsolation required
      */
-    protected function _copyFixtureViewToTmpDir($fixtureViewPath)
+    protected function _initTestTheme()
     {
-        Mage::app()->getConfig()->getOptions()->setDesignDir(self::$_fixtureTmpDir);
-        mkdir($fixtureViewPath . '/images', 0777, true);
-
-        // Copy all files to fixture location
-        $mTime = time() - 10; // To ensure that all files, changed later in test, will be recognized for publication
-        $sourcePath = dirname(__DIR__) . '/_files/design/frontend/test/publication/';
-        $files = array('theme.xml', 'style.css', 'sub.css', 'images/square.gif', 'images/rectangle.gif');
-        foreach ($files as $file) {
-            copy($sourcePath . $file, $fixtureViewPath . $file);
-            touch($fixtureViewPath . $file, $mTime);
-        }
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES => dirname(__DIR__) . '/_files/design/'
+            )
+        ));
+        $this->_model->setDesignTheme('test/default');
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageTest.php
index 4942ea526c7..a910db073eb 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Design/PackageTest.php
@@ -26,7 +26,7 @@
  */
 
 /**
- * @magentoDbIsolation enabled
+ * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
  */
 class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
 {
@@ -35,39 +35,29 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
      */
     protected $_model;
 
-    protected static $_developerMode;
-
     public static function setUpBeforeClass()
     {
-        $mediaDir = Mage::app()->getConfig()->getOptions()->getMediaDir();
+        $themeDir = Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA) . 'theme';
         $filesystem = Mage::getObjectManager()->create('Magento_Filesystem');
-        $filesystem->delete($mediaDir . '/theme/frontend');
-        $filesystem->delete($mediaDir . '/theme/_merged');
+        $filesystem->delete($themeDir . '/frontend');
+        $filesystem->delete($themeDir . '/_merged');
 
         $ioAdapter = new Varien_Io_File();
         $ioAdapter->cp(
-            Mage::app()->getConfig()->getOptions()->getJsDir() . '/prototype/prototype.js',
-            Mage::app()->getConfig()->getOptions()->getJsDir() . '/prototype/prototype.min.js'
+            Mage::getBaseDir(Mage_Core_Model_Dir::PUB_LIB) . '/prototype/prototype.js',
+            Mage::getBaseDir(Mage_Core_Model_Dir::PUB_LIB) . '/prototype/prototype.min.js'
         );
-        self::$_developerMode = Mage::getIsDeveloperMode();
     }
 
     public static function tearDownAfterClass()
     {
         $ioAdapter = new Varien_Io_File();
-        $ioAdapter->rm(Mage::app()->getConfig()->getOptions()->getJsDir() . '/prototype/prototype.min.js');
-        Mage::setIsDeveloperMode(self::$_developerMode);
+        $ioAdapter->rm(Mage::getBaseDir(Mage_Core_Model_Dir::PUB_LIB) . '/prototype/prototype.min.js');
     }
 
     protected function setUp()
     {
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'design',
-            Mage::getModel('Mage_Core_Model_Design_Package')
-        ));
-        $themeUtility->registerThemes()->setDesignTheme('test/default', 'frontend');
-        $this->_model = $themeUtility->getDesign();
+        $this->_model = new Mage_Core_Model_Design_Package(Mage::getObjectManager()->create('Magento_Filesystem'));
     }
 
     protected function tearDown()
@@ -75,6 +65,21 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
         $this->_model = null;
     }
 
+    /**
+     * Emulate fixture design theme
+     *
+     * @param string $themePath
+     */
+    protected function _emulateFixtureTheme($themePath = 'test/default')
+    {
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES => realpath(__DIR__ . '/../_files/design'),
+            ),
+        ));
+        $this->_model->setDesignTheme($themePath);
+    }
+
     public function testSetGetArea()
     {
         $this->assertEquals(Mage_Core_Model_Design_Package::DEFAULT_AREA, $this->_model->getArea());
@@ -82,11 +87,6 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
         $this->assertEquals('test', $this->_model->getArea());
     }
 
-    public function testGetTheme()
-    {
-        $this->assertEquals('test/default', $this->_model->getDesignTheme()->getThemePath());
-    }
-
     public function testSetDesignTheme()
     {
         $this->_model->setDesignTheme('test/test', 'test');
@@ -99,11 +99,48 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
         $this->assertInstanceOf('Mage_Core_Model_Theme', $this->_model->getDesignTheme());
     }
 
+    /**
+     * @magentoConfigFixture frontend/design/theme/full_name f
+     * @magentoConfigFixture install/design/theme/full_name i
+     * @magentoConfigFixture adminhtml/design/theme/full_name b
+     * @magentoConfigFixture current_store design/theme/theme_id 0
+     */
+    public function testGetConfigurationDesignThemeDefaults()
+    {
+        $this->assertEquals('f', $this->_model->getConfigurationDesignTheme());
+        $this->assertEquals('f', $this->_model->getConfigurationDesignTheme('frontend'));
+        $this->assertEquals('f', $this->_model->getConfigurationDesignTheme('frontend', array('store' => 0)));
+        $this->assertEquals('f', $this->_model->getConfigurationDesignTheme('frontend', array('store' => null)));
+        $this->assertEquals('i', $this->_model->getConfigurationDesignTheme('install'));
+        $this->assertEquals('i', $this->_model->getConfigurationDesignTheme('install', array('store' => uniqid())));
+        $this->assertEquals('b', $this->_model->getConfigurationDesignTheme('adminhtml'));
+        $this->assertEquals('b', $this->_model->getConfigurationDesignTheme('adminhtml', array('store' => uniqid())));
+    }
+
+    /**
+     * @magentoConfigFixture current_store design/theme/theme_id one
+     * @magentoConfigFixture fixturestore_store design/theme/theme_id two
+     * @magentoDataFixture Mage/Core/_files/store.php
+     */
+    public function testGetConfigurationDesignThemeStore()
+    {
+        $storeId = Mage::app()->getStore()->getId();
+        $this->assertEquals('one', $this->_model->getConfigurationDesignTheme());
+        $this->assertEquals('one', $this->_model->getConfigurationDesignTheme(null, array('store' => $storeId)));
+        $this->assertEquals('one', $this->_model->getConfigurationDesignTheme('frontend', array('store' => $storeId)));
+        $this->assertEquals('two', $this->_model->getConfigurationDesignTheme(null, array('store' => 'fixturestore')));
+        $this->assertEquals('two', $this->_model->getConfigurationDesignTheme(
+            'frontend', array('store' => 'fixturestore')
+        ));
+    }
+
     /**
      * @dataProvider getFilenameDataProvider
+     * @magentoAppIsolation enabled
      */
     public function testGetFilename($file, $params)
     {
+        $this->_emulateFixtureTheme();
         $this->assertFileExists($this->_model->getFilename($file, $params));
     }
 
@@ -141,8 +178,12 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testGetOptimalCssUrls()
     {
+        $this->_emulateFixtureTheme();
         $expected = array(
             'http://localhost/pub/media/theme/frontend/test/default/en_US/css/styles.css',
             'http://localhost/pub/lib/mage/translate-inline.css',
@@ -159,9 +200,11 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
      * @param array $expectedFiles
      * @dataProvider getOptimalCssUrlsMergedDataProvider
      * @magentoConfigFixture current_store dev/css/merge_css_files 1
+     * @magentoAppIsolation enabled
      */
     public function testGetOptimalCssUrlsMerged($files, $expectedFiles)
     {
+        $this->_emulateFixtureTheme();
         $this->assertEquals($expectedFiles, $this->_model->getOptimalCssUrls($files));
     }
 
@@ -179,9 +222,12 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
         );
     }
 
-
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testGetOptimalJsUrls()
     {
+        $this->_emulateFixtureTheme();
         $expected = array(
             'http://localhost/pub/media/theme/frontend/test/default/en_US/js/tabs.js',
             'http://localhost/pub/lib/jquery/jquery-ui-timepicker-addon.js',
@@ -200,9 +246,11 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
      * @param array $expectedFiles
      * @dataProvider getOptimalJsUrlsMergedDataProvider
      * @magentoConfigFixture current_store dev/js/merge_files 1
+     * @magentoAppIsolation enabled
      */
     public function testGetOptimalJsUrlsMerged($files, $expectedFiles)
     {
+        $this->_emulateFixtureTheme();
         $this->assertEquals($expectedFiles, $this->_model->getOptimalJsUrls($files));
     }
 
@@ -220,32 +268,43 @@ class Mage_Core_Model_Design_PackageTest extends PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testGetViewConfig()
     {
+        $this->_emulateFixtureTheme();
         $config = $this->_model->getViewConfig();
         $this->assertInstanceOf('Magento_Config_View', $config);
         $this->assertEquals(array('var1' => 'value1', 'var2' => 'value2'), $config->getVars('Namespace_Module'));
     }
 
     /**
+     * @param bool $devMode
      * @param string $file
      * @param string $result
-     * @covers Mage_Core_Model_Design_Package::getViewUrl
+     *
      * @dataProvider getViewUrlDataProvider
+     *
      * @magentoConfigFixture current_store dev/static/sign 0
+     * @magentoAppIsolation enabled
      */
     public function testGetViewUrl($devMode, $file, $result)
     {
+        $this->_emulateFixtureTheme();
         Mage::setIsDeveloperMode($devMode);
         $this->assertEquals($this->_model->getViewFileUrl($file), $result);
     }
 
     /**
+     * @param bool $devMode
      * @param string $file
      * @param string $result
-     * @covers Mage_Core_Model_Design_Package::getSkinUrl
+     *
      * @dataProvider getViewUrlDataProvider
+     *
      * @magentoConfigFixture current_store dev/static/sign 1
+     * @magentoAppIsolation enabled
      */
     public function testGetViewUrlSigned($devMode, $file, $result)
     {
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php
index a3722622e66..950d5ff288e 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Email/Template/FilterTest.php
@@ -44,8 +44,6 @@ class Mage_Core_Model_Email_Template_FilterTest extends PHPUnit_Framework_TestCa
 
     /**
      * Isolation level has been raised in order to flush themes configuration in-memory cache
-     *
-     * @magentoAppIsolation enabled
      */
     public function testViewDirective()
     {
@@ -102,27 +100,35 @@ class Mage_Core_Model_Email_Template_FilterTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * @magentoDbIsolation enabled
-     * @magentoAppIsolation enabled
-     * @magentoConfigFixture default_store design/theme/full_name test/default
+     * @magentoDataFixture Mage/Core/Model/Email/_files/themes.php
      * @magentoConfigFixture adminhtml/design/theme/full_name test/default
+     * @magentoAppIsolation enabled
      * @dataProvider layoutDirectiveDataProvider
      *
-     * @param string $currentArea
+     * @param string $area
      * @param string $directiveParams
      * @param string $expectedOutput
      */
-    public function testLayoutDirective($currentArea, $directiveParams, $expectedOutput)
+    public function testLayoutDirective($area, $directiveParams, $expectedOutput)
     {
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'design'
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES => dirname(__DIR__) . '/_files/design'
+            )
         ));
-        $themeUtility->registerThemes()
-            ->setDesignTheme('test/default', 'frontend')
-            ->setDesignTheme('test/default', 'adminhtml');
 
-        $this->_emulateCurrentArea($currentArea);
+        $collection = new Mage_Core_Model_Resource_Theme_Collection;
+        $themeId = $collection->getThemeByFullPath('frontend/test/default')->getId();
+        Mage::app()->getStore()->setConfig(Mage_Core_Model_Design_Package::XML_PATH_THEME_ID, $themeId);
+
+        /** @var $layout Mage_Core_Model_Layout */
+        $objectManager = Mage::getObjectManager();
+        $layout = Mage::getObjectManager()->create('Mage_Core_Model_Layout', array('area' => $area));
+        $objectManager->addSharedInstance($layout, 'Mage_Core_Model_Layout');
+        $this->assertEquals($area, $layout->getArea());
+        $this->assertEquals($area, Mage::app()->getLayout()->getArea());
+        Mage::getDesign()->setDesignTheme('test/default');
+
         $actualOutput = $this->_model->layoutDirective(array(
             '{{layout ' . $directiveParams . '}}',
             'layout',
@@ -161,18 +167,4 @@ class Mage_Core_Model_Email_Template_FilterTest extends PHPUnit_Framework_TestCa
         );
         return $result;
     }
-
-    /**
-     * Emulate the current application area
-     *
-     * @param string $area
-     */
-    protected function _emulateCurrentArea($area)
-    {
-        /** @var $layoutFactory Mage_Core_Model_Layout_Factory */
-        $layoutFactory = Mage::getObjectManager()->get('Mage_Core_Model_Layout_Factory');
-        $layout = $layoutFactory->createLayout(array('area' => $area));
-        $this->assertEquals($area, $layout->getArea());
-        $this->assertEquals($area, Mage::app()->getLayout()->getArea());
-    }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php
index ababfcca6e8..1cbede5ed7b 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Email/TemplateTest.php
@@ -39,8 +39,6 @@ class Mage_Core_Model_Email_TemplateTest extends PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        Mage_Core_Utility_Theme::registerDesignMock();
-        Mage::getDesign()->setDefaultDesignTheme();
         $this->_mail = $this->getMock(
             'Zend_Mail', array('send', 'addTo', 'addBcc', 'setReturnPath', 'setReplyTo'), array('utf-8')
         );
@@ -83,14 +81,8 @@ class Mage_Core_Model_Email_TemplateTest extends PHPUnit_Framework_TestCase
         $this->assertSame($filter, $this->_model->getTemplateFilter());
     }
 
-    /**
-     * @magentoAppIsolation enabled
-     */
     public function testLoadDefault()
     {
-        Mage::app()->getConfig()->getOptions()
-            ->setLocaleDir(dirname(__DIR__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'locale');
-
         $this->_model->loadDefault('customer_create_account_email_template');
         $this->assertNotEmpty($this->_model->getTemplateText());
         $this->assertNotEmpty($this->_model->getTemplateSubject());
@@ -114,12 +106,11 @@ class Mage_Core_Model_Email_TemplateTest extends PHPUnit_Framework_TestCase
     /**
      * @magentoAppIsolation enabled
      * @magentoDataFixture Mage/Core/_files/store.php
-     * @magentoConfigFixture fixturestore_store design/theme/full_name test/default
-     * @magentoDataFixture Mage/Core/Model/Email/_files/theme_registration.php
      */
     public function testGetProcessedTemplate()
     {
-        $expectedViewUrl = 'theme/frontend/test/default/en_US/Mage_Page/favicon.ico';
+        $this->_setBlueThemeForFixtureStore();
+        $expectedViewUrl = 'theme/frontend/default/demo_blue/en_US/Mage_Page/favicon.ico';
         $this->_model->setTemplateText('{{view url="Mage_Page::favicon.ico"}}');
         $this->assertStringEndsNotWith($expectedViewUrl, $this->_model->getProcessedTemplate());
         $this->_model->setDesignConfig(array(
@@ -128,6 +119,18 @@ class Mage_Core_Model_Email_TemplateTest extends PHPUnit_Framework_TestCase
         $this->assertStringEndsWith($expectedViewUrl, $this->_model->getProcessedTemplate());
     }
 
+    /**
+     * Set 'default/demo_blue' for the 'fixturestore' store.
+     * Application isolation is required, if a test uses this method.
+     */
+    protected function _setBlueThemeForFixtureStore()
+    {
+        $theme = Mage::getModel('Mage_Core_Model_Theme');
+        $theme->load('default/demo_blue', 'theme_path');
+        Mage::app()->getStore('fixturestore')
+            ->setConfig(Mage_Core_Model_Design_Package::XML_PATH_THEME_ID, $theme->getId());
+    }
+
     /**
      * @magentoAppIsolation enabled
      * @magentoDataFixture Mage/Core/_files/design_change.php
@@ -144,12 +147,11 @@ class Mage_Core_Model_Email_TemplateTest extends PHPUnit_Framework_TestCase
     /**
      * @magentoAppIsolation enabled
      * @magentoDataFixture Mage/Core/_files/store.php
-     * @magentoConfigFixture fixturestore_store design/theme/full_name test/default
-     * @magentoDataFixture Mage/Core/Model/Email/_files/theme_registration.php
      */
     public function testGetProcessedTemplateSubject()
     {
-        $expectedViewUrl = 'theme/frontend/test/default/en_US/Mage_Page/favicon.ico';
+        $this->_setBlueThemeForFixtureStore();
+        $expectedViewUrl = 'theme/frontend/default/demo_blue/en_US/Mage_Page/favicon.ico';
         $this->_model->setTemplateSubject('{{view url="Mage_Page::favicon.ico"}}');
         $this->assertStringEndsNotWith($expectedViewUrl, $this->_model->getProcessedTemplateSubject(array()));
         $this->_model->setDesignConfig(array(
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Email/_files/themes.php b/dev/tests/integration/testsuite/Mage/Core/Model/Email/_files/themes.php
new file mode 100644
index 00000000000..bfcc7910940
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Email/_files/themes.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/** @var $registration Mage_Core_Model_Theme_Registration */
+$registration = Mage::getModel('Mage_Core_Model_Theme_Registration');
+$registration->register(
+    __DIR__ . DIRECTORY_SEPARATOR . 'design',
+    implode(DIRECTORY_SEPARATOR, array('*','*', '*', 'theme.xml'))
+);
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/MergeTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/MergeTest.php
index 8f8c2df0b04..004485100ef 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Layout/MergeTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Layout/MergeTest.php
@@ -25,9 +25,6 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-/**
- * @magentoDbIsolation enabled
- */
 class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
 {
     /**
@@ -35,21 +32,18 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
      */
     protected $_model;
 
-    /**
-     * @var Mage_Core_Utility_Theme
-     */
-    protected $_themeUtility;
-
     protected function setUp()
     {
-        $this->_themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__DIR__) . '/_files/design',
-            Mage::getDesign()
-        ));
-        $this->_themeUtility->registerThemes()->setDesignTheme('test/default', 'frontend');
-
         /* Disable loading and saving layout cache */
         Mage::app()->getCacheInstance()->banUse('layout');
+
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES => dirname(__DIR__) . '/_files/design'
+            )
+        ));
+        Mage::getDesign()->setDesignTheme('test/default');
+
         $this->_model = Mage::getModel('Mage_Core_Model_Layout_Merge', array(
             'arguments' => array('area' => 'frontend', 'theme' => Mage::getDesign()->getDesignTheme()->getId())
         ));
@@ -152,6 +146,9 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
 
     /**
      * Test that, regarding of the current area, page types hierarchy getter retrieves the front-end page types
+     *
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoAppIsolation enabled
      * @throws Exception
      */
     public function testGetPageHandlesHierarchyFromBackend()
@@ -159,21 +156,16 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
         $area = Mage::getDesign()->getArea();
         $this->assertEquals('frontend', $area, 'Test assumes that front-end is the current area.');
 
-        /* use new instance to ensure that in-memory caching, if any, won't affect test results */
         /** @var $model Mage_Core_Model_Layout_Merge */
         $model = Mage::getModel('Mage_Core_Model_Layout_Merge');
         $frontendPageTypes = $model->getPageHandlesHierarchy();
         $this->assertNotEmpty($frontendPageTypes);
 
+        /* use new instance to ensure that in-memory caching, if any, won't affect test results */
+        $model = Mage::getModel('Mage_Core_Model_Layout_Merge');
         Mage::getDesign()->setArea('adminhtml');
-        try {
-            $backendPageTypes = $this->_model->getPageHandlesHierarchy();
-            $this->assertSame($frontendPageTypes, $backendPageTypes);
-        } catch (Exception $e) {
-            Mage::getDesign()->setArea($area);
-            throw $e;
-        }
-        Mage::getDesign()->setArea($area);
+        $backendPageTypes = $model->getPageHandlesHierarchy();
+        $this->assertSame($frontendPageTypes, $backendPageTypes);
     }
 
     /**
@@ -215,16 +207,18 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
     }
 
     /**
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
      * @magentoAppIsolation enabled
      */
     public function testLoad()
     {
+        $collection = new Mage_Core_Model_Resource_Theme_Collection;
         $layoutHandle = 'layout_test_handle';
         $expectedText = 'Text declared in the frontend/test/test_theme';
         /** @var $model Mage_Core_Model_Layout_Merge */
         $model = Mage::getModel('Mage_Core_Model_Layout_Merge', array('arguments' => array(
-            'area'       => 'frontend',
-            'theme'    => $this->_themeUtility->getThemeByParams('test/test_theme', 'frontend')->getId()
+            'area' => 'frontend',
+            'theme' => $collection->getThemeByFullPath('frontend/test/test_theme')->getId()
         )));
         $this->assertNotContains($layoutHandle, $model->getHandles());
         $this->assertNotContains($expectedText, $model->asString());
@@ -234,6 +228,7 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
     }
 
     /**
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
      * @magentoAppIsolation enabled
      */
     public function testLoadCache()
@@ -244,23 +239,29 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
         $expectedTextThemeOne = 'Text declared in the frontend/test/test_theme';
         $expectedTextThemeTwo = 'Text declared in the frontend/test/cache_test_theme';
 
+        $collection = new Mage_Core_Model_Resource_Theme_Collection;
         $model = Mage::getModel('Mage_Core_Model_Layout_Merge', array('arguments' => array(
             'area'    => 'frontend',
-            'theme' => $this->_themeUtility->getThemeByParams('test/test_theme', 'frontend')->getId()
+            'theme' => $collection->getThemeByFullPath('frontend/test/test_theme')->getId()
         )));
         $model->load($layoutHandle);
         $this->assertContains($expectedTextThemeOne, $model->asString());
         $this->assertNotContains($expectedTextThemeTwo, $model->asString());
 
+        $collection = new Mage_Core_Model_Resource_Theme_Collection;
         $model = Mage::getModel('Mage_Core_Model_Layout_Merge', array('arguments' => array(
             'area'    => 'frontend',
-            'theme' => $this->_themeUtility->getThemeByParams('test/cache_test_theme', 'frontend')->getId()
+            'theme' => $collection->getThemeByFullPath('frontend/test/cache_test_theme')->getId()
         )));
         $model->load($layoutHandle);
         $this->assertContains($expectedTextThemeTwo, $model->asString());
         $this->assertNotContains($expectedTextThemeOne, $model->asString());
     }
 
+    /**
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoAppIsolation enabled
+     */
     public function testFetchDbLayoutUpdates()
     {
         $update = '<reference name="root"><block type="Mage_Core_Block_Template" template="dummy.phtml"/></reference>';
@@ -280,6 +281,10 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoAppIsolation enabled
+     */
     public function testGetFileLayoutUpdatesXmlFromTheme()
     {
         $this->_replaceConfigLayoutUpdates('
@@ -383,6 +388,8 @@ class Mage_Core_Model_Layout_MergeTest extends PHPUnit_Framework_TestCase
     /**
      * @magentoConfigFixture current_store advanced/modules_disable_output/Mage_Catalog true
      * @magentoConfigFixture current_store advanced/modules_disable_output/Mage_Page    true
+     * @magentoDataFixture Mage/Core/Model/_files/design/themes.php
+     * @magentoAppIsolation enabled
      */
     public function testGetFileLayoutUpdatesXmlDisabledOutput()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutArgumentTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutArgumentTest.php
deleted file mode 100644
index 4472b384276..00000000000
--- a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutArgumentTest.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Magento
- * @package     Mage_Core
- * @subpackage  integration_tests
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Layout integration tests
- *
- * @magentoDbIsolation enabled
- */
-class Mage_Core_Model_LayoutArgumentTest extends Mage_Core_Model_LayoutTestBase
-{
-    /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     */
-    public function testLayoutArgumentsDirective()
-    {
-        $this->_layout->getUpdate()->load(array('layout_test_handle_arguments'));
-        $this->_layout->generateXml()->generateElements();
-        $this->assertEquals('1', $this->_layout->getBlock('block_with_args')->getOne());
-        $this->assertEquals('two', $this->_layout->getBlock('block_with_args')->getTwo());
-        $this->assertEquals('3', $this->_layout->getBlock('block_with_args')->getThree());
-    }
-
-    /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     */
-    public function testLayoutArgumentsDirectiveIfComplexValues()
-    {
-        $this->_layout->getUpdate()->load(array('layout_test_handle_arguments_complex_values'));
-        $this->_layout->generateXml()->generateElements();
-
-        $this->assertEquals(array('parameters' => array('first' => '1', 'second' => '2')),
-            $this->_layout->getBlock('block_with_args_complex_values')->getOne());
-
-        $this->assertEquals('two', $this->_layout->getBlock('block_with_args_complex_values')->getTwo());
-
-        $this->assertEquals(array('extra' => array('key1' => 'value1', 'key2' => 'value2')),
-            $this->_layout->getBlock('block_with_args_complex_values')->getThree());
-    }
-
-    /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     */
-    public function testLayoutObjectArgumentsDirective()
-    {
-        $this->_layout->getUpdate()->load(array('layout_test_handle_arguments_object_type'));
-        $this->_layout->generateXml()->generateElements();
-        $this->assertInstanceOf('Mage_Core_Block_Text', $this->_layout->getBlock('block_with_object_args')->getOne());
-        $this->assertInstanceOf('Mage_Core_Block_Messages',
-            $this->_layout->getBlock('block_with_object_args')->getTwo()
-        );
-        $this->assertEquals(3, $this->_layout->getBlock('block_with_object_args')->getThree());
-    }
-
-    /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     */
-    public function testLayoutUrlArgumentsDirective()
-    {
-        $this->_layout->getUpdate()->load(array('layout_test_handle_arguments_url_type'));
-        $this->_layout->generateXml()->generateElements();
-        $this->assertContains('customer/account/login', $this->_layout->getBlock('block_with_url_args')->getOne());
-        $this->assertContains('customer/account/logout', $this->_layout->getBlock('block_with_url_args')->getTwo());
-        $this->assertContains('customer_id/3', $this->_layout->getBlock('block_with_url_args')->getTwo());
-    }
-
-    /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     */
-    public function testLayoutObjectArgumentUpdatersDirective()
-    {
-        $this->_layout->getUpdate()->load(array('layout_test_handle_arguments_object_type_updaters'));
-        $this->_layout->generateXml()->generateElements();
-
-        $expectedObjectData = array(
-            0 => 'updater call',
-            1 => 'updater call',
-            2 => 'updater call',
-        );
-
-        $expectedSimpleData = 2;
-
-        $block = $this->_layout->getBlock('block_with_object_updater_args')->getOne();
-        $this->assertInstanceOf('Mage_Core_Block_Text', $block);
-        $this->assertEquals($expectedObjectData, $block->getUpdaterCall());
-        $this->assertEquals($expectedSimpleData, $this->_layout->getBlock('block_with_object_updater_args')->getTwo());
-    }
-}
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutDirectivesTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutDirectivesTest.php
new file mode 100644
index 00000000000..dd484b1a97d
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutDirectivesTest.php
@@ -0,0 +1,241 @@
+<?php
+/**
+ * Set of tests of layout directives handling behavior
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Core_Model_LayoutDirectivesTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test scheduled operations in the rendering of elements
+     *
+     * Expected behavior:
+     * 1) block1 was not declared at the moment when "1" invocation declared. The operation is scheduled
+     * 2) block1 creation directive schedules adding "2" as well
+     * 3) block2 is generated with "3"
+     * 4) yet another action schedules replacing value of block2 into "4"
+     * 5) when entire layout is read, all scheduled operations are executed in the same order as declared
+     *    (blocks are instantiated first, of course)
+     * The end result can be observed in container1
+     */
+    public function testRenderElement()
+    {
+        $layout = $this->_getLayoutModel('render.xml');
+        $this->assertEmpty($layout->renderElement('nonexisting_element'));
+        $this->assertEquals('124', $layout->renderElement('container1'));
+        $this->assertEquals('12', $layout->renderElement('block1'));
+    }
+
+    /**
+     * Invoke getBlock() while layout is being generated
+     *
+     * Assertions in this test are pure formalism. The point is to emulate situation where block refers to other block
+     * while the latter hasn't been generated yet, and assure that there is no crash
+     */
+    public function testGetBlockUnscheduled()
+    {
+        $layout = $this->_getLayoutModel('get_block.xml');
+        $this->assertInstanceOf('Mage_Core_Block_Text', $layout->getBlock('block1'));
+        $this->assertInstanceOf('Mage_Core_Block_Text', $layout->getBlock('block2'));
+    }
+
+    /**
+     * @expectedException Magento_Exception
+     */
+    public function testGetBlockUnscheduledException()
+    {
+        $this->_getLayoutModel('get_block_exception.xml');
+    }
+
+    public function testLayoutArgumentsDirective()
+    {
+        $layout = $this->_getLayoutModel('arguments.xml');
+        $this->assertEquals('1', $layout->getBlock('block_with_args')->getOne());
+        $this->assertEquals('two', $layout->getBlock('block_with_args')->getTwo());
+        $this->assertEquals('3', $layout->getBlock('block_with_args')->getThree());
+    }
+
+    public function testLayoutArgumentsDirectiveIfComplexValues()
+    {
+        $layout = $this->_getLayoutModel('arguments_complex_values.xml');
+
+        $this->assertEquals(array('parameters' => array('first' => '1', 'second' => '2')),
+            $layout->getBlock('block_with_args_complex_values')->getOne());
+
+        $this->assertEquals('two', $layout->getBlock('block_with_args_complex_values')->getTwo());
+
+        $this->assertEquals(array('extra' => array('key1' => 'value1', 'key2' => 'value2')),
+            $layout->getBlock('block_with_args_complex_values')->getThree());
+    }
+
+    public function testLayoutObjectArgumentsDirective()
+    {
+        $layout = $this->_getLayoutModel('arguments_object_type.xml');
+        $this->assertInstanceOf('Mage_Core_Block_Text', $layout->getBlock('block_with_object_args')->getOne());
+        $this->assertInstanceOf('Mage_Core_Block_Messages',
+            $layout->getBlock('block_with_object_args')->getTwo()
+        );
+        $this->assertEquals(3, $layout->getBlock('block_with_object_args')->getThree());
+    }
+
+    public function testLayoutUrlArgumentsDirective()
+    {
+        $layout = $this->_getLayoutModel('arguments_url_type.xml');
+        $this->assertContains('customer/account/login', $layout->getBlock('block_with_url_args')->getOne());
+        $this->assertContains('customer/account/logout', $layout->getBlock('block_with_url_args')->getTwo());
+        $this->assertContains('customer_id/3', $layout->getBlock('block_with_url_args')->getTwo());
+    }
+
+    public function testLayoutObjectArgumentUpdatersDirective()
+    {
+        $layout = $this->_getLayoutModel('arguments_object_type_updaters.xml');
+
+        $expectedObjectData = array(
+            0 => 'updater call',
+            1 => 'updater call',
+            2 => 'updater call',
+        );
+
+        $expectedSimpleData = 2;
+
+        $block = $layout->getBlock('block_with_object_updater_args')->getOne();
+        $this->assertInstanceOf('Mage_Core_Block_Text', $block);
+        $this->assertEquals($expectedObjectData, $block->getUpdaterCall());
+        $this->assertEquals($expectedSimpleData, $layout->getBlock('block_with_object_updater_args')->getTwo());
+    }
+
+    public function testMoveSameAlias()
+    {
+        $layout = $this->_getLayoutModel('move_the_same_alias.xml');
+        $this->assertEquals('container1', $layout->getParentName('no_name3'));
+    }
+
+    public function testMoveNewAlias()
+    {
+        $layout = $this->_getLayoutModel('move_new_alias.xml');
+        $this->assertEquals('new_alias', $layout->getElementAlias('no_name3'));
+    }
+
+    public function testActionAnonymousParentBlock()
+    {
+        $layout = $this->_getLayoutModel('action_for_anonymous_parent_block.xml');
+        $this->assertEquals('schedule_block', $layout->getParentName('test.block.insert'));
+        $this->assertEquals('schedule_block_1', $layout->getParentName('test.block.append'));
+    }
+
+    public function testRemove()
+    {
+        $layout = $this->_getLayoutModel('remove.xml');
+        $this->assertFalse($layout->getBlock('no_name2'));
+        $this->assertFalse($layout->getBlock('child_block1'));
+        $this->assertTrue($layout->isBlock('child_block2'));
+    }
+
+    public function testMove()
+    {
+        $layout = $this->_getLayoutModel('move.xml');
+        $this->assertEquals('container2', $layout->getParentName('container1'));
+        $this->assertEquals('container1', $layout->getParentName('no.name2'));
+        $this->assertEquals('block_container', $layout->getParentName('no_name3'));
+
+        // verify `after` attribute
+        $this->assertEquals('block_container', $layout->getParentName('no_name'));
+        $childrenOrderArray = array_keys($layout->getChildBlocks($layout->getParentName('no_name')));
+        $positionAfter = array_search('child_block1', $childrenOrderArray);
+        $positionToVerify = array_search('no_name', $childrenOrderArray);
+        $this->assertEquals($positionAfter, --$positionToVerify);
+
+        // verify `before` attribute
+        $this->assertEquals('block_container', $layout->getParentName('no_name4'));
+        $childrenOrderArray = array_keys($layout->getChildBlocks($layout->getParentName('no_name4')));
+        $positionBefore = array_search('child_block2', $childrenOrderArray);
+        $positionToVerify = array_search('no_name4', $childrenOrderArray);
+        $this->assertEquals($positionBefore, ++$positionToVerify);
+    }
+
+    /**
+     * @expectedException Magento_Exception
+     */
+    public function testMoveBroken()
+    {
+        $this->_getLayoutModel('move_broken.xml');
+    }
+
+    /**
+     * @expectedException Magento_Exception
+     */
+    public function testMoveAliasBroken()
+    {
+        $this->_getLayoutModel('move_alias_broken.xml');
+    }
+
+    /**
+     * @expectedException Magento_Exception
+     */
+    public function testRemoveBroken()
+    {
+        $this->_getLayoutModel('remove_broken.xml');
+    }
+
+    /**
+     * @param string $case
+     * @param string $expectedResult
+     * @dataProvider sortSpecialCasesDataProvider
+     */
+    public function testSortSpecialCases($case, $expectedResult)
+    {
+        $layout = $this->_getLayoutModel($case);
+        $this->assertEquals($expectedResult, $layout->renderElement('root'));
+    }
+
+    /**
+     * @return array
+     */
+    public function sortSpecialCasesDataProvider()
+    {
+        return array(
+            'Before element which is after' => array('sort_before_after.xml', '312'),
+            'Before element which is previous' => array('sort_before_before.xml', '213'),
+            'After element which is after' => array('sort_after_after.xml', '312'),
+            'After element which is previous' => array('sort_after_previous.xml', '321'),
+        );
+    }
+
+
+    /**
+     * Prepare a layout model with pre-loaded fixture of an update XML
+     *
+     * @param string $fixtureFile
+     * @return Mage_Core_Model_Layout
+     */
+    protected function _getLayoutModel($fixtureFile)
+    {
+        /** @var $layout Mage_Core_Model_Layout */
+        $layout = Mage::getModel('Mage_Core_Model_Layout');
+        $layout->setXml(simplexml_load_file(
+            __DIR__ . "/_files/layout_directives_test/{$fixtureFile}",
+            'Mage_Core_Model_Layout_Element'
+        ));
+        $layout->generateElements();
+        return $layout;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php
index c2b7f550353..d3a8d537206 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTest.php
@@ -28,10 +28,27 @@
 /**
  * Layout integration tests
  *
- * @magentoDbIsolation enabled
+ * Note that some methods are not covered here, see the Mage_Core_Model_LayoutDirectivesTest
+ *
+ * @see Mage_Core_Model_LayoutDirectivesTest
  */
-class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase
+class Mage_Core_Model_LayoutTest extends PHPUnit_Framework_TestCase
 {
+    /**
+     * @var Mage_Core_Model_Layout
+     */
+    protected $_layout;
+
+    protected function setUp()
+    {
+        $this->_layout = Mage::getModel('Mage_Core_Model_Layout');
+    }
+
+    protected function tearDown()
+    {
+        $this->_layout = null;
+    }
+
     /**
      * @param array $inputArguments
      * @param string $expectedArea
@@ -56,6 +73,7 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase
     {
         $structure = new Magento_Data_Structure;
         $structure->createElement('test.container', array());
+        /** @var $layout Mage_Core_Model_Layout */
         $layout = Mage::getModel('Mage_Core_Model_Layout', array('structure' => $structure));
         $this->assertTrue($layout->hasElement('test.container'));
     }
@@ -80,166 +98,54 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase
         $this->assertTrue($this->_layout->isDirectOutput());
     }
 
-    /**
-     * @covers Mage_Core_Model_Layout::getAllBlocks
-     * @covers Mage_Core_Model_Layout::generateBlocks
-     * @covers Mage_Core_Model_Layout::getBlock
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     */
-    public function testGenerateXmlAndElements()
-    {
-        $this->_layout->generateXml();
-        /**
-         * Generate fixture
-         * file_put_contents(dirname(__FILE__) . '/_files/_layout_update.xml', $this->_model->getNode()->asNiceXml());
-         */
-        $this->assertXmlStringEqualsXmlFile(__DIR__ . '/_files/_layout_update.xml', $this->_layout->getXmlString());
-
-        $this->assertEquals(array(), $this->_layout->getAllBlocks());
-
-        $expectedBlocks = array(
-            'root',
-            'head',
-            'head.calendar',
-            'notifications',
-            'notification_baseurl',
-            'cache_notifications',
-            'notification_survey',
-            'notification_security',
-            'messages',
-            'root_schedule_block',
-            'index_notifications',
-            'index_notifications_copy'
-        );
-        $this->_layout->generateElements();
-
-        $actualBlocks = $this->_layout->getAllBlocks();
-        $this->assertEquals($expectedBlocks, array_keys($actualBlocks));
-
-        /** @var $block Mage_Adminhtml_Block_Page_Head */
-        $block = $this->_layout->getBlock('head');
-        $this->assertEquals('Magento Admin', $block->getTitle());
-
-        $block = $this->_layout->getBlock('head.calendar');
-        $this->assertSame($this->_layout->getBlock('head'), $block->getParentBlock());
-
-        /** @var $block Mage_Core_Block_Template */
-        $block = $this->_layout->getBlock('root');
-        $this->assertEquals('popup.phtml', $block->getTemplate());
-
-        $this->assertFalse($this->_layout->getBlock('test.nonexisting.block'));
-    }
-
-    /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     */
-    public function testLayoutDirectives()
+    public function testGenerateXml()
     {
-        /**
-         * Test move with the same alias
-         */
+        $structure = new Magento_Data_Structure;
         /** @var $layout Mage_Core_Model_Layout */
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->getUpdate()->load(array('layout_test_handle_move_the_same_alias'));
-        $layout->generateXml()->generateElements();
-        $this->assertEquals('container1', $layout->getParentName('no_name3'));
-
-        /**
-         * Test move with a new alias
-         */
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->getUpdate()->load(array('layout_test_handle_move_new_alias'));
-        $layout->generateXml()->generateElements();
-        $this->assertEquals('new_alias', $layout->getElementAlias('no_name3'));
-
-        /**
-         * Test layout action with anonymous parent block
-         */
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->getUpdate()->load(array('layout_test_handle_action_for_anonymous_parent_block'));
-        $layout->generateXml()->generateElements();
-        $this->assertEquals('schedule_block', $layout->getParentName('test.block.insert'));
-        $this->assertEquals('schedule_block_1', $layout->getParentName('test.block.append'));
-
-        /**
-         * Test layout remove directive
-         */
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->getUpdate()->load(array('layout_test_handle_remove'));
-        $layout->generateXml()->generateElements();
-        $this->assertFalse($layout->getBlock('no_name2'));
-        $this->assertFalse($layout->getBlock('child_block1'));
-        $this->assertTrue($layout->isBlock('child_block2'));
-
-        /**
-         * Test correct move
-         */
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->getUpdate()->load(array('layout_test_handle_move'));
-        $layout->generateXml()->generateElements();
-        $this->assertEquals('container2', $layout->getParentName('container1'));
-        $this->assertEquals('container1', $layout->getParentName('no.name2'));
-        $this->assertEquals('block_container', $layout->getParentName('no_name3'));
-
-        // verify `after` attribute
-        $this->assertEquals('block_container', $layout->getParentName('no_name'));
-        $childrenOrderArray = array_keys($layout->getChildBlocks($layout->getParentName('no_name')));
-        $positionAfter = array_search('child_block1', $childrenOrderArray);
-        $positionToVerify = array_search('no_name', $childrenOrderArray);
-        $this->assertEquals($positionAfter, --$positionToVerify);
-
-        // verify `before` attribute
-        $this->assertEquals('block_container', $layout->getParentName('no_name4'));
-        $childrenOrderArray = array_keys($layout->getChildBlocks($layout->getParentName('no_name4')));
-        $positionBefore = array_search('child_block2', $childrenOrderArray);
-        $positionToVerify = array_search('no_name4', $childrenOrderArray);
-        $this->assertEquals($positionBefore, ++$positionToVerify);
-    }
-
-    /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     * @expectedException Magento_Exception
-     */
-    public function testLayoutMoveDirectiveBroken()
-    {
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->getUpdate()->load(array('layout_test_handle_move_broken'));
-        $layout->generateXml()->generateElements();
-    }
-
-    /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     * @expectedException Magento_Exception
-     */
-    public function testLayoutMoveAliasBroken()
-    {
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->getUpdate()->load(array('layout_test_handle_move_alias_broken'));
-        $layout->generateXml()->generateElements();
+        $layout = $this->getMock('Mage_Core_Model_Layout', array('getUpdate'), array(
+            $this->getMock('Mage_Core_Model_BlockFactory', array(), array(), '', false),
+            $structure,
+            $this->getMock('Mage_Core_Model_Layout_Argument_Processor', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Layout_Translator', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Layout_ScheduledStructure', array(), array(), '', false),
+        ));
+        $merge = $this->getMock('StdClass', array('asSimplexml'));
+        $merge->expects($this->once())->method('asSimplexml')->will($this->returnValue(simplexml_load_string(
+            '<layout><container name="container1"></container></layout>',
+            'Mage_Core_Model_Layout_Element'
+        )));
+        $layout->expects($this->once())->method('getUpdate')->will($this->returnValue($merge));
+        $this->assertEmpty($layout->getXpath('/layout/container[@name="container1"]'));
+        $layout->generateXml();
+        $this->assertNotEmpty($layout->getXpath('/layout/container[@name="container1"]'));
     }
 
     /**
-     * @magentoConfigFixture default_store design/theme/full_name test/default
-     * @expectedException Magento_Exception
+     * A smoke test for generating elements
+     *
+     * See sophisticated tests at Mage_Core_Model_LayoutDirectivesTest
+     * @see Mage_Core_Model_LayoutDirectivesTest
      */
-    public function testGenerateElementsBroken()
+    public function testGenerateGetAllBlocks()
     {
-        $layout = Mage::getModel('Mage_Core_Model_Layout');
-        $layout->getUpdate()->load('layout_test_handle_remove_broken');
-        $layout->generateXml()->generateElements();
-    }
-
-    public function testRenderElement()
-    {
-        $utility = new Mage_Core_Utility_Layout($this);
-        $layout = $utility->getLayoutFromFixture(__DIR__ . '/_files/valid_layout_updates.xml',
-            $utility->getLayoutDependencies()
-        );
-        $layout->getUpdate()->load(array('first_handle', 'a_handle', 'another_handle'));
-        $layout->generateXml()->generateElements();
-        $this->assertEmpty($layout->renderElement('nonexisting_element'));
-        $this->assertEquals("Value: 1 Reference: 1.1\nValue: 2 Reference: 2.2\n", $layout->renderElement('container1'));
-        $this->assertEquals("Value: 1 Reference: 1.1\n", $layout->renderElement('block1'));
+        $this->_layout->setXml(simplexml_load_string(
+            '<layout>
+                <block type="Mage_Core_Block_Text" name="block1">
+                    <block type="Mage_Core_Block_Text"/>
+                </block>
+                <block type="Mage_Core_Block_Text" template="test"/>
+                <block type="Mage_Core_Block_Text"/>
+            </layout>',
+            'Mage_Core_Model_Layout_Element'
+        ));
+        $this->assertEquals(array(), $this->_layout->getAllBlocks());
+        $this->_layout->generateElements();
+        $expected = array('block1', 'block1_schedule_block', 'schedule_block', 'schedule_block_1');
+        $this->assertSame($expected, array_keys($this->_layout->getAllBlocks()));
+        $child = $this->_layout->getBlock('block1_schedule_block');
+        $this->assertSame($this->_layout->getBlock('block1'), $child->getParentBlock());
+        $this->assertEquals('test', $this->_layout->getBlock('schedule_block')->getData('template'));
+        $this->assertFalse($this->_layout->getBlock('nonexisting'));
     }
 
     public function testGetElementProperty()
@@ -272,7 +178,7 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase
     public function testSetUnsetBlock()
     {
         $expectedBlockName = 'block_' . __METHOD__;
-        $expectedBlock = Mage::app()->getLayout()->createBlock('Mage_Core_Block_Text');
+        $expectedBlock = $this->_layout->createBlock('Mage_Core_Block_Text');
 
         $this->_layout->setBlock($expectedBlockName, $expectedBlock);
         $this->assertSame($expectedBlock, $this->_layout->getBlock($expectedBlockName));
@@ -413,32 +319,6 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase
         $this->assertSame(array('two', 'four', 'three'), $layout->getChildNames('one'));
     }
 
-    /**
-     * @param string $handle
-     * @param string $expectedResult
-     * @dataProvider sortSpecialCasesDataProvider
-     */
-    public function testSortSpecialCases($handle, $expectedResult)
-    {
-        $utility = new Mage_Core_Utility_Layout($this);
-        $layout = $utility->getLayoutFromFixture(__DIR__ . '/_files/sort_special_cases.xml',
-            $utility->getLayoutDependencies()
-        );
-        $layout->getUpdate()->load($handle);
-        $layout->generateXml()->generateElements();
-        $this->assertEquals($expectedResult, $layout->renderElement('root'));
-    }
-
-    public function sortSpecialCasesDataProvider()
-    {
-        return array(
-            'Before element which is after' => array('before_after', '312'),
-            'Before element which is previous' => array('before_before', '213'),
-            'After element which is after' => array('after_after', '312'),
-            'After element which is previous' => array('after_previous', '321'),
-        );
-    }
-
     public function testGetChildBlocks()
     {
         $this->_layout->addContainer('parent', 'Parent');
@@ -508,43 +388,8 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase
         $this->assertSame($block, $this->_layout->getBlock('test'));
     }
 
-    /**
-     * Invoke getBlock() while layout is being generated
-     *
-     * Assertions in this test are pure formalism. The point is to emulate situation where block refers to other block
-     * while the latter hasn't been generated yet, and assure that there is no crash
-     */
-    public function testGetBlockUnscheduled()
-    {
-        $utility = new Mage_Core_Utility_Layout($this);
-        $layout = $utility->getLayoutFromFixture(__DIR__ . '/_files/valid_layout_updates.xml',
-            $utility->getLayoutDependencies()
-        );
-        $layout->getUpdate()->load(array('get_block_special_case'));
-        $layout->generateXml()->generateElements();
-        $this->assertInstanceOf('Mage_Core_Block_Text', $layout->getBlock('block1'));
-        $this->assertInstanceOf('Mage_Core_Block_Text', $layout->getBlock('block2'));
-    }
-
-    /**
-     * @expectedException Magento_Exception
-     */
-    public function testGetBlockUnscheduledException()
-    {
-        $utility = new Mage_Core_Utility_Layout($this);
-        $layout = $utility->getLayoutFromFixture(__DIR__ . '/_files/valid_layout_updates.xml',
-            $utility->getLayoutDependencies()
-        );
-        $layout->getUpdate()->load(array('get_block_special_case_exception'));
-        $layout->generateXml();
-        $layout->generateElements();
-    }
-
     public function testGetParentName()
     {
-        /**
-         * Test get name
-         */
         $this->_layout->addContainer('one', 'One');
         $this->_layout->addContainer('two', 'Two', array(), 'one');
         $this->assertFalse($this->_layout->getParentName('one'));
@@ -586,23 +431,11 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase
         $this->assertInstanceOf('Mage_Core_Block_Messages', $this->_layout->getMessagesBlock());
     }
 
-    /**
-     * @param string $blockType
-     * @param string $expectedClassName
-     * @dataProvider getBlockSingletonDataProvider
-     */
-    public function testGetBlockSingleton($blockType, $expectedClassName)
-    {
-        $block = $this->_layout->getBlockSingleton($blockType);
-        $this->assertInstanceOf($expectedClassName, $block);
-        $this->assertSame($block, $this->_layout->getBlockSingleton($blockType));
-    }
-
-    public function getBlockSingletonDataProvider()
+    public function testGetBlockSingleton()
     {
-        return array(
-            array('Mage_Core_Block_Text', 'Mage_Core_Block_Text')
-        );
+        $block = $this->_layout->getBlockSingleton('Mage_Core_Block_Text');
+        $this->assertInstanceOf('Mage_Core_Block_Text', $block);
+        $this->assertSame($block, $this->_layout->getBlockSingleton('Mage_Core_Block_Text'));
     }
 
     public function testHelper()
@@ -621,6 +454,9 @@ class Mage_Core_Model_LayoutTest extends Mage_Core_Model_LayoutTestBase
         $this->assertEquals($moduleName, Mage_Core_Model_Layout::findTranslationModuleName($node));
     }
 
+    /**
+     * @return array
+     */
     public function findTranslationModuleNameDefaultsDataProvider()
     {
         $layout = '<layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Magento/ApiTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Magento/ApiTest.php
new file mode 100644
index 00000000000..15f69d4c7cb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Magento/ApiTest.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Core module API tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Magento info Api tests
+ */
+class Mage_Core_Model_Magento_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test magento magento info retrieving
+     */
+    public function testInfo()
+    {
+        $magentoInfo = Magento_Test_Helper_Api::call($this, 'magentoInfo');
+        $this->assertNotEmpty($magentoInfo['magento_version']);
+        $this->assertNotEmpty($magentoInfo['magento_edition']);
+        $this->assertEquals(Mage::getEdition(), $magentoInfo['magento_edition']);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ObserverTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ObserverTest.php
index 4d0332d3128..c50b12dedc4 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/ObserverTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/ObserverTest.php
@@ -38,24 +38,28 @@ class Mage_Core_Model_ObserverTest extends PHPUnit_Framework_TestCase
      */
     public function testThemeRegistration()
     {
+        $baseDir = 'base_dir';
+        $pattern = 'path_pattern';
+
         $eventObserver = $this->_createEventObserverForThemeRegistration();
-        $eventObserver->getEvent()->setBaseDir(dirname(__FILE__) . DS . '_files' . DS . 'design');
+        $eventObserver->getEvent()->setBaseDir($baseDir);
+        $eventObserver->getEvent()->setPathPattern($pattern);
+
+        /** @var $objectManager Magento_Test_ObjectManager */
+        $objectManager = Mage::getObjectManager();
+        $themeRegistration = $this->getMock(
+            'Mage_Core_Model_Theme_Registration',
+            array('register'),
+            array($objectManager->create('Mage_Core_Model_Theme'))
+        );
+        $themeRegistration->expects($this->once())
+            ->method('register')
+            ->with($baseDir, $pattern);
+        $objectManager->addSharedInstance($themeRegistration, 'Mage_Core_Model_Theme_Registration');
 
         /** @var $observer Mage_Core_Model_Observer */
         $observer = Mage::getModel('Mage_Core_Model_Observer');
         $observer->themeRegistration($eventObserver);
-
-        $defaultModel = $this->_getThemeModel();
-        $defaultModel->load('default/default', 'theme_path');
-
-        $iphoneModel = $this->_getThemeModel();
-        $iphoneModel->load('default/default_iphone', 'theme_path');
-
-        $this->assertEquals('Default', $defaultModel->getThemeTitle());
-        $this->assertEquals(null, $defaultModel->getParentId());
-
-        $this->assertEquals('Iphone', $iphoneModel->getThemeTitle());
-        $this->assertEquals($defaultModel->getId(), $iphoneModel->getParentId());
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Store/ApiTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Store/ApiTest.php
new file mode 100644
index 00000000000..c72af0f9566
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Store/ApiTest.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Core module API tests.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Magento store Api tests
+ *
+ * @magentoDataFixture Mage/Core/_files/store.php
+ */
+class Mage_Core_Model_Store_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test store info.
+     */
+    public function testInfo()
+    {
+        $expectedStore = Mage::app()->getStore('fixturestore');
+        $storeInfo = Magento_Test_Helper_Api::call($this, 'storeInfo', array(
+            'storeId' => 'fixturestore',
+        ));
+        $expectedData= $expectedStore->getData();
+        $this->assertEquals($expectedData, $storeInfo);
+    }
+
+    /**
+     * Test stores list.
+     */
+    public function testList()
+    {
+        $actualStores = Magento_Test_Helper_Api::call($this, 'storeList');
+        $expectedStores = Mage::app()->getStores();
+        /** @var Mage_Core_Model_Store $expectedStore */
+        foreach ($expectedStores as $expectedStore) {
+            $expectedStoreFound = false;
+            foreach ($actualStores as $actualStore) {
+                if ($actualStore['store_id'] == $expectedStore->getId()) {
+                    $this->assertEquals($expectedStore->getData(), $actualStore);
+                    $expectedStoreFound = true;
+                }
+            }
+            if (!$expectedStoreFound) {
+                $this->fail(sprintf('Store "%s" was not found in API response.', $expectedStore->getFrontendName()));
+            }
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Install/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Store/GroupTest.php
similarity index 53%
rename from dev/tests/integration/testsuite/Mage/Install/Helper/DataTest.php
rename to dev/tests/integration/testsuite/Mage/Core/Model/Store/GroupTest.php
index 70967b43f73..96a086c6e78 100644
--- a/dev/tests/integration/testsuite/Mage/Install/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Store/GroupTest.php
@@ -19,25 +19,37 @@
  * needs please refer to http://www.magentocommerce.com for more information.
  *
  * @category    Magento
- * @package     Mage_Install
+ * @package     Mage_Core
  * @subpackage  integration_tests
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-class Mage_Install_Helper_DataTest extends PHPUnit_Framework_TestCase
+class Mage_Core_Model_Store_GroupTest extends PHPUnit_Framework_TestCase
 {
-    public function testCleanVarFolder()
+    /**
+     * @var Mage_Core_Model_Store_Group
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $eventDispatcher = Mage::getObjectManager()->get('Mage_Core_Model_Event_Manager');
+        $cacheManager = Mage::getObjectManager()->get('Mage_Core_Model_Cache');
+        $this->_model = new Mage_Core_Model_Store_Group($eventDispatcher, $cacheManager);
+    }
+
+    public function tearDown()
+    {
+        $this->_model = null;
+    }
+
+    public function testSetGetWebsite()
     {
-        $rootFolder = Mage::getConfig()->getVarDir() . DIRECTORY_SEPARATOR . 'parentFolder';
-        $subFolderA = $rootFolder . DIRECTORY_SEPARATOR . 'subFolderA' . DIRECTORY_SEPARATOR;
-        $subFolderB = $rootFolder . DIRECTORY_SEPARATOR . 'subFolderB' . DIRECTORY_SEPARATOR;
-        @mkdir($subFolderA, 0777, true);
-        @mkdir($subFolderB, 0777, true);
-        @file_put_contents($subFolderB . 'test.txt', 'Some text here');
-        $helper = Mage::helper('Mage_Install_Helper_Data');
-        $helper->setVarSubFolders(array($rootFolder));
-        $helper->cleanVarFolder();
-        $this->assertFalse(is_dir($rootFolder));
+        $this->assertFalse($this->_model->getWebsite());
+        $website = Mage::app()->getWebsite();
+        $this->_model->setWebsite($website);
+        $actualResult = $this->_model->getWebsite();
+        $this->assertSame($website, $actualResult);
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/StoreTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/StoreTest.php
index 379a1b038cf..7504294c377 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/StoreTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/StoreTest.php
@@ -84,6 +84,24 @@ class Mage_Core_Model_StoreTest extends PHPUnit_Framework_TestCase
         $this->_model->setConfig(Mage_Core_Model_Store::XML_PATH_USE_REWRITES, 0);
     }
 
+    public function testSetGetWebsite()
+    {
+        $this->assertFalse($this->_model->getWebsite());
+        $website = Mage::app()->getWebsite();
+        $this->_model->setWebsite($website);
+        $actualResult = $this->_model->getWebsite();
+        $this->assertSame($website, $actualResult);
+    }
+
+    public function testSetGetGroup()
+    {
+        $this->assertFalse($this->_model->getGroup());
+        $storeGroup = Mage::app()->getGroup();
+        $this->_model->setGroup($storeGroup);
+        $actualResult = $this->_model->getGroup();
+        $this->assertSame($storeGroup, $actualResult);
+    }
+
     /**
      * Isolation is enabled, as we pollute config with rewrite values
      *
@@ -123,29 +141,30 @@ class Mage_Core_Model_StoreTest extends PHPUnit_Framework_TestCase
             array(Mage_Core_Model_Store::URL_TYPE_DIRECT_LINK, false, true,  'http://localhost/index.php/'),
             array(Mage_Core_Model_Store::URL_TYPE_DIRECT_LINK, true,  false, 'http://localhost/'),
             array(Mage_Core_Model_Store::URL_TYPE_DIRECT_LINK, true,  true,  'http://localhost/'),
-            array(Mage_Core_Model_Store::URL_TYPE_JS, false, false, 'http://localhost/pub/lib/'),
-            array(Mage_Core_Model_Store::URL_TYPE_JS, false, true,  'http://localhost/pub/lib/'),
-            array(Mage_Core_Model_Store::URL_TYPE_JS, true,  false, 'http://localhost/pub/lib/'),
-            array(Mage_Core_Model_Store::URL_TYPE_JS, true,  true,  'http://localhost/pub/lib/'),
+            array(Mage_Core_Model_Store::URL_TYPE_LIB, false, false, 'http://localhost/pub/lib/'),
+            array(Mage_Core_Model_Store::URL_TYPE_LIB, false, true,  'http://localhost/pub/lib/'),
+            array(Mage_Core_Model_Store::URL_TYPE_LIB, true,  false, 'http://localhost/pub/lib/'),
+            array(Mage_Core_Model_Store::URL_TYPE_LIB, true,  true,  'http://localhost/pub/lib/'),
             array(Mage_Core_Model_Store::URL_TYPE_MEDIA, false, false, 'http://localhost/pub/media/'),
             array(Mage_Core_Model_Store::URL_TYPE_MEDIA, false, true,  'http://localhost/pub/media/'),
             array(Mage_Core_Model_Store::URL_TYPE_MEDIA, true,  false, 'http://localhost/pub/media/'),
             array(Mage_Core_Model_Store::URL_TYPE_MEDIA, true,  true,  'http://localhost/pub/media/'),
-            array(Mage_Core_Model_Store::URL_TYPE_THEME, false, false, 'http://localhost/pub/media/theme/'),
-            array(Mage_Core_Model_Store::URL_TYPE_THEME, false, true,  'http://localhost/pub/media/theme/'),
-            array(Mage_Core_Model_Store::URL_TYPE_THEME, true,  false, 'http://localhost/pub/media/theme/'),
-            array(Mage_Core_Model_Store::URL_TYPE_THEME, true,  true,  'http://localhost/pub/media/theme/')
         );
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testGetBaseUrlInPub()
     {
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_URIS => array(Mage_Core_Model_Dir::PUB => '')
+        ));
         $this->_model->load('default');
-        $_SERVER['SCRIPT_FILENAME'] = 'test/pub/index.php';
 
         $this->assertEquals(
             'http://localhost/lib/',
-            $this->_model->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_JS)
+            $this->_model->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LIB)
         );
         $this->assertEquals(
             'http://localhost/media/',
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/Theme/CollectionTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/Theme/CollectionTest.php
index 7bde8095192..cb8d54c4f7e 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/Theme/CollectionTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/Theme/CollectionTest.php
@@ -37,8 +37,6 @@ class Mage_Core_Model_Theme_CollectionTest extends PHPUnit_Framework_TestCase
      */
     public function testLoadThemesFromFileSystem()
     {
-        Mage::app()->getConfig()->getOptions()->setDesignDir(dirname(__DIR__));
-
         $baseDesignDir = implode(DS, array(__DIR__, '..', '_files', 'design'));
         $pathPattern = implode(DS, array('frontend', 'default', '*', 'theme.xml'));
 
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/ThemeTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/ThemeTest.php
index 67b1d204fc8..40cf31279d7 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/ThemeTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/ThemeTest.php
@@ -29,6 +29,8 @@ class Mage_Core_Model_ThemeTest extends PHPUnit_Framework_TestCase
 {
     /**
      * Test crud operations for theme model using valid data
+     *
+     * @magentoDbIsolation enabled
      */
     public function testCrud()
     {
@@ -42,22 +44,17 @@ class Mage_Core_Model_ThemeTest extends PHPUnit_Framework_TestCase
 
     /**
      * Load from configuration
-     *
-     * @magentoAppIsolation enabled
-     * @magentoDbIsolation enabled
      */
     public function testLoadFromConfiguration()
     {
         $designPath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'design';
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array($designPath));
-        $themeUtility->registerThemes()->setDesignTheme('default/default', 'frontend');
-
         $themePath = implode(DS, array('frontend', 'default', 'default', 'theme.xml'));
 
         /** @var $themeModel Mage_Core_Model_Theme */
         $themeModel = Mage::getObjectManager()->create('Mage_Core_Model_Theme');
-        $theme = $themeModel->getCollectionFromFilesystem()->setBaseDir($designPath)->addTargetPattern($themePath)
+        $theme = $themeModel->getCollectionFromFilesystem()
+            ->setBaseDir($designPath)
+            ->addTargetPattern($themePath)
             ->getFirstItem();
 
         $this->assertEquals($this->_expectedThemeDataFromConfiguration(), $theme->getData());
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/TranslateTest.php b/dev/tests/integration/testsuite/Mage/Core/Model/TranslateTest.php
index d2a16de7ec3..3dcc3bdf304 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/TranslateTest.php
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/TranslateTest.php
@@ -37,20 +37,18 @@ class Mage_Core_Model_TranslateTest extends PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        Mage::getConfig()->setOptions(array(
-            'locale_dir' => dirname(__FILE__) . '/_files/locale',
-        ));
+        $pathChunks = array(dirname(__FILE__), '_files', 'design', 'frontend', 'test', 'default', 'locale', 'en_US',
+            'translate.csv');
 
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__FILE__) . '/_files/design',
-            Mage::getDesign()
-        ));
-        $themeUtility->registerThemes()->setDesignTheme('test/default', 'frontend');
+        $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
+        $design = $this->getMock('Mage_Core_Model_Design_Package', array('getLocaleFileName'), array($filesystem));
+        $design->expects($this->any())
+            ->method('getLocaleFileName')
+            ->will($this->returnValue(implode(DS, $pathChunks)));
 
         Mage::getConfig()->setModuleDir('Mage_Core', 'locale', dirname(__FILE__) . '/_files/Mage/Core/locale');
         Mage::getConfig()->setModuleDir('Mage_Catalog', 'locale', dirname(__FILE__) . '/_files/Mage/Catalog/locale');
-        $this->_model = Mage::getModel('Mage_Core_Model_Translate');
+        $this->_model = Mage::getModel('Mage_Core_Model_Translate', array($design));
         $this->_model->init('frontend');
     }
 
@@ -153,6 +151,10 @@ class Mage_Core_Model_TranslateTest extends PHPUnit_Framework_TestCase
             array(
                 Mage::getModel('Mage_Core_Model_Translate_Expr', array('text' => 'text_with_no_translation')),
                 'text_with_no_translation'
+            ),
+            array(
+                'Design value to translate',
+                'Design translated value'
             )
         );
     }
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/layout.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/layout.xml
index 16875f3bfc6..54f6e843a71 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/layout.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/layout.xml
@@ -68,224 +68,4 @@
             <action method="getSomething"/>
         </reference>
     </layout_test_handle_main>
-
-    <layout_test_handle_move>
-        <container name="container1" label="Container 1">
-            <block type="Mage_Core_Block_Text" name="no.name2" as="no.name2"/>
-        </container>
-        <container name="container2" label="Container 2"/>
-        <move element="container1" destination="container2"/>
-
-        <block type="Mage_Core_Block_Text" name="block_container" as="block.container">
-            <block type="Mage_Core_Block_Text" name="child_block1"/>
-            <block type="Mage_Core_Block_Text" name="child_block2"/>
-        </block>
-
-        <container name="container3" label="Container 3">
-            <block type="Mage_Core_Block_Text" name="no_name"/>
-        </container>
-        <move element="no_name" destination="block_container" after="child_block1"/>
-
-        <block type="Mage_Core_Block_Text" name="no_name4"/>
-        <move element="no_name4" destination="block_container" before="child_block2"/>
-
-        <move element="no_name3" destination="block_container"/>
-        <block type="Mage_Core_Block_Text" name="no_name3"/>
-    </layout_test_handle_move>
-
-    <layout_test_handle_arguments>
-        <block type="Mage_Core_Block_Text" name="block_with_args">
-            <arguments>
-                <one>1</one>
-                <two>2</two>
-            </arguments>
-        </block>
-        <reference name="block_with_args">
-            <arguments>
-                <two>two</two>
-                <three>3</three>
-            </arguments>
-        </reference>
-    </layout_test_handle_arguments>
-
-    <layout_test_handle_arguments_complex_values>
-        <block type="Mage_Core_Block_Text" name="block_with_args_complex_values">
-            <arguments>
-                <one>
-                    <parameters>
-                        <first>1</first>
-                        <second>2</second>
-                    </parameters>
-                </one>
-                <two>
-                    <parameter_one>
-                        <value>Paramter One</value>
-                    </parameter_one>
-                    <parameter_two>2</parameter_two>
-                </two>
-                <three>
-                    <extra>
-                        <key1>value</key1>
-                    </extra>
-                </three>
-            </arguments>
-        </block>
-        <reference name="block_with_args_complex_values">
-            <arguments>
-                <two>two</two>
-                <three>
-                    <extra>
-                        <key1>value1</key1>
-                        <key2>value2</key2>
-                    </extra>
-                </three>
-            </arguments>
-        </reference>
-    </layout_test_handle_arguments_complex_values>
-
-    <layout_test_handle_arguments_object_type>
-        <block type="Mage_Core_Block_Text" name="block_with_object_args">
-            <arguments>
-                <one type='object'>Mage_Core_Block_Text</one>
-                <two type='object'>Mage_Core_Block_Text</two>
-                <three type='object'>Mage_Core_Block_Text</three>
-                <four type='object'>Mage_Core_Block_Text</four>
-            </arguments>
-        </block>
-        <reference name="block_with_object_args">
-            <arguments>
-                <two>Mage_Core_Block_Messages</two>
-                <three type=''>3</three>
-            </arguments>
-        </reference>
-    </layout_test_handle_arguments_object_type>
-
-    <layout_test_handle_arguments_object_type_updaters>
-        <block type="Mage_Core_Block_Text" name="block_with_object_updater_args">
-            <arguments>
-                <one type='object'>Mage_Core_Block_Text</one>
-                <two>0</two>
-            </arguments>
-        </block>
-        <reference name="block_with_object_updater_args">
-            <arguments>
-                <one>
-                    <updater>Mage_Core_Model_LayoutArgumentObjectUpdater</updater>
-                    <updater>Mage_Core_Model_LayoutArgumentObjectUpdater</updater>
-                </one>
-                <two>
-                    <updater>Mage_Core_Model_LayoutArgumentSimpleUpdater</updater>
-                </two>
-            </arguments>
-        </reference>
-        <reference name="block_with_object_updater_args">
-            <arguments>
-                <one>
-                    <updater>Mage_Core_Model_LayoutArgumentObjectUpdater</updater>
-                </one>
-                <two>
-                    <updater>Mage_Core_Model_LayoutArgumentSimpleUpdater</updater>
-                </two>
-            </arguments>
-        </reference>
-    </layout_test_handle_arguments_object_type_updaters>
-
-    <layout_test_handle_arguments_url_type>
-        <block type="Mage_Core_Block_Text" name="block_with_url_args">
-            <arguments>
-                <one type="url">
-                    <path>customer/account/login</path>
-                    <params>
-                        <_current>1</_current>
-                        <_secure>1</_secure>
-                    </params>
-                </one>
-                <two type="url">
-                    <path>customer/account/logout</path>
-                    <params>
-                        <_current>1</_current>
-                        <_secure>1</_secure>
-                        <customer_id>2</customer_id>
-                    </params>
-                </two>
-            </arguments>
-        </block>
-        <reference name="block_with_url_args">
-            <arguments>
-                <two>
-                    <params>
-                        <customer_id>3</customer_id>
-                    </params>
-                </two>
-            </arguments>
-        </reference>
-    </layout_test_handle_arguments_url_type>
-
-
-    <layout_test_handle_move_broken>
-        <container name="container1" label="Container 1"/>
-        <move element="no_name3"/>
-        <block type="Mage_Core_Block_Text" name="no_name3"/>
-    </layout_test_handle_move_broken>
-
-    <layout_test_handle_move_alias_broken>
-        <container name="container1" label="Container 1">
-            <block type="Mage_Core_Block_Text" name="no_name1" as="same_alias"/>
-        </container>
-        <move element="no_name3" destination="container1" as="same_alias"/>
-        <block type="Mage_Core_Block_Text" name="no_name3" as="same_alias"/>
-    </layout_test_handle_move_alias_broken>
-
-    <layout_test_handle_move_the_same_alias>
-        <container name="container1" label="Container 1">
-            <block type="Mage_Core_Block_Text" name="no_name1" as="same_alias"/>
-        </container>
-        <move element="no_name3" destination="container1"/>
-        <block type="Mage_Core_Block_Text" name="no_name3" as="same_alias"/>
-    </layout_test_handle_move_the_same_alias>
-
-    <layout_test_handle_move_new_alias>
-        <container name="container1" label="Container 1">
-            <block type="Mage_Core_Block_Text" name="no_name1" as="same_alias"/>
-        </container>
-        <move element="no_name3" destination="container1" as="new_alias"/>
-        <block type="Mage_Core_Block_Text" name="no_name3" as="same_alias"/>
-    </layout_test_handle_move_new_alias>
-
-    <layout_test_handle_remove>
-        <container name="container1" label="Container 1">
-            <block type="Mage_Core_Block_Text" name="no_name2"/>
-        </container>
-        <remove name="container1"/>
-
-        <remove name="child_block1"/>
-        <block type="Mage_Core_Block_Text" name="block_container" as="block.container">
-            <block type="Mage_Core_Block_Text" name="child_block1"/>
-            <block type="Mage_Core_Block_Text" name="child_block2"/>
-        </block>
-        <remove name="not_exist"/>
-    </layout_test_handle_remove>
-
-    <layout_test_handle_remove_broken>
-        <block name="test.broken.block" type="Mage_Core_Block_Text"/>
-        <remove name="test.broken.block"/>
-        <block type="Mage_Core_Block_Template" name="bug.without.name.action.is.ignored">
-            <action method="insert"><element>test.broken.block</element></action>
-            <action method="append"><element>test.broken.block</element></action>
-        </block>
-    </layout_test_handle_remove_broken>
-
-
-    <layout_test_handle_action_for_anonymous_parent_block>
-        <block name="test.block.insert" type="Mage_Core_Block_Text"/>
-
-        <block type="Mage_Core_Block_Template">
-            <action method="insert"><element>test.block.insert</element></action>
-        </block>
-
-        <block name="test.block.append" type="Mage_Core_Block_Text"/>
-        <block type="Mage_Core_Block_Text">
-            <action method="append"><element>test.block.append</element></action>
-        </block>
-    </layout_test_handle_action_for_anonymous_parent_block>
 </layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/test.phtml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/test.phtml
index 992c4c873b3..708bcd7549e 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/test.phtml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/frontend/test/default/Mage_Core/test.phtml
@@ -24,4 +24,4 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-echo "Value: {$this->getTestValue()} Reference: {$this->getReferenceValue()}\n";
+echo 'Content of this file is not asserted. Only its presence.';
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/themes.php b/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/themes.php
new file mode 100644
index 00000000000..c0082d1d77e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/design/themes.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Core
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $registration Mage_Core_Model_Theme_Registration */
+$registration = Mage::getModel('Mage_Core_Model_Theme_Registration');
+$registration->register(
+    __DIR__,
+    implode(DIRECTORY_SEPARATOR, array('*', '*', '*', 'theme.xml'))
+);
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/fallback/pub/js/mage/script.js b/dev/tests/integration/testsuite/Mage/Core/Model/_files/fallback/pub/lib/mage/script.js
similarity index 100%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/fallback/pub/js/mage/script.js
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/fallback/pub/lib/mage/script.js
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_no_custom_config/a.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/action_for_anonymous_parent_block.xml
similarity index 69%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_no_custom_config/a.xml
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/action_for_anonymous_parent_block.xml
index 781197f9e2a..cdbf362522a 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_no_custom_config/a.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/action_for_anonymous_parent_block.xml
@@ -19,15 +19,19 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Magento
- * @package     Magento_Core
- * @subpackage  integration_tests
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<root>
-    <a>
-        <value>a</value>
-    </a>
-</root>
+<layout>
+    <block name="test.block.insert" type="Mage_Core_Block_Text"/>
+
+    <block type="Mage_Core_Block_Template">
+        <action method="insert"><element>test.block.insert</element></action>
+    </block>
+
+    <block name="test.block.append" type="Mage_Core_Block_Text"/>
+    <block type="Mage_Core_Block_Text">
+        <action method="append"><element>test.block.append</element></action>
+    </block>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments.xml
new file mode 100644
index 00000000000..1e6ae71360a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <block type="Mage_Core_Block_Text" name="block_with_args">
+        <arguments>
+            <one>1</one>
+            <two>2</two>
+        </arguments>
+    </block>
+    <reference name="block_with_args">
+        <arguments>
+            <two>two</two>
+            <three>3</three>
+        </arguments>
+    </reference>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_complex_values.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_complex_values.xml
new file mode 100644
index 00000000000..29b414bb28c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_complex_values.xml
@@ -0,0 +1,59 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <block type="Mage_Core_Block_Text" name="block_with_args_complex_values">
+        <arguments>
+            <one>
+                <parameters>
+                    <first>1</first>
+                    <second>2</second>
+                </parameters>
+            </one>
+            <two>
+                <parameter_one>
+                    <value>Paramter One</value>
+                </parameter_one>
+                <parameter_two>2</parameter_two>
+            </two>
+            <three>
+                <extra>
+                    <key1>value</key1>
+                </extra>
+            </three>
+        </arguments>
+    </block>
+    <reference name="block_with_args_complex_values">
+        <arguments>
+            <two>two</two>
+            <three>
+                <extra>
+                    <key1>value1</key1>
+                    <key2>value2</key2>
+                </extra>
+            </three>
+        </arguments>
+    </reference>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_object_type.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_object_type.xml
new file mode 100644
index 00000000000..d49fd067c16
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_object_type.xml
@@ -0,0 +1,41 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <block type="Mage_Core_Block_Text" name="block_with_object_args">
+        <arguments>
+            <one type='object'>Mage_Core_Block_Text</one>
+            <two type='object'>Mage_Core_Block_Text</two>
+            <three type='object'>Mage_Core_Block_Text</three>
+            <four type='object'>Mage_Core_Block_Text</four>
+        </arguments>
+    </block>
+    <reference name="block_with_object_args">
+        <arguments>
+            <two>Mage_Core_Block_Messages</two>
+            <three type=''>3</three>
+        </arguments>
+    </reference>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_object_type_updaters.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_object_type_updaters.xml
new file mode 100644
index 00000000000..97d3821ee0f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_object_type_updaters.xml
@@ -0,0 +1,54 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <block type="Mage_Core_Block_Text" name="block_with_object_updater_args">
+        <arguments>
+            <one type='object'>Mage_Core_Block_Text</one>
+            <two>0</two>
+        </arguments>
+    </block>
+    <reference name="block_with_object_updater_args">
+        <arguments>
+            <one>
+                <updater>Mage_Core_Model_LayoutArgumentObjectUpdater</updater>
+                <updater>Mage_Core_Model_LayoutArgumentObjectUpdater</updater>
+            </one>
+            <two>
+                <updater>Mage_Core_Model_LayoutArgumentSimpleUpdater</updater>
+            </two>
+        </arguments>
+    </reference>
+    <reference name="block_with_object_updater_args">
+        <arguments>
+            <one>
+                <updater>Mage_Core_Model_LayoutArgumentObjectUpdater</updater>
+            </one>
+            <two>
+                <updater>Mage_Core_Model_LayoutArgumentSimpleUpdater</updater>
+            </two>
+        </arguments>
+    </reference>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_url_type.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_url_type.xml
new file mode 100644
index 00000000000..a266b64bb1a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/arguments_url_type.xml
@@ -0,0 +1,55 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <block type="Mage_Core_Block_Text" name="block_with_url_args">
+        <arguments>
+            <one type="url">
+                <path>customer/account/login</path>
+                <params>
+                    <_current>1</_current>
+                    <_secure>1</_secure>
+                </params>
+            </one>
+            <two type="url">
+                <path>customer/account/logout</path>
+                <params>
+                    <_current>1</_current>
+                    <_secure>1</_secure>
+                    <customer_id>2</customer_id>
+                </params>
+            </two>
+        </arguments>
+    </block>
+    <reference name="block_with_url_args">
+        <arguments>
+            <two>
+                <params>
+                    <customer_id>3</customer_id>
+                </params>
+            </two>
+        </arguments>
+    </reference>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/custom/invalid.pattern.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/get_block.xml
similarity index 81%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/custom/invalid.pattern.xml
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/get_block.xml
index 1430dc32c05..c5e0fc2dd49 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/custom/invalid.pattern.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/get_block.xml
@@ -19,11 +19,13 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Magento
- * @package     Magento_Core
- * @subpackage  integration_tests
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-intentionally non-well-formed XML
+<layout>
+    <block name="block1" type="Mage_Core_Block_Text">
+        <action method="getChildBlock"><value>block2</value></action>
+        <block name="block2" type="Mage_Core_Block_Text"/>
+    </block>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/get_block_exception.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/get_block_exception.xml
new file mode 100644
index 00000000000..fcf3c2319cd
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/get_block_exception.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <block name="block1" type="Mage_Core_Block_Text">
+        <container name="container" label="Container"/>
+        <action method="getChildBlock"><value>container</value></action>
+    </block>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move.xml
new file mode 100644
index 00000000000..272df53b954
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move.xml
@@ -0,0 +1,48 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="container1" label="Container 1">
+        <block type="Mage_Core_Block_Text" name="no.name2" as="no.name2"/>
+    </container>
+    <container name="container2" label="Container 2"/>
+    <move element="container1" destination="container2"/>
+
+    <block type="Mage_Core_Block_Text" name="block_container" as="block.container">
+        <block type="Mage_Core_Block_Text" name="child_block1"/>
+        <block type="Mage_Core_Block_Text" name="child_block2"/>
+    </block>
+
+    <container name="container3" label="Container 3">
+        <block type="Mage_Core_Block_Text" name="no_name"/>
+    </container>
+    <move element="no_name" destination="block_container" after="child_block1"/>
+
+    <block type="Mage_Core_Block_Text" name="no_name4"/>
+    <move element="no_name4" destination="block_container" before="child_block2"/>
+
+    <move element="no_name3" destination="block_container"/>
+    <block type="Mage_Core_Block_Text" name="no_name3"/>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_alias_broken.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_alias_broken.xml
new file mode 100644
index 00000000000..f8b7252018b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_alias_broken.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="container1" label="Container 1">
+        <block type="Mage_Core_Block_Text" name="no_name1" as="same_alias"/>
+    </container>
+    <move element="no_name3" destination="container1" as="same_alias"/>
+    <block type="Mage_Core_Block_Text" name="no_name3" as="same_alias"/>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/local.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_broken.xml
similarity index 85%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/local.xml
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_broken.xml
index 648546d88c1..0024fd3d4e9 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/local.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_broken.xml
@@ -19,13 +19,12 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    Magento
- * @package     Magento_Core
- * @subpackage  integration_tests
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<root>
-    <value>local</value>
-</root>
+<layout>
+    <container name="container1" label="Container 1"/>
+    <move element="no_name3"/>
+    <block type="Mage_Core_Block_Text" name="no_name3"/>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_new_alias.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_new_alias.xml
new file mode 100644
index 00000000000..50aa2e0b0e4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_new_alias.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="container1" label="Container 1">
+        <block type="Mage_Core_Block_Text" name="no_name1" as="same_alias"/>
+    </container>
+    <move element="no_name3" destination="container1" as="new_alias"/>
+    <block type="Mage_Core_Block_Text" name="no_name3" as="same_alias"/>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_the_same_alias.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_the_same_alias.xml
new file mode 100644
index 00000000000..349d77c0c34
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/move_the_same_alias.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="container1" label="Container 1">
+        <block type="Mage_Core_Block_Text" name="no_name1" as="same_alias"/>
+    </container>
+    <move element="no_name3" destination="container1"/>
+    <block type="Mage_Core_Block_Text" name="no_name3" as="same_alias"/>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/remove.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/remove.xml
new file mode 100644
index 00000000000..2fc0f35048b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/remove.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="container1" label="Container 1">
+        <block type="Mage_Core_Block_Text" name="no_name2"/>
+    </container>
+    <remove name="container1"/>
+
+    <remove name="child_block1"/>
+    <block type="Mage_Core_Block_Text" name="block_container" as="block.container">
+        <block type="Mage_Core_Block_Text" name="child_block1"/>
+        <block type="Mage_Core_Block_Text" name="child_block2"/>
+    </block>
+    <remove name="not_exist"/>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/remove_broken.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/remove_broken.xml
new file mode 100644
index 00000000000..65244c241ba
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/remove_broken.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <block name="test.broken.block" type="Mage_Core_Block_Text"/>
+    <remove name="test.broken.block"/>
+    <block type="Mage_Core_Block_Template" name="bug.without.name.action.is.ignored">
+        <action method="insert"><element>test.broken.block</element></action>
+        <action method="append"><element>test.broken.block</element></action>
+    </block>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/render.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/render.xml
new file mode 100644
index 00000000000..acae298c251
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/render.xml
@@ -0,0 +1,47 @@
+<?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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <!-- Despite reference element is not declared yet, it will "save this action for later" -->
+    <reference name="block1">
+        <action method="addText"><value>1</value></action>
+    </reference>
+    <container name="container1" label="Container 1">
+        <block type="Mage_Core_Block_Text" name="block1">
+            <action method="addText"><value>2</value></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="block2">
+            <action method="setText"><value>3</value></action>
+        </block>
+    </container>
+    <!-- A conventional use of reference - after element is declared -->
+    <reference name="block2">
+        <action method="setText"><value>4</value></action>
+    </reference>
+    <!-- Reference to non-existing element will remain ignored -->
+    <reference name="nonexistent">
+        <action method="addText"><value>5</value></action>
+    </reference>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_after_after.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_after_after.xml
new file mode 100644
index 00000000000..8e26cf42f4c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_after_after.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="root" label="Root">
+        <block type="Mage_Core_Block_Text" name="element1" after="element3">
+            <action method="setText"><text>1</text></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="element2" after="element1">
+            <action method="setText"><text>2</text></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="element3" after="element_non_existing">
+            <action method="setText"><text>3</text></action>
+        </block>
+    </container>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_after_previous.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_after_previous.xml
new file mode 100644
index 00000000000..361a8bb63fc
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_after_previous.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="root" label="Root">
+        <block type="Mage_Core_Block_Text" name="element1" after="element2">
+            <action method="setText"><text>1</text></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="element2" after="element3">
+            <action method="setText"><text>2</text></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="element3">
+            <!-- neither "before" or "after" specified, therefore insert before all elements -->
+            <action method="setText"><text>3</text></action>
+        </block>
+    </container>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_before_after.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_before_after.xml
new file mode 100644
index 00000000000..b8c63968053
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_before_after.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="root" label="Root">
+        <block type="Mage_Core_Block_Text" name="element1" before="element2">
+            <action method="setText"><text>1</text></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="element2" after="element3">
+            <action method="setText"><text>2</text></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="element3" after="-">
+            <action method="setText"><text>3</text></action>
+        </block>
+    </container>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_before_before.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_before_before.xml
new file mode 100644
index 00000000000..7dc8ed80e22
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/layout_directives_test/sort_before_before.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout>
+    <container name="root" label="Root">
+        <block type="Mage_Core_Block_Text" name="element1" before="element3">
+            <action method="setText"><text>1</text></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="element2" before="element1">
+            <action method="setText"><text>2</text></action>
+        </block>
+        <block type="Mage_Core_Block_Text" name="element3" before="element_non_existing">
+            <!-- element_non_existing doesn't exist, so element3 is generated at the end -->
+            <action method="setText"><text>3</text></action>
+        </block>
+    </container>
+</layout>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_no_custom_config/local.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/custom/local.xml
similarity index 82%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_no_custom_config/local.xml
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/custom/local.xml
index 648546d88c1..d0dbcd3f538 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_no_custom_config/local.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/custom/local.xml
@@ -27,5 +27,13 @@
  */
 -->
 <root>
-    <value>local</value>
+    <global>
+        <resources>
+            <core_setup>
+                <connection>
+                    <model>custom</model>
+                </connection>
+            </core_setup>
+        </resources>
+    </global>
 </root>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/custom/prohibited.filename.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/custom/prohibited.filename.xml
new file mode 100644
index 00000000000..12bcb4b28dd
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/custom/prohibited.filename.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_Core
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<root>
+    <global>
+        <resources>
+            <core_setup>
+                <connection>
+                    <model>prohibited_value</model>
+                </connection>
+            </core_setup>
+        </resources>
+    </global>
+</root>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/custom/local.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/local.xml
similarity index 82%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/custom/local.xml
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/local.xml
index ddf145258c0..c6d0fea0602 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_custom_config/custom/local.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/local.xml
@@ -27,5 +27,13 @@
  */
 -->
 <root>
-    <value>custom</value>
+    <global>
+        <resources>
+            <core_setup>
+                <connection>
+                    <model>local</model>
+                </connection>
+            </core_setup>
+        </resources>
+    </global>
 </root>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_no_custom_config/z.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/z.xml
similarity index 82%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_no_custom_config/z.xml
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/z.xml
index ef72118fde4..d01f67dedc6 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config_no_custom_config/z.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/local_config/z.xml
@@ -27,5 +27,13 @@
  */
 -->
 <root>
-    <value>z</value>
+    <global>
+        <resources>
+            <core_setup>
+                <connection>
+                    <model>z</model>
+                </connection>
+            </core_setup>
+        </resources>
+    </global>
 </root>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_custom_config/a.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/a.xml
similarity index 82%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_custom_config/a.xml
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/a.xml
index 64c1d4b50d4..9a1523b665f 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_custom_config/a.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/a.xml
@@ -27,5 +27,13 @@
  */
 -->
 <root>
-    <a/>
+    <global>
+        <resources>
+            <core_setup>
+                <connection>
+                    <model>a</model>
+                </connection>
+            </core_setup>
+        </resources>
+    </global>
 </root>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_no_custom_config/b.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/b.xml
similarity index 82%
rename from dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_no_custom_config/b.xml
rename to dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/b.xml
index 27130671a08..12376c1e653 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_no_custom_config/b.xml
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/b.xml
@@ -27,7 +27,13 @@
  */
 -->
 <root>
-    <a>
-        <value>b</value>
-    </a>
+    <global>
+        <resources>
+            <core_setup>
+                <connection>
+                    <model>b</model>
+                </connection>
+            </core_setup>
+        </resources>
+    </global>
 </root>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/custom/local.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/custom/local.xml
new file mode 100644
index 00000000000..d0dbcd3f538
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config/custom/local.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_Core
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<root>
+    <global>
+        <resources>
+            <core_setup>
+                <connection>
+                    <model>custom</model>
+                </connection>
+            </core_setup>
+        </resources>
+    </global>
+</root>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_custom_config/custom/local.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_custom_config/custom/local.xml
deleted file mode 100644
index 1430dc32c05..00000000000
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/local_config/no_local_config_custom_config/custom/local.xml
+++ /dev/null
@@ -1,29 +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.
- *
- * @category    Magento
- * @package     Magento_Core
- * @subpackage  integration_tests
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-intentionally non-well-formed XML
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/sort_special_cases.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/sort_special_cases.xml
deleted file mode 100644
index 4829969301f..00000000000
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/sort_special_cases.xml
+++ /dev/null
@@ -1,84 +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.
- *
- * @category    Magento
- * @package     Magento_Core
- * @subpackage  integration_tests
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<layouts>
-    <before_after>
-        <container name="root" label="Root">
-            <block type="Mage_Core_Block_Text" name="element1" before="element2">
-                <action method="setText"><text>1</text></action>
-            </block>
-            <block type="Mage_Core_Block_Text" name="element2" after="element3">
-                <action method="setText"><text>2</text></action>
-            </block>
-            <block type="Mage_Core_Block_Text" name="element3" after="-">
-                <action method="setText"><text>3</text></action>
-            </block>
-        </container>
-    </before_after>
-    <before_before>
-        <container name="root" label="Root">
-            <block type="Mage_Core_Block_Text" name="element1" before="element3">
-                <action method="setText"><text>1</text></action>
-            </block>
-            <block type="Mage_Core_Block_Text" name="element2" before="element1">
-                <action method="setText"><text>2</text></action>
-            </block>
-            <block type="Mage_Core_Block_Text" name="element3" before="element_non_existing">
-                <!-- element_non_existing doesn't exist, so element3 is generated at the end -->
-                <action method="setText"><text>3</text></action>
-            </block>
-        </container>
-    </before_before>
-    <after_after>
-        <container name="root" label="Root">
-            <block type="Mage_Core_Block_Text" name="element1" after="element3">
-                <action method="setText"><text>1</text></action>
-            </block>
-            <block type="Mage_Core_Block_Text" name="element2" after="element1">
-                <action method="setText"><text>2</text></action>
-            </block>
-            <block type="Mage_Core_Block_Text" name="element3" after="element_non_existing">
-                <action method="setText"><text>3</text></action>
-            </block>
-        </container>
-    </after_after>
-    <after_previous>
-        <container name="root" label="Root">
-            <block type="Mage_Core_Block_Text" name="element1" after="element2">
-                <action method="setText"><text>1</text></action>
-            </block>
-            <block type="Mage_Core_Block_Text" name="element2" after="element3">
-                <action method="setText"><text>2</text></action>
-            </block>
-            <block type="Mage_Core_Block_Text" name="element3">
-                <!-- neither "before" or "after" specified, therefore insert before all elements -->
-                <action method="setText"><text>3</text></action>
-            </block>
-        </container>
-    </after_previous>
-</layouts>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/_files/valid_layout_updates.xml b/dev/tests/integration/testsuite/Mage/Core/Model/_files/valid_layout_updates.xml
deleted file mode 100644
index 90693d68ad3..00000000000
--- a/dev/tests/integration/testsuite/Mage/Core/Model/_files/valid_layout_updates.xml
+++ /dev/null
@@ -1,73 +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.
- *
- * @category    Magento
- * @package     Magento_Core
- * @subpackage  integration_tests
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
--->
-<layouts>
-    <first_handle>
-        <!-- Despite reference element is not declared yet, it will "save this action for later" -->
-        <reference name="block1">
-            <action method="setReferenceValue"><value>1.1</value></action>
-        </reference>
-    </first_handle>
-
-    <a_handle>
-        <container name="container1" label="Container 1">
-            <block type="Mage_Core_Block_Template" name="block1" template="Mage_Core::test.phtml">
-                <action method="setTestValue"><value>1</value></action>
-            </block>
-            <block type="Mage_Core_Block_Template" name="block2" template="Mage_Core::test.phtml">
-                <action method="setTestValue"><value>2</value></action>
-            </block>
-        </container>
-    </a_handle>
-
-    <another_handle>
-        <!-- A conventional use of reference - after element is declared -->
-        <reference name="block2">
-            <action method="setReferenceValue"><value>2.2</value></action>
-        </reference>
-
-        <!-- Reference to non-existing element will remain ignored -->
-        <reference name="nonexistent">
-            <action method="setReferenceValue"><value>3.3</value></action>
-        </reference>
-    </another_handle>
-
-    <get_block_special_case>
-        <block name="block1" type="Mage_Core_Block_Text">
-            <action method="getChildBlock"><value>block2</value></action>
-            <block name="block2" type="Mage_Core_Block_Text"/>
-        </block>
-    </get_block_special_case>
-
-    <get_block_special_case_exception>
-        <block name="block1" type="Mage_Core_Block_Text">
-            <container name="container" label="Container"/>
-            <action method="getChildBlock"><value>container</value></action>
-        </block>
-    </get_block_special_case_exception>
-</layouts>
diff --git a/dev/tests/integration/testsuite/Mage/Core/Utility/Theme.php b/dev/tests/integration/testsuite/Mage/Core/Utility/Theme.php
deleted file mode 100644
index 28f449b2d6e..00000000000
--- a/dev/tests/integration/testsuite/Mage/Core/Utility/Theme.php
+++ /dev/null
@@ -1,211 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @category    Magento
- * @package     Magento
- * @subpackage  integration_tests
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Core theme utility
- */
-class Mage_Core_Utility_Theme
-{
-    /**
-     * @var string
-     */
-    protected $_designDir;
-
-    /**
-     * @var Mage_Core_Model_Design_Package
-     */
-    protected $_design;
-
-    /**
-     * @var Mage_Core_Model_Theme_Registration
-     */
-    protected $_register;
-
-    /**
-     * @var Mage_Core_Model_Theme
-     */
-    protected $_theme;
-
-    /**
-     * @var Mage_Core_Model_Resource_Theme_Collection
-     */
-    protected $_themesCollection;
-
-    /**
-     * @param string $designDir
-     * @param Mage_Core_Model_Design_Package $design
-     * @param Mage_Core_Model_Theme_Registration $registration
-     * @param Mage_Core_Model_Theme $theme
-     */
-    public function __construct(
-        $designDir = null,
-        Mage_Core_Model_Design_Package $design = null,
-        Mage_Core_Model_Theme_Registration $registration,
-        Mage_Core_Model_Theme $theme
-    ) {
-        $this->_designDir = $designDir;
-        $this->_design = $design ? $design : Mage::getDesign();
-        $this->_register = $registration;
-        $this->_theme = $theme;
-    }
-
-    /**
-     * @return Mage_Core_Model_Design_Package
-     */
-    public function getDesign()
-    {
-        return $this->_design;
-    }
-
-    /**
-     * Register mocked package model in di
-     *
-     * @static
-     */
-    public static function registerDesignMock()
-    {
-        /** @var $packageMock Mage_Core_Model_Design_Package|PHPUnit_Framework_MockObject_MockObject */
-        $packageMock = PHPUnit_Framework_MockObject_Generator::getMock(
-            'Mage_Core_Model_Design_Package', array('getConfigurationDesignTheme'),
-            array(self::_createFilesystem())
-        );
-        $package = Mage::getModel('Mage_Core_Model_Design_Package', array('filesystem' => self::_createFilesystem()));
-
-        $callBackFixture = function ($area, $params) use ($package, $packageMock) {
-            $area = $area ? $area : $packageMock->getArea();
-            if (isset($params['useId']) && $params['useId'] === false) {
-                return $package->getConfigurationDesignTheme($area, $params);
-            } else {
-                $params['useId'] = false;
-                /** @var $package Mage_Core_Model_Design_Package */
-                $configPath = $package->getConfigurationDesignTheme($area, $params);
-                return Mage_Core_Utility_Theme::getTheme($configPath, $area)->getId();
-            }
-        };
-
-        $packageMock->expects(new PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount)
-            ->method('getConfigurationDesignTheme')
-            ->will(new PHPUnit_Framework_MockObject_Stub_ReturnCallback($callBackFixture));
-
-        /** @var $objectManager Magento_Test_ObjectManager */
-        $objectManager = Mage::getObjectManager();
-        $objectManager->addSharedInstance($packageMock, 'Mage_Core_Model_Design_Package');
-    }
-
-
-    /**
-     * @return Magento_Filesystem
-     */
-    protected static function _createFilesystem()
-    {
-        return new Magento_Filesystem(new Magento_Filesystem_Adapter_Local());
-    }
-
-    /**
-     * @return Mage_Core_Utility_Theme
-     */
-    public function registerThemes()
-    {
-        Mage::app()->getConfig()->getOptions()->setDesignDir($this->_designDir);
-        $this->_register->register();
-        $this->_design->setDefaultDesignTheme();
-        return $this;
-    }
-
-    /**
-     * @return Mage_Core_Model_Resource_Theme_Collection
-     */
-    protected function _getCollection()
-    {
-        if (!$this->_themesCollection) {
-            $this->_themesCollection = $this->_theme->getCollection()->load();
-        }
-        return $this->_themesCollection;
-    }
-
-    /**
-     * @param string $themePath
-     * @param string|null $area
-     * @return Mage_Core_Model_Theme
-     */
-    public function getThemeByParams($themePath, $area)
-    {
-        /** @var $theme Mage_Core_Model_Theme */
-        foreach ($this->_getCollection() as $theme) {
-            if ($theme->getThemePath() === $themePath && $theme->getArea() === $area) {
-                return $theme;
-            }
-        }
-        return $this->_theme;
-    }
-
-    /**
-     * @param string $themePath
-     * @param string|null $area
-     * @return Mage_Core_Model_Theme
-     */
-    public static function getTheme($themePath, $area)
-    {
-        /** @var $theme Mage_Core_Model_Theme */
-        $theme = Mage::getSingleton('Mage_Core_Model_Theme');
-        $collection = $theme->getCollection()
-            ->addFieldToFilter('theme_path', $themePath)
-            ->addFieldToFilter('area', $area)
-            ->load();
-        return $collection->getFirstItem();
-    }
-
-    /**
-     * @param string $themePath
-     * @param null $area
-     * @return Mage_Core_Utility_Theme
-     */
-    public function setDesignTheme($themePath, $area = null)
-    {
-        if (empty($area)) {
-            $area = $this->_design->getArea();
-        }
-        $theme = $this->getThemeByParams($themePath, $area);
-        $this->_design->setDesignTheme($theme, $area);
-        return $this;
-    }
-
-    /**
-     * @return array
-     */
-    public function getStructure()
-    {
-        $structure = array();
-        /** @var $theme Mage_Core_Model_Theme */
-        foreach ($this->_getCollection() as $theme) {
-            if ($theme->getId() && $theme->getThemePath()) {
-                $structure[$theme->getArea()][$theme->getThemePath()] = $theme;
-            }
-        }
-        return $structure;
-    }
-}
diff --git a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTestBase.php b/dev/tests/integration/testsuite/Mage/Core/_files/media_for_change.php
similarity index 50%
rename from dev/tests/integration/testsuite/Mage/Core/Model/LayoutTestBase.php
rename to dev/tests/integration/testsuite/Mage/Core/_files/media_for_change.php
index ec8e60fa7cc..a658ac04edd 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Model/LayoutTestBase.php
+++ b/dev/tests/integration/testsuite/Mage/Core/_files/media_for_change.php
@@ -25,35 +25,23 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-/**
- * Layout integration tests
- */
-class Mage_Core_Model_LayoutTestBase extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var Mage_Core_Model_Layout
-     */
-    protected $_layout;
-
-    protected function setUp()
-    {
-        /** @var $themeUtility Mage_Core_Utility_Theme */
-        $themeUtility = Mage::getModel('Mage_Core_Utility_Theme', array(
-            dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'design',
-            Mage::getDesign()
-        ));
-        $themeUtility->registerThemes()->setDesignTheme('test/default', 'frontend');
+$designDir = Magento_Test_Bootstrap::getInstance()->getInstallDir() . '/media_for_change';
+$themeDir = $designDir . DIRECTORY_SEPARATOR . '/frontend/test/default';
+$sourcePath = dirname(__DIR__) . '/Model/_files/design/frontend/test/publication/';
 
-        /* Disable loading and saving layout cache */
-        Mage::app()->getCacheInstance()->banUse('layout');
+mkdir($themeDir . '/images', 0777, true);
 
-        $this->_layout = Mage::getModel('Mage_Core_Model_Layout');
-        $this->_layout->getUpdate()->addHandle('layout_test_handle_main');
-        $this->_layout->getUpdate()->load('layout_test_handle_extra');
-    }
-
-    protected function tearDown()
-    {
-        $this->_layout = null;
-    }
+// Copy all files to fixture location
+$mTime = time() - 10; // To ensure that all files, changed later in test, will be recognized for publication
+$files = array('theme.xml', 'style.css', 'sub.css', 'images/square.gif', 'images/rectangle.gif');
+foreach ($files as $file) {
+    copy($sourcePath . $file, $themeDir . DIRECTORY_SEPARATOR . $file);
+    touch($themeDir . DIRECTORY_SEPARATOR . $file, $mTime);
 }
+
+/** @var $registration Mage_Core_Model_Theme_Registration */
+$registration = Mage::getModel('Mage_Core_Model_Theme_Registration');
+$registration->register(
+    $designDir,
+    implode(DIRECTORY_SEPARATOR, array('*', '*', '*', 'theme.xml'))
+);
diff --git a/dev/tests/integration/testsuite/Mage/Core/_files/media_for_change_rollback.php b/dev/tests/integration/testsuite/Mage/Core/_files/media_for_change_rollback.php
new file mode 100644
index 00000000000..ba8bf37418a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Core/_files/media_for_change_rollback.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Core
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+$designDir = Magento_Test_Bootstrap::getInstance()->getInstallDir() . '/media_for_change';
+Varien_Io_File::rmdirRecursive($designDir);
diff --git a/dev/tests/integration/testsuite/Mage/Customer/Model/Address/ApiTest.php b/dev/tests/integration/testsuite/Mage/Customer/Model/Address/ApiTest.php
new file mode 100644
index 00000000000..1531f1a021d
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Customer/Model/Address/ApiTest.php
@@ -0,0 +1,232 @@
+<?php
+/**
+ * Test class for Mage_Customer_Model_Address_Api.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Customer/_files/customer.php
+ * @magentoDataFixture Mage/Customer/_files/customer_two_addresses.php
+ */
+class Mage_Customer_Model_Address_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test for customer address list
+     */
+    public function testCustomerAddressList()
+    {
+        // Get the customer's addresses
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'customerAddressList',
+            array(
+                'customerId' => 1
+            )
+        );
+
+        $this->assertNotEmpty($soapResult, 'Error during customer address list via API call');
+        $this->assertCount(2, $soapResult, 'Result did not contain 2 addresses');
+
+        /** @var $firstAddress Mage_Customer_Model_Address */
+        $firstAddress = Mage::getModel('Mage_Customer_Model_Address');
+        $firstAddress->load(1);
+        $this->_verifyAddress($firstAddress->getData(), $soapResult[0]);
+
+        /** @var $secondAddress Mage_Customer_Model_Address */
+        $secondAddress = Mage::getModel('Mage_Customer_Model_Address');
+        $secondAddress->load(2);
+        $this->_verifyAddress($secondAddress->getData(), $soapResult[1]);
+    }
+
+    /**
+     * Test for customer address info
+     */
+    public function testCustomerAddressInfo()
+    {
+        /** @var $customerAddress Mage_Customer_Model_Address */
+        $customerAddress = Mage::getModel('Mage_Customer_Model_Address');
+        $customerAddress->load(1);
+
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'customerAddressInfo',
+            array(
+                'addressId' => $customerAddress->getId()
+            )
+        );
+
+        $this->assertNotEmpty($soapResult, 'Error during customer address info via API call');
+        $this->_verifyAddress($customerAddress->getData(), $soapResult);
+    }
+
+    /**
+     * Test customer address create
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testCustomerAddressCreate()
+    {
+        $customerId = 1;
+
+        // New address to create
+        $newAddressData = array(
+            'city' => 'Kyle',
+            'company' => 'HBM',
+            'country_id' => 'US',
+            'fax' => '5125551234',
+            'firstname' => 'Sherry',
+            'lastname' => 'Berry',
+            'middlename' => 'Kari',
+            'postcode' => '77777',
+            'prefix' => 'Ms',
+            'region_id' => 35,
+            'region' => 'Mississippi',
+            'street' => array('123 FM 101'),
+            'suffix' => 'M',
+            'telephone' => '5',
+            'is_default_billing' => false,
+            'is_default_shipping' => false
+        );
+
+        // Call api to create the address
+        $newAddressId = Magento_Test_Helper_Api::call(
+            $this,
+            'customerAddressCreate',
+            array(
+                'customerId' => $customerId,
+                'addressData' => (object)$newAddressData
+            )
+        );
+
+        // Verify the new address was added
+        /** @var $newAddressModel Mage_Customer_Model_Address */
+        $newAddressModel = Mage::getModel('Mage_Customer_Model_Address');
+        $newAddressModel->load($newAddressId);
+
+        // Verify all field values were correctly set
+        $newAddressData['street'] = trim(implode("\n", $newAddressData['street']));
+        $newAddressData['customer_address_id'] = $newAddressId;
+        $this->_verifyAddress($newAddressData, $newAddressModel->getData());
+    }
+
+    /**
+     * Test customer address delete
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testCustomerAddressDelete()
+    {
+        $addressId = 1;
+
+        // Delete address
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'customerAddressDelete',
+            array(
+                'addressId' => $addressId
+            )
+        );
+        $this->assertTrue($soapResult, 'Error during customer address delete via API call');
+
+        /** @var Mage_Customer_Model_Address $address */
+        $address = Mage::getModel('Mage_Customer_Model_Address')->load($addressId);
+        $this->assertNull($address->getEntityId());
+    }
+
+    /**
+     * Test customer address update
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testCustomerAddressUpdate()
+    {
+        $addressId = 1;
+        $newFirstname = 'Eric';
+        $newTelephone = '888-555-8888';
+
+        // Data to set in existing address
+        $updateData = (object)array(
+            'firstname' => $newFirstname,
+            'telephone' => $newTelephone
+        );
+
+        // update a customer's address
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'customerAddressUpdate',
+            array(
+                'addressId' => $addressId,
+                'addressData' => $updateData
+            )
+        );
+
+        $this->assertTrue($soapResult, 'Error during customer address update via API call');
+
+        // Verify all field values were correctly set
+        /** @var $customerAddress Mage_Customer_Model_Address */
+        $customerAddress = Mage::getModel('Mage_Customer_Model_Address');
+        $customerAddress->load($addressId);
+
+        $this->assertEquals(
+            $newFirstname,
+            $customerAddress->getFirstname(),
+            'First name is not updated.'
+        );
+        $this->assertEquals(
+            $newTelephone,
+            $customerAddress->getTelephone(),
+            'Telephone is not updated.'
+        );
+    }
+
+    /**
+     * Verify fields in an address array
+     *
+     * Compares two arrays containing address data.  Throws assertion error if
+     * data does not match.
+     *
+     * @param array $expectedData Expected values of address array
+     * @param array $actualData Values that are to be tested
+     */
+    protected function _verifyAddress($expectedData, $actualData)
+    {
+        $fieldsToCompare = array(
+            'entity_id' => 'customer_address_id',
+            'city',
+            'country_id',
+            'fax',
+            'firstname',
+            'lastname',
+            'middlename',
+            'postcode',
+            'region',
+            'region_id',
+            'street',
+            'telephone'
+        );
+
+        Magento_Test_Helper_Api::checkEntityFields(
+            $this,
+            $expectedData,
+            $actualData,
+            $fieldsToCompare
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Customer/Model/Customer/ApiTest.php b/dev/tests/integration/testsuite/Mage/Customer/Model/Customer/ApiTest.php
new file mode 100644
index 00000000000..b07e4f8c085
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Customer/Model/Customer/ApiTest.php
@@ -0,0 +1,166 @@
+<?php
+/**
+ * Test for customer API.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Customer_Model_Customer_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test create method.
+     *
+     * @magentoDbIsolation enabled
+     */
+    public function testCreate()
+    {
+        $customerEmail = uniqid() . '@example.org';
+        $customerData = (object)array(
+            'email' => $customerEmail,
+            'firstname' => 'Firstname',
+            'lastname' => 'Lastname',
+            'password' => 'password',
+            'website_id' => 0,
+            'group_id' => 1
+        );
+        /** Create new customer. */
+        $customerId = Magento_Test_Helper_Api::call(
+            $this,
+            'customerCustomerCreate',
+            array('customerData' => $customerData)
+        );
+        /** Load created customer. */
+        /** @var Mage_Customer_Model_Customer $customer */
+        $customer = Mage::getModel('Mage_Customer_Model_Customer');
+        $customer->load($customerId);
+        /** Assert main customers fields are set. */
+        $this->assertEquals($customerEmail, $customer->getEmail(), 'Customer email is not set.');
+        $this->assertEquals('Firstname', $customer->getFirstname(), 'Customer first name is not set.');
+        $this->assertEquals('Lastname', $customer->getLastname(), 'Customer last name is not set.');
+    }
+
+    /**
+     * Test info method.
+     *
+     * @magentoDataFixture Mage/Customer/_files/customer.php
+     */
+    public function testInfo()
+    {
+        $customerId = 1;
+        /** Retrieve customer data. */
+        $customerData = Magento_Test_Helper_Api::call(
+            $this,
+            'customerCustomerInfo',
+            array($customerId)
+        );
+        /** Assert customer email is set. */
+        $this->assertEquals('customer@example.com', $customerData['email'], 'Customer email is invalid.');
+        /** Assert response contains base fields. */
+        $expectedFields = array('customer_id', 'email', 'firstname', 'lastname', 'password_hash');
+        $missingFields = array_diff_key($expectedFields, array_keys($customerData));
+        $this->assertEmpty(
+            $missingFields,
+            sprintf("The following fields must be present in response: %s.", implode(', ', $missingFields))
+        );
+    }
+
+    /**
+     * Test list method.
+     *
+     * @magentoDataFixture Mage/Customer/_files/two_customers.php
+     */
+    public function testList()
+    {
+        /** Retrieve the list of customers. */
+        $customersList = Magento_Test_Helper_Api::call(
+            $this,
+            'customerCustomerList',
+            array()
+        );
+        /** Assert returned customers quantity. */
+        $this->assertCount(2, $customersList, 'Returned customers quantity are wrong.');
+        /** Assert response contains base fields. */
+        $expectedFields = array('customer_id', 'email', 'firstname', 'lastname', 'password_hash');
+        $customerData = reset($customersList);
+        $missingFields = array_diff_key($expectedFields, array_keys($customerData));
+        $this->assertEmpty(
+            $missingFields,
+            sprintf("The following fields must be present in response: %s.", implode(', ', $missingFields))
+        );
+    }
+
+    /**
+     * Test update method.
+     *
+     * @magentoDataFixture Mage/Customer/_files/customer.php
+     */
+    public function testUpdate()
+    {
+        $customerId = 1;
+        $updateCustomerData = (object)array(
+            'firstname' => 'new_firstname',
+            'email' => 'new_email@example.org'
+        );
+        /** Update customer. */
+        $updateResult = Magento_Test_Helper_Api::call(
+            $this,
+            'customerCustomerUpdate',
+            array('customerId' => $customerId, 'customerData' => $updateCustomerData)
+        );
+        /** Assert API update operation result. */
+        $this->assertTrue($updateResult, 'Customer update is failed.');
+        /** Assert fields are updated. */
+        /** @var Mage_Customer_Model_Customer $customer */
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')->load($customerId);
+        $this->assertEquals(
+            'new_firstname',
+            $customer->getFirstname(),
+            'First name is not updated.'
+        );
+        $this->assertEquals(
+            'new_email@example.org',
+            $customer->getEmail(),
+            'Email is not updated.'
+        );
+    }
+
+    /**
+     * Test delete method.
+     *
+     * @magentoDataFixture Mage/Customer/_files/customer.php
+     */
+    public function testDelete()
+    {
+        $customerId = 1;
+        /** Delete customer. */
+        $deleteResult = Magento_Test_Helper_Api::call(
+            $this,
+            'customerCustomerDelete',
+            array('customerId' => $customerId)
+        );
+        /** Assert delete operation result. */
+        $this->assertTrue($deleteResult, 'Customer is not deleted.');
+        /** Assert customer is deleted. */
+        /** @var Mage_Customer_Model_Customer $customer */
+        $customer = Mage::getModel('Mage_Customer_Model_Customer')->load($customerId);
+        $this->assertNull($customer->getEntityId());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Customer/Model/Group/ApiTest.php b/dev/tests/integration/testsuite/Mage/Customer/Model/Group/ApiTest.php
new file mode 100644
index 00000000000..1c89ba13d65
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Customer/Model/Group/ApiTest.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Test customer group Api.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Customer_Model_Group_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test item method.
+     */
+    public function testList()
+    {
+        /** Retrieve the list of customer groups. */
+        $groupsList = Magento_Test_Helper_Api::call($this, 'customerGroupList', array());
+        /** Assert customers group list is not empty. */
+        $this->assertNotEmpty($groupsList, 'Customers list retrieving was unsuccessful.');
+        /** Assert base fields are present in the response. */
+        $groupInfo = reset($groupsList);
+        $expectedFields = array('customer_group_id', 'customer_group_code');
+        $missingFields = array_diff($expectedFields, array_keys($groupInfo));
+        $this->assertEmpty(
+            $missingFields,
+            sprintf("The following fields must be present in response: %s.", implode(', ', $missingFields))
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Customer/_files/customer_address.php b/dev/tests/integration/testsuite/Mage/Customer/_files/customer_address.php
index 0202e67f88a..f48cb6ec0e9 100644
--- a/dev/tests/integration/testsuite/Mage/Customer/_files/customer_address.php
+++ b/dev/tests/integration/testsuite/Mage/Customer/_files/customer_address.php
@@ -26,6 +26,7 @@
 
 /** @var Mage_Customer_Model_Address $customerAddress */
 $customerAddress = Mage::getModel('Mage_Customer_Model_Address');
+$customerAddress->isObjectNew(true);
 $customerAddress->setCustomerId(1)
     ->setData(array(
         'entity_id' => 1,
@@ -36,7 +37,6 @@ $customerAddress->setCustomerId(1)
         'street' => 'Green str, 67',
         'lastname' => 'Smith',
         'firstname' => 'John',
-        'parent_id' => 1,
-        'created_at' => date('YYY-MM-DD hh:mm:ss')
+        'parent_id' => 1
     ));
 $customerAddress->save();
diff --git a/dev/tests/integration/testsuite/Mage/Customer/_files/customer_two_addresses.php b/dev/tests/integration/testsuite/Mage/Customer/_files/customer_two_addresses.php
index e25d22008ea..f442029147d 100644
--- a/dev/tests/integration/testsuite/Mage/Customer/_files/customer_two_addresses.php
+++ b/dev/tests/integration/testsuite/Mage/Customer/_files/customer_two_addresses.php
@@ -28,6 +28,7 @@ require 'customer_address.php';
 
 /** @var Mage_Customer_Model_Address $customerAddress */
 $customerAddress = Mage::getModel('Mage_Customer_Model_Address');
+$customerAddress->isObjectNew(true);
 $customerAddress->setCustomerId(1)
     ->setData(array(
         'entity_id' => 2,
@@ -38,7 +39,6 @@ $customerAddress->setCustomerId(1)
         'street' => 'Black str, 48',
         'lastname' => 'Smith',
         'firstname' => 'John',
-        'parent_id' => 1,
-        'created_at' => date('YYY-MM-DD hh:mm:ss')
+        'parent_id' => 1
     ));
 $customerAddress->save();
diff --git a/dev/tests/integration/testsuite/Mage/Customer/_files/two_customers.php b/dev/tests/integration/testsuite/Mage/Customer/_files/two_customers.php
new file mode 100644
index 00000000000..85194571644
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Customer/_files/two_customers.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Fixture for Customer List method.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+require 'customer.php';
+
+$customer = Mage::getModel('Mage_Customer_Model_Customer');
+$customer
+    ->setWebsiteId(1)
+    ->setEntityId(2)
+    ->setEntityTypeId(1)
+    ->setAttributeSetId(0)
+    ->setEmail('customer_two@example.com')
+    ->setPassword('password')
+    ->setGroupId(1)
+    ->setStoreId(1)
+    ->setIsActive(1)
+    ->setFirstname('Firstname')
+    ->setLastname('Lastname')
+    ->setDefaultBilling(1)
+    ->setDefaultShipping(1);
+$customer->isObjectNew(true);
+$customer->save();
diff --git a/dev/tests/integration/testsuite/Mage/Directory/Model/Country/ApiTest.php b/dev/tests/integration/testsuite/Mage/Directory/Model/Country/ApiTest.php
new file mode 100644
index 00000000000..89f8dcef17a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Directory/Model/Country/ApiTest.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Directory country API test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Directory_Model_Country_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test 'items' method of directory country API.
+     */
+    public function testList()
+    {
+        $countries = Magento_Test_Helper_Api::call($this, 'directoryCountryList');
+        $this->assertGreaterThan(200, count($countries), "The list of countries seems to be not full.");
+        $countryData = reset($countries);
+        $expectedFields = array('country_id', 'iso2_code', 'iso3_code', 'name');
+        $missingFields = array_diff($expectedFields, array_keys($countryData));
+        $this->assertEmpty(
+            $missingFields,
+            sprintf("The following fields must be present in country data: %s.", implode(', ', $missingFields))
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Directory/Model/Region/ApiTest.php b/dev/tests/integration/testsuite/Mage/Directory/Model/Region/ApiTest.php
new file mode 100644
index 00000000000..906da30f39d
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Directory/Model/Region/ApiTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/**
+ * Test Directory Region operations
+ */
+class Mage_Directory_Model_Region_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test directoryRegionList API method
+     */
+    public function testList()
+    {
+        $data = Magento_Test_Helper_Api::call($this, 'directoryRegionList', array('country' => 'US'));
+        $this->assertTrue(is_array($data), 'Region list is not array');
+        $this->assertNotEmpty($data, 'Region list is empty');
+        $region = reset($data);
+        $this->assertTrue(
+            is_string($region['name']) && strlen($region['name']),
+            'Region name is empty or not a string'
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractTest.php
index 17bb6ebd4da..477d27ce120 100644
--- a/dev/tests/integration/testsuite/Mage/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Eav/Block/Adminhtml/Attribute/Edit/Main/AbstractTest.php
@@ -54,6 +54,8 @@ class Mage_Eav_Block_Adminhtml_Attribute_Edit_Main_AbstractTest
             Mage::getObjectManager()->get('Mage_Core_Model_Store_Config'),
             Mage::getObjectManager()->get('Mage_Core_Controller_Varien_Front'),
             Mage::getObjectManager()->get('Mage_Core_Model_Factory_Helper'),
+            Mage::getObjectManager()->get('Mage_Core_Model_Dir'),
+            Mage::getObjectManager()->get('Mage_Core_Model_Logger'),
             Mage::getObjectManager()->get('Magento_Filesystem'),
         );
         $block = $this->getMockForAbstractClass('Mage_Eav_Block_Adminhtml_Attribute_Edit_Main_Abstract', $arguments)
diff --git a/dev/tests/integration/testsuite/Mage/GiftMessage/Model/ApiTest.php b/dev/tests/integration/testsuite/Mage/GiftMessage/Model/ApiTest.php
new file mode 100644
index 00000000000..24de10e28ae
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/GiftMessage/Model/ApiTest.php
@@ -0,0 +1,167 @@
+<?php
+/**
+ * Test case for gift message assigning to the shopping cart via API.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_GiftMessage_Model_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test setting gift message fot the whole shopping cart.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     */
+    public function testSetForQuote()
+    {
+        /** Prepare data. */
+        $quoteId = $this->_getQuote()->getId();
+
+        /** Call tested method. */
+        $status = Magento_Test_Helper_Api::call(
+            $this,
+            'giftMessageSetForQuote',
+            array($quoteId, $this->_getGiftMessageData())
+        );
+        $expectedStatus = array('entityId' => $quoteId, 'result' => true, 'error' => '');
+        $this->assertEquals($expectedStatus, (array)$status, 'Gift message was not added to the quote.');
+
+        /** Ensure that messages were actually added and saved to DB. */
+        /** @var Mage_Sales_Model_Quote $updatedQuote */
+        $updatedQuote = Mage::getModel('Mage_Sales_Model_Quote')->load($quoteId);
+        $this->assertGreaterThan(0, (int)$updatedQuote->getGiftMessageId(), "Gift message was not added.");
+        $this->_checkCreatedGiftMessage($updatedQuote->getGiftMessageId(), $this->_getGiftMessageData());
+    }
+
+    /**
+     * Test setting gift message fot the specific quote item.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     */
+    public function testSetForQuoteItem()
+    {
+        /** Prepare data. */
+        $quoteItems = $this->_getQuote()->getAllItems();
+        /** @var Mage_Sales_Model_Quote_Item $quoteItem */
+        $quoteItem = reset($quoteItems);
+
+        /** Call tested method. */
+        $status = Magento_Test_Helper_Api::call(
+            $this,
+            'giftMessageSetForQuoteItem',
+            array($quoteItem->getId(), $this->_getGiftMessageData())
+        );
+        $expectedStatus = array('entityId' => $quoteItem->getId(), 'result' => true, 'error' => '');
+        $this->assertEquals($expectedStatus, (array)$status, 'Gift message was not added to the quote.');
+
+        /** Ensure that messages were actually added and saved to DB. */
+        /** @var Mage_Sales_Model_Quote_Item $updatedQuoteItem */
+        $updatedQuoteItem = Mage::getModel('Mage_Sales_Model_Quote_Item')->load($quoteItem->getId());
+        $this->assertGreaterThan(0, (int)$updatedQuoteItem->getGiftMessageId(), "Gift message was not added.");
+        $this->_checkCreatedGiftMessage($updatedQuoteItem->getGiftMessageId(), $this->_getGiftMessageData());
+
+    }
+
+    /**
+     * Test setting gift message fot the specified products in shopping cart.
+     *
+     * @magentoDataFixture Mage/Checkout/_files/quote_with_simple_product.php
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     */
+    public function testSetForQuoteProduct()
+    {
+        /** Prepare data. */
+        $quoteItems = $this->_getQuote()->getAllItems();
+        /** @var Mage_Sales_Model_Quote_Item $quoteItem */
+        $quoteItem = reset($quoteItems);
+
+        /** Call tested method. */
+        $status = Magento_Test_Helper_Api::call(
+            $this,
+            'giftMessageSetForQuoteProduct',
+            array(
+                $this->_getQuote()->getId(),
+                array(
+                    (object)array(
+                        'product' => (object)array('product_id' => $quoteItem->getProductId()),
+                        'message' => $this->_getGiftMessageData()
+                    )
+                )
+            )
+        );
+        $expectedStatus = array((object)array('entityId' => $quoteItem->getId(), 'result' => true, 'error' => ''));
+        $this->assertEquals($expectedStatus, $status, 'Gift message was not added to the quote.');
+
+        /** Ensure that messages were actually added and saved to DB. */
+        /** @var Mage_Sales_Model_Quote_Item $updatedQuoteItem */
+        $updatedQuoteItem = Mage::getModel('Mage_Sales_Model_Quote_Item')->load($quoteItem->getId());
+        $this->assertGreaterThan(0, (int)$updatedQuoteItem->getGiftMessageId(), "Gift message was not added.");
+        $this->_checkCreatedGiftMessage($updatedQuoteItem->getGiftMessageId(), $this->_getGiftMessageData());
+    }
+
+    /**
+     * Prepare gift message data for tests.
+     *
+     * @return object
+     */
+    protected function _getGiftMessageData()
+    {
+        $giftMessageData = (object)array(
+            'from' => 'from@null.null',
+            'to' => 'to@null.null',
+            'message' => 'Gift message content.'
+        );
+        return $giftMessageData;
+    }
+
+    /**
+     * Ensure that added gift message was successfully stored in DB.
+     *
+     * @param int $giftMessageId
+     * @param object $giftMessageData
+     */
+    protected function _checkCreatedGiftMessage($giftMessageId, $giftMessageData)
+    {
+        $giftMessage = Mage::getModel('Mage_GiftMessage_Model_Message')->load($giftMessageId);
+        $this->assertEquals($giftMessageData->message, $giftMessage['message'], 'Message stored in DB is invalid.');
+        $this->assertEquals($giftMessageData->to, $giftMessage['recipient'], 'Recipient stored in DB is invalid.');
+        $this->assertEquals($giftMessageData->from, $giftMessage['sender'], 'Sender stored in DB is invalid.');
+    }
+
+    /**
+     * Retrieve quote created in fixture.
+     *
+     * @return Mage_Sales_Model_Quote
+     */
+    protected function _getQuote()
+    {
+        /** @var $session Mage_Checkout_Model_Session */
+        $session = Mage::getModel('Mage_Checkout_Model_Session');
+        /** @var Mage_Sales_Model_Quote $quote */
+        $quote = $session->getQuote();
+        return $quote;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/ProductTest.php b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/ProductTest.php
index 90f3cd1da10..ab1f0ee49fe 100644
--- a/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/ProductTest.php
+++ b/dev/tests/integration/testsuite/Mage/ImportExport/Model/Export/Entity/ProductTest.php
@@ -154,7 +154,6 @@ class Mage_ImportExport_Model_Export_Entity_ProductTest extends PHPUnit_Framewor
      * Verify header columns (that stock item attributes column headers are present)
      *
      * @param array $headerColumns
-     * @return void
      */
     public function verifyHeaderColumns(array $headerColumns)
     {
@@ -169,7 +168,6 @@ class Mage_ImportExport_Model_Export_Entity_ProductTest extends PHPUnit_Framewor
      * Verify row data (stock item attribute values)
      *
      * @param array $rowData
-     * @return void
      */
     public function verifyRow(array $rowData)
     {
diff --git a/dev/tests/integration/testsuite/Mage/Index/Model/Process/FileTest.php b/dev/tests/integration/testsuite/Mage/Index/Model/Process/FileTest.php
index 3c993f0710d..e786cfb1139 100644
--- a/dev/tests/integration/testsuite/Mage/Index/Model/Process/FileTest.php
+++ b/dev/tests/integration/testsuite/Mage/Index/Model/Process/FileTest.php
@@ -59,9 +59,9 @@ class Mage_Index_Model_Process_FileTest extends PHPUnit_Framework_TestCase
     {
         $this->_objectManager   = Mage::getObjectManager();
         $this->_model           = $this->_objectManager->create('Mage_Index_Model_Process_File');
-        /** @var $configuration Mage_Core_Model_Config */
-        $configuration          = $this->_objectManager->get('Mage_Core_Model_Config');
-        $this->_fileDirectory   = $configuration->getVarDir('locks');
+        /** @var $dir Mage_Core_Model_Dir */
+        $dir = $this->_objectManager->get('Mage_Core_Model_Dir');
+        $this->_fileDirectory   = $dir->getDir(Mage_Core_Model_Dir::VAR_DIR) . DIRECTORY_SEPARATOR . 'locks';
         $fullFileName           = $this->_fileDirectory . DIRECTORY_SEPARATOR . self::FILE_NAME;
         $this->_testFileHandler = fopen($fullFileName, 'w');
     }
diff --git a/dev/tests/integration/testsuite/Mage/Install/IndexControllerTest.php b/dev/tests/integration/testsuite/Mage/Install/IndexControllerTest.php
new file mode 100644
index 00000000000..f731b954c24
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Install/IndexControllerTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Install_IndexControllerTest extends Magento_Test_TestCase_ControllerAbstract
+{
+    public function testIndexAction()
+    {
+        $this->dispatch('install/index/index');
+        $request = $this->getRequest();
+        $this->assertEquals('begin', $request->getActionName());
+        $this->assertEquals('wizard', $request->getControllerName());
+        $this->assertEquals('install', $request->getModuleName());
+        /**
+         * Make sure that preDispatch() didn't cleanup var directory (by asserting presence of anything there),
+         * because in integration testing environment the application is considered "installed"
+         */
+        $this->assertFileExists(Mage::getBaseDir(Mage_Core_Model_Dir::TMP));
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Install/Model/Installer/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Install/Model/Installer/ConfigTest.php
new file mode 100644
index 00000000000..fe5a40f947f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Install/Model/Installer/ConfigTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Install_Model_Installer_ConfigTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @var string
+     */
+    protected static $_tmpDir = '';
+
+    public static function setUpBeforeClass()
+    {
+        self::$_tmpDir = Mage::getBaseDir(Mage_Core_Model_Dir::VAR_DIR) . DIRECTORY_SEPARATOR . __CLASS__;
+        mkdir(self::$_tmpDir);
+    }
+
+    public static function tearDownAfterClass()
+    {
+        Varien_Io_File::rmdirRecursive(self::$_tmpDir);
+    }
+
+    public function testInstall()
+    {
+        file_put_contents(self::$_tmpDir . '/local.xml.template', "test; {{date}}; {{base_url}}; {{unknown}}");
+        $expectedFile = self::$_tmpDir . '/local.xml';
+
+        $config = $this->getMock('Mage_Core_Model_Config', array('getDistroBaseUrl'), array(), '', false);
+        $config->expects($this->once())->method('getDistroBaseUrl')->will($this->returnValue('http://example.com/'));
+        $expectedContents = "test; <![CDATA[d-d-d-d-d]]>; <![CDATA[http://example.com/]]>; {{unknown}}";
+        $dirs = new Mage_Core_Model_Dir(self::$_tmpDir, array(), array(Mage_Core_Model_Dir::CONFIG => self::$_tmpDir));
+
+        $this->assertFileNotExists($expectedFile);
+        $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
+        $model = new Mage_Install_Model_Installer_Config($config, $dirs, $filesystem);
+        $model->install();
+        $this->assertFileExists($expectedFile);
+        $this->assertStringEqualsFile($expectedFile, $expectedContents);
+    }
+
+    public function testGetFormData()
+    {
+        /** @var $model Mage_Install_Model_Installer_Config */
+        $model = Mage::getModel('Mage_Install_Model_Installer_Config');
+        /** @var $result Varien_Object */
+        $result = $model->getFormData();
+        $this->assertInstanceOf('Varien_Object', $result);
+        $data = $result->getData();
+        $this->assertArrayHasKey('db_host', $data);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Install/controllers/WizardControllerTest.php b/dev/tests/integration/testsuite/Mage/Install/controllers/WizardControllerTest.php
index aaae218c7ed..bc7771d6842 100644
--- a/dev/tests/integration/testsuite/Mage/Install/controllers/WizardControllerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Install/controllers/WizardControllerTest.php
@@ -30,59 +30,53 @@ class Mage_Install_WizardControllerTest extends Magento_Test_TestCase_Controller
     /**
      * @var string
      */
-    protected static $_tmpMediaDir;
+    protected static $_mediaDir;
 
     /**
      * @var string
      */
-    protected static $_tmpThemeDir;
+    protected static $_themeDir;
 
     public static function setUpBeforeClass()
     {
         parent::setUpBeforeClass();
-        self::$_tmpMediaDir = realpath(Magento_Test_Bootstrap::getInstance()->getTmpDir())
-            . DIRECTORY_SEPARATOR . 'media';
-        self::$_tmpThemeDir = self::$_tmpMediaDir . DIRECTORY_SEPARATOR . 'theme';
+        self::$_mediaDir = Mage::getBaseDir(Mage_Core_Model_Dir::MEDIA);
+        self::$_themeDir = self::$_mediaDir . DIRECTORY_SEPARATOR . 'theme';
     }
 
     public function setUp()
     {
         parent::setUp();
         // emulate non-installed application
-        $this->_runOptions[Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_DATA]
+        $this->_runOptions[Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA]
             = sprintf(Mage_Core_Model_Config::CONFIG_TEMPLATE_INSTALL_DATE, 'invalid');
     }
 
     public function tearDown()
     {
-        Varien_Io_File::rmdirRecursive(self::$_tmpMediaDir);
+        if (is_dir(self::$_mediaDir)) {
+            chmod(self::$_mediaDir, 0777);
+        }
+        if (is_dir(self::$_themeDir)) {
+            chmod(self::$_themeDir, 0777);
+        }
         parent::tearDown();
     }
 
-    /**
-     * @magentoAppIsolation enabled
-     */
     public function testPreDispatch()
     {
-        $this->dispatch('install/index');
+        $this->dispatch('install/wizard');
         $this->assertEquals(200, $this->getResponse()->getHttpResponseCode());
     }
 
     public function testPreDispatchNonWritableMedia()
     {
-        mkdir(self::$_tmpMediaDir, 0444);
-        $this->_runOptions['media_dir'] = self::$_tmpMediaDir;
-
-        $this->_testInstallProhibitedWhenNonWritable(self::$_tmpMediaDir);
+        $this->_testInstallProhibitedWhenNonWritable(self::$_mediaDir);
     }
 
     public function testPreDispatchNonWritableTheme()
     {
-        mkdir(self::$_tmpMediaDir, 0777);
-        $this->_runOptions['media_dir'] = self::$_tmpMediaDir;
-
-        mkdir(self::$_tmpThemeDir, 0444);
-        $this->_testInstallProhibitedWhenNonWritable(self::$_tmpThemeDir);
+        $this->_testInstallProhibitedWhenNonWritable(self::$_themeDir);
     }
 
     /**
@@ -93,13 +87,23 @@ class Mage_Install_WizardControllerTest extends Magento_Test_TestCase_Controller
      */
     protected function _testInstallProhibitedWhenNonWritable($nonWritableDir)
     {
+        if (file_exists($nonWritableDir) && !is_dir($nonWritableDir)) {
+            $this->markTestSkipped("Incorrect file structure. $nonWritableDir should be a directory");
+        }
+
+        if (is_dir($nonWritableDir)) {
+            chmod($nonWritableDir, 0444);
+        } else {
+            mkdir($nonWritableDir, 0444);
+        }
+
         if (is_writable($nonWritableDir)) {
             $this->markTestSkipped("Current OS doesn't support setting write-access for folders via mode flags");
         }
 
-        $this->dispatch('install/index');
+        $this->dispatch('install/wizard');
 
         $this->assertEquals(503, $this->getResponse()->getHttpResponseCode());
-        $this->assertContains(self::$_tmpThemeDir, $this->getResponse()->getBody());
+        $this->assertContains(self::$_themeDir, $this->getResponse()->getBody());
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Newsletter/Model/QueueTest.php b/dev/tests/integration/testsuite/Mage/Newsletter/Model/QueueTest.php
index 8fb652ca4c2..6cbb315ac0e 100644
--- a/dev/tests/integration/testsuite/Mage/Newsletter/Model/QueueTest.php
+++ b/dev/tests/integration/testsuite/Mage/Newsletter/Model/QueueTest.php
@@ -29,13 +29,16 @@ class Mage_Newsletter_Model_QueueTest extends PHPUnit_Framework_TestCase
 {
     /**
      * @magentoDataFixture Mage/Newsletter/_files/queue.php
-     * @magentoConfigFixture current_store design/theme/full_name default/demo_blue
-     * @magentoConfigFixture fixturestore_store design/theme/full_name default/demo
+     * @magentoConfigFixture frontend/design/theme/full_name default/demo_blue
      * @magentoConfigFixture fixturestore_store general/locale/code  de_DE
      * @magentoAppIsolation enabled
      */
     public function testSendPerSubscriber()
     {
+        $collection = new Mage_Core_Model_Resource_Theme_Collection;
+        $themeId = $collection->getThemeByFullPath('frontend/default/demo')->getId();
+        Mage::app()->getStore('fixturestore')->setConfig('design/theme/theme_id', $themeId);
+
         $subscriberOne = $this->getMock('Zend_Mail', array('send', 'setBodyHTML'), array('utf-8'));
         $subscriberOne->expects($this->any())->method('send');
         $subscriberTwo = clone $subscriberOne;
diff --git a/dev/tests/integration/testsuite/Mage/Page/Block/HtmlTest.php b/dev/tests/integration/testsuite/Mage/Page/Block/HtmlTest.php
new file mode 100644
index 00000000000..7eda712c0f0
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Page/Block/HtmlTest.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Page
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Page_Block_HtmlTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     *
+     * @dataProvider getConfigValuesDataProvider
+     */
+    public function testGetPrintLogoUrl($configData, $returnValue)
+    {
+        $storeConfig = $this->getMock('Mage_Core_Model_Store_Config');
+        $storeConfig->expects($this->any())
+            ->method('getConfig')
+            ->will($this->returnValueMap($configData));
+
+        $urlBuilder = $this->getMock('Mage_Core_Model_Url', array('getBaseUrl'));
+        $urlBuilder->expects($this->any())
+            ->method('getBaseUrl')
+            ->will($this->returnValue('http://localhost/pub/media/'));
+
+        $arguments = array(
+            'storeConfig' => $storeConfig,
+            'urlBuilder' => $urlBuilder,
+        );
+
+        $block = Mage::getObjectManager()->create('Mage_Page_Block_Html', $arguments);
+
+        $this->assertEquals($returnValue, $block->getPrintLogoUrl());
+    }
+
+    public function getConfigValuesDataProvider()
+    {
+        return array(
+            'sales_identity_logo_html' => array(
+                array(array('sales/identity/logo_html', null, 'image.gif')),
+                'http://localhost/pub/media/sales/store/logo_html/image.gif'
+            ),
+            'sales_identity_logo' => array(
+                array(array('sales/identity/logo', null, 'image.gif')),
+                'http://localhost/pub/media/sales/store/logo/image.gif'
+            ),
+            'sales_identity_logoTif' => array(
+                array(array('sales/identity/logo', null, 'image.tif')),
+                ''
+            ),
+            'sales_identity_logoTiff' => array(
+                array(array('sales/identity/logo', null, 'image.tiff')),
+                ''
+            ),
+            'no_logo' => array(
+                array(),
+                ''
+            ),
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Paypal/Adminhtml/Paypal/ReportsControllerTest.php b/dev/tests/integration/testsuite/Mage/Paypal/Adminhtml/Paypal/ReportsControllerTest.php
new file mode 100644
index 00000000000..d2729f76afd
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Paypal/Adminhtml/Paypal/ReportsControllerTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Paypal_Adminhtml_Paypal_ReportsControllerTest extends Mage_Backend_Utility_Controller
+{
+    /**
+     * @magentoConfigFixture current_store paypal/fetch_reports/active 1
+     * @magentoConfigFixture current_store paypal/fetch_reports/ftp_ip 127.0.0.1
+     * @magentoConfigFixture current_store paypal/fetch_reports/ftp_path /tmp
+     * @magentoConfigFixture current_store paypal/fetch_reports/ftp_login login
+     * @magentoConfigFixture current_store paypal/fetch_reports/ftp_password password
+     * @magentoConfigFixture current_store paypal/fetch_reports/ftp_sandbox 0
+     * @magentoDbIsolation enabled
+     */
+    public function testFetchAction()
+    {
+        $this->dispatch('backend/admin/paypal_reports/fetch');
+        /** @var $session Mage_Backend_Model_Session */
+        $session = Mage::getSingleton('Mage_Backend_Model_Session');
+        $this->assertEquals(1, $session->getMessages()->count());
+        /** @var $message Mage_Core_Model_Message_Error */
+        foreach ($session->getMessages() as $message) {
+            $this->assertInstanceOf('Mage_Core_Model_Message_Error', $message);
+            $this->assertContains('login@127.0.0.1', $message->getText());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Paypal/Model/Report/SettlementTest.php b/dev/tests/integration/testsuite/Mage/Paypal/Model/Report/SettlementTest.php
new file mode 100644
index 00000000000..1420b3057a1
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Paypal/Model/Report/SettlementTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Paypal_Model_Report_SettlementTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @magentoDbIsolation enabled
+     */
+    public function testFetchAndSave()
+    {
+        /** @var $model Mage_Paypal_Model_Report_Settlement; */
+        $model = Mage::getModel('Mage_Paypal_Model_Report_Settlement');
+        $connection = $this->getMock('Varien_Io_Sftp', array('rawls', 'read'), array(), '', false);
+        $filename = 'STL-00000000.00.abc.CSV';
+        $connection->expects($this->once())->method('rawls')->will($this->returnValue(array($filename => array())));
+        $connection->expects($this->once())->method('read')->with($filename, $this->anything());
+        $model->fetchAndSave($connection);
+    }
+
+    /**
+     * @param array $config
+     * @expectedException InvalidArgumentException
+     * @dataProvider createConnectionExceptionDataProvider
+     */
+    public function testCreateConnectionException($config)
+    {
+        Mage_Paypal_Model_Report_Settlement::createConnection($config);
+    }
+
+    /**
+     * @return array
+     */
+    public function createConnectionExceptionDataProvider()
+    {
+        return array(
+            array(array()),
+            array(array('username' => 'test', 'password' => 'test', 'path' => '/')),
+            array(array('hostname' => 'example.com', 'password' => 'test', 'path' => '/')),
+            array(array('hostname' => 'example.com', 'username' => 'test', 'path' => '/')),
+            array(array('hostname' => 'example.com', 'username' => 'test', 'password' => 'test')),
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/customer.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/customer.php
new file mode 100644
index 00000000000..97cded705ab
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/customer.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+$customer = Mage::getModel('Mage_Customer_Model_Customer');
+$customer->setStoreId(1)
+    ->setCreatedIn('Default Store View')
+    ->setDefaultBilling(1)
+    ->setDefaultShipping(1)
+    ->setEmail('mr.test.creditmemo.' . uniqid() . '@test.com')
+    ->setFirstname('Test')
+    ->setLastname('Test')
+    ->setMiddlename('Test')
+    ->setGroupId(1)
+    ->setRewardUpdateNotification(1)
+    ->setRewardWarningNotification(1)
+    ->save();
+Mage::register('customer', $customer);
+
+$customerAddress = Mage::getModel('Mage_Customer_Model_Address');
+$customerAddress->setData(
+    array(
+        'city' => 'New York',
+        'country_id' => 'US',
+        'fax' => '56-987-987',
+        'firstname' => 'Jacklin',
+        'lastname' => 'Sparrow',
+        'middlename' => 'John',
+        'postcode' => '10012',
+        'region' => 'New York',
+        'region_id' => '43',
+        'street' => 'Main Street',
+        'telephone' => '718-452-9207',
+        'is_default_billing' => true,
+        'is_default_shipping' => true
+    )
+);
+$customerAddress->setCustomer($customer);
+$customerAddress->save();
+Mage::register('customer_address', $customerAddress);
+
+//Set customer default shipping and billing address
+$customer->addAddress($customerAddress);
+$customer->setDefaultShipping($customerAddress->getId());
+$customer->setDefaultBilling($customerAddress->getId());
+$customer->save();
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/customer_rollback.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/customer_rollback.php
new file mode 100644
index 00000000000..0b0a82e14d6
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/customer_rollback.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+Mage::unregister('customer');
+Mage::unregister('customer_address');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/multiple_invoices.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/multiple_invoices.php
new file mode 100644
index 00000000000..a48ea09a908
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/multiple_invoices.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+if (!Mage::registry('order')) {
+    require 'order.php';
+}
+/** @var $order Mage_Sales_Model_Order */
+$order = Mage::registry('order');
+
+$orderService = new Mage_Sales_Model_Service_Order($order);
+$invoice = $orderService->prepareInvoice();
+$invoice->register();
+$invoice->getOrder()->setIsInProcess(true);
+$transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction');
+$transactionSave->addObject($invoice)
+    ->addObject($invoice->getOrder())
+    ->save();
+
+Mage::register('invoice', $invoice);
+$order2 = Mage::registry('order2');
+$orderService2 = new Mage_Sales_Model_Service_Order($order2);
+$invoice2 = $orderService2->prepareInvoice();
+$invoice2->register();
+$invoice2->getOrder()->setIsInProcess(true);
+$transactionSave2 = Mage::getModel('Mage_Core_Model_Resource_Transaction');
+$transactionSave2->addObject($invoice2)
+    ->addObject($invoice2->getOrder())
+    ->save();
+
+Mage::register('invoice2', $invoice2);
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/multiple_invoices_rollback.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/multiple_invoices_rollback.php
new file mode 100644
index 00000000000..524f9439451
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/multiple_invoices_rollback.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+Mage::unregister('invoice');
+Mage::unregister('invoice2');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order.php
new file mode 100644
index 00000000000..f84998f168a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+//Set up customer fixture
+require 'customer.php';
+/** @var $customer Mage_Customer_Model_Customer */
+$customer = Mage::registry('customer');
+//Set up virtual product fixture
+require 'product_virtual.php';
+/** @var $product Mage_Catalog_Model_Product */
+$product = Mage::registry('product_virtual');
+
+//Create quote
+$quote = Mage::getModel('Mage_Sales_Model_Quote');
+$quote->setStoreId(1)
+    ->setCustomerEmail($customer->getEmail())
+    ->setIsActive(false)
+    ->setIsMultiShipping(false)
+    ->assignCustomerWithAddressChange($customer)
+    ->setCheckoutMethod($customer->getMode())
+    ->setPasswordHash($customer->encryptPassword($customer->getPassword()))
+    ->addProduct($product->load($product->getId()), 2);
+
+$quote->collectTotals();
+$quote->save();
+Mage::register('quote', $quote);
+
+//Create order
+$quoteService = new Mage_Sales_Model_Service_Quote($quote);
+//Set payment method to check/money order
+$quoteService->getQuote()->getPayment()->setMethod('checkmo');
+$order = $quoteService->submitOrder();
+$order->place();
+$order->save();
+Mage::register('order', $order);
+
+//Create order
+$quote2 = Mage::getModel('Mage_Sales_Model_Quote');
+$quote2->setStoreId(1)
+    ->setCustomerEmail($customer->getEmail())
+    ->setIsActive(false)
+    ->setIsMultiShipping(false)
+    ->assignCustomerWithAddressChange($customer)
+    ->setCheckoutMethod($customer->getMode())
+    ->setPasswordHash($customer->encryptPassword($customer->getPassword()))
+    ->addProduct($product->load($product->getId()), 2);
+
+$quote2->collectTotals();
+$quote2->save();
+Mage::register('quote2', $quote2);
+
+$quoteService2 = new Mage_Sales_Model_Service_Quote($quote2);
+//Set payment method to check/money order
+$quoteService2->getQuote()->getPayment()->setMethod('checkmo');
+$order2 = $quoteService2->submitOrder();
+$order2->place();
+$order2->save();
+Mage::register('order2', $order2);
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_rollback.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_rollback.php
new file mode 100644
index 00000000000..b2ff2ba6d18
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_rollback.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('quote');
+Mage::unregister('order');
+Mage::unregister('quote2');
+Mage::unregister('order2');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_with_shipping.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_with_shipping.php
new file mode 100644
index 00000000000..04a70899b26
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_with_shipping.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+//Set up customer fixture
+require 'customer.php';
+/** @var $customer Mage_Customer_Model_Customer */
+//Set up customer address fixture
+$customer = Mage::registry('customer');
+/** @var $customerAddress Mage_Customer_Model_Address */
+$customerAddress = Mage::registry('customer_address');
+/*//$customerAddress->addShippingRate($rate);
+$customerAddress->setShippingMethod('freeshipping_freeshipping');
+$customerAddress->addShippingRate($method);   //$rate
+$customerAddress->save();*/
+
+//Set up simple product fixture
+require 'product_simple.php';
+/** @var $product Mage_Catalog_Model_Product */
+$product = Mage::registry('product_simple');
+
+
+//Create quote
+$quote = Mage::getModel('Mage_Sales_Model_Quote');
+$quote->setStoreId(1)
+    ->setIsActive(false)
+    ->setIsMultiShipping(false)
+    ->assignCustomerWithAddressChange($customer)
+    ->setCheckoutMethod($customer->getMode())
+    ->setPasswordHash($customer->encryptPassword($customer->getPassword()))
+    ->addProduct($product->load($product->getId()), 2);
+
+/** @var $rate Mage_Sales_Model_Quote_Address_Rate */
+$rate = Mage::getModel('Mage_Sales_Model_Quote_Address_Rate');
+$rate->setCode('freeshipping_freeshipping');
+$rate->getPrice(1);
+
+$quote->getShippingAddress()->setShippingMethod('freeshipping_freeshipping');
+$quote->getShippingAddress()->addShippingRate($rate);
+
+$quote->collectTotals();
+$quote->save();
+Mage::register('quote', $quote);
+
+//Create order
+$quoteService = new Mage_Sales_Model_Service_Quote($quote);
+//Set payment method to check/money order
+$quoteService->getQuote()->getPayment()->setMethod('checkmo');
+$order = $quoteService->submitOrder();
+$order->place();
+$order->save();
+Mage::register('order', $order);
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_with_shipping_rollback.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_with_shipping_rollback.php
new file mode 100644
index 00000000000..e2696eca8f9
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/order_with_shipping_rollback.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Fixture roll back logic.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('quote');
+Mage::unregister('order');
+Mage::unregister('product_simple');
+Mage::unregister('customer');
+Mage::unregister('customer_address');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_simple.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_simple.php
new file mode 100644
index 00000000000..de2ce774043
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_simple.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+$product = Mage::getModel('Mage_Catalog_Model_Product');
+$product->setTypeId('simple')
+    ->setAttributeSetId(4)
+    ->setStoreId(0)
+    ->setName('Simple Product')
+    ->setSku('simple-product-' . uniqid())
+    ->setPrice(10)
+    ->setTaxClassId(0)
+    ->setMetaTitle('meta title')
+    ->setMetaKeyword('meta keyword')
+    ->setMetaDescription('meta description')
+    ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
+    ->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
+    ->setStockData(
+    array(
+        'use_config_manage_stock' => 1,
+        'qty' => 100,
+        'is_qty_decimal' => 0,
+        'is_in_stock' => 1,
+    )
+)
+    ->save();
+// to make stock item visible from created product it should be reloaded
+$product = Mage::getModel('Mage_Catalog_Model_Product')->load($product->getId());
+Mage::register('product_simple', $product);
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_simple_rollback.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_simple_rollback.php
new file mode 100644
index 00000000000..b34f865fafd
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_simple_rollback.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+Mage::unregister('product_simple');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_virtual.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_virtual.php
new file mode 100644
index 00000000000..01041a27780
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_virtual.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+$product = Mage::getModel('Mage_Catalog_Model_Product');
+$product->setTypeId('virtual')
+    ->setAttributeSetId(4)
+    ->setStoreId(0)
+    ->setName('Simple Product')
+    ->setSku('virtual-creditmemo-' . uniqid())
+    ->setPrice(10)
+    ->setTaxClassId(0)
+    ->setMetaTitle('meta title')
+    ->setMetaKeyword('meta keyword')
+    ->setMetaDescription('meta description')
+    ->setVisibility(Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
+    ->setStatus(Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
+    ->setStockData(
+    array(
+        'use_config_manage_stock' => 1,
+        'qty' => 100,
+        'is_qty_decimal' => 0,
+        'is_in_stock' => 1,
+    )
+);
+$product->save();
+Mage::register('product_virtual', $product);
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_virtual_rollback.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_virtual_rollback.php
new file mode 100644
index 00000000000..cc17167bae1
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/product_virtual_rollback.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+Mage::unregister('product_virtual');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/shipment.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/shipment.php
new file mode 100644
index 00000000000..ad6bd240bc5
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/shipment.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+include 'order_with_shipping.php';
+/** @var Mage_Sales_Model_Order $order */
+
+$shipment = $order->prepareShipment();
+$shipment->register();
+$shipment->getOrder()->setIsInProcess(true);
+/** @var Mage_Core_Model_Resource_Transaction $transaction */
+$transaction = Mage::getModel('Mage_Core_Model_Resource_Transaction');
+$transaction->addObject($shipment)->addObject($order)->save();
+
+Mage::register('shipment', $shipment);
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/shipment_rollback.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/shipment_rollback.php
new file mode 100644
index 00000000000..16074db5ed9
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Api/_files/shipment_rollback.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Fixture roll back logic.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+Mage::unregister('quote');
+Mage::unregister('order');
+Mage::unregister('product_simple');
+Mage::unregister('customer');
+Mage::unregister('customer_address');
+Mage::unregister('shipment');
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/ApiTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/ApiTest.php
new file mode 100644
index 00000000000..87d6411318a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/ApiTest.php
@@ -0,0 +1,221 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/**
+ * Test API getting orders list method
+ *
+ * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/order.php
+ */
+class Mage_Sales_Model_Order_ApiTest extends PHPUnit_Framework_TestCase
+{
+    const STATUS_PENDING = 'pending';
+
+    /**
+     * Test info method of sales order API.
+     */
+    public function testInfo()
+    {
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+        $orderInfo = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderInfo',
+            array(
+                $order->getIncrementId()
+            )
+        );
+        /** Check availability of some important fields in response */
+        $expectedArrayFields = array('shipping_address', 'billing_address', 'items', 'payment', 'status_history');
+        $missingFields = array_diff($expectedArrayFields, array_keys($orderInfo));
+        $this->assertEmpty(
+            $missingFields,
+            sprintf("The following fields must be present in response: %s.", implode(', ', $missingFields))
+        );
+
+        /** Check values of some fields received from order info */
+        $fieldsToCompare = array(
+            'entity_id' => 'order_id',
+            'state',
+            'status',
+            'customer_id',
+            'store_id',
+            'base_grand_total',
+            'increment_id',
+            'customer_email',
+            'order_currency_code'
+        );
+
+        Magento_Test_Helper_Api::checkEntityFields($this, $order->getData(), $orderInfo, $fieldsToCompare);
+    }
+
+    /**
+     * Test 'addComment' method of sales order API.
+     */
+    public function testAddComment()
+    {
+        $this->markTestSkipped("Skipped due to bug in addComment implementation: MAGETWO-6895.");
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+
+        $historySizeBefore = count($order->getAllStatusHistory());
+        $newOrderStatus = self::STATUS_PENDING;
+        $statusChangeComment = "Order status change comment.";
+        $isAdded = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderAddComment',
+            array(
+                $order->getIncrementId(),
+                $newOrderStatus,
+                $statusChangeComment,
+                true
+            )
+        );
+        $this->assertTrue($isAdded, "Comment was not added");
+
+        /** @var Mage_Sales_Model_Order $orderAfter */
+        $orderAfter = Mage::getModel('Mage_Sales_Model_Order')->load($order->getId());
+        $historyAfter = $orderAfter->getAllStatusHistory();
+        $this->assertCount($historySizeBefore + 1, $historyAfter, "History item was not created.");
+        /** @var Mage_Sales_Model_Order_Status_History $createdHistoryItem */
+        $createdHistoryItem = end($historyAfter);
+        $this->assertEquals($statusChangeComment, $createdHistoryItem->getComment(), 'Comment is invalid.');
+    }
+
+    /**
+     * Test getting sales order list in other methods
+     */
+    public function testList()
+    {
+        if (Magento_Test_Bootstrap::getInstance()->getDbVendorName() != 'mysql') {
+            $this->markTestIncomplete('Legacy API is expected to support MySQL only.');
+        }
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+
+        $filters = array(
+            'filters' => (object)array(
+                'filter' => array(
+                    (object)array('key' => 'status', 'value' => $order->getData('status')),
+                    (object)array('key' => 'created_at', 'value' => $order->getData('created_at'))
+                ),
+                'complex_filter' => array(
+                    (object)array(
+                        'key' => 'order_id',
+                        'value' => (object)array('key' => 'in', 'value' => "{$order->getId()},0")
+                    ),
+                    array(
+                        'key' => 'protect_code',
+                        'value' => (object)array('key' => 'in', 'value' => $order->getData('protect_code'))
+                    )
+                )
+            )
+        );
+
+        $result = Magento_Test_Helper_Api::call($this, 'salesOrderList', $filters);
+
+        if (!isset($result[0])) { // workaround for WS-I
+            $result = array($result);
+        }
+        //should be got array with one order item
+        $this->assertInternalType('array', $result);
+        $this->assertEquals(1, count($result));
+        $this->assertEquals($order->getId(), $result[0]['order_id']);
+    }
+
+    /**
+     * Test for salesOrderCancel when order is in 'pending' status
+     */
+    public function testCancelPendingOrder()
+    {
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+
+        $order->setStatus(self::STATUS_PENDING)
+            ->save();
+
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCancel',
+            array(
+                'orderIncrementId' => $order->getIncrementId()
+            )
+        );
+
+        $this->assertTrue((bool)$soapResult, 'API call result in not TRUE');
+
+        // reload order to obtain new status
+        $order->load($order->getId());
+
+        $this->assertEquals(Mage_Sales_Model_Order::STATE_CANCELED, $order->getStatus(), 'Status is not CANCELED');
+    }
+
+    /**
+     * Test for salesOrderHold when order is in 'processing' status
+     */
+    public function testHoldProcessingOrder()
+    {
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+
+        $order->setState(Mage_Sales_Model_Order::STATE_NEW, self::STATUS_PENDING)
+            ->save();
+
+        $soapResult = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderHold',
+            array(
+                'orderIncrementId' => $order->getIncrementId()
+            )
+        );
+
+        $this->assertTrue((bool)$soapResult, 'API call result in not TRUE');
+
+        // reload order to obtain new status
+        $order->load($order->getId());
+
+        $this->assertEquals(Mage_Sales_Model_Order::STATE_HOLDED, $order->getStatus(), 'Status is not HOLDED');
+    }
+
+    /**
+     * Test for 'unhold' method of sales order API.
+     *
+     * @depends testHoldProcessingOrder
+     */
+    public function testUnhold()
+    {
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+        $isUnholded = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderUnhold',
+            array(
+                $order->getIncrementId()
+            )
+        );
+        $this->assertTrue($isUnholded, "The order was not unholded.");
+        /** @var Mage_Sales_Model_Order $updatedOrder */
+        $updatedOrder = Mage::getModel('Mage_Sales_Model_Order');
+        $updatedOrder->load($order->getId());
+        $this->assertEquals(self::STATUS_PENDING, $updatedOrder->getStatus(), 'Order was not unholded.');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Creditmemo/ApiTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Creditmemo/ApiTest.php
new file mode 100644
index 00000000000..c3ed61fe52a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Creditmemo/ApiTest.php
@@ -0,0 +1,357 @@
+<?php
+/**
+ * Creditmemo API model test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Sales_Model_Order_Creditmemo_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test sales order credit memo list, info, create, cancel
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/multiple_invoices.php
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     */
+    public function testCRUD()
+    {
+        $creditmemoInfo = $this->_createCreditmemo();
+        list($product, $qtys, $adjustmentPositive, $adjustmentNegative, $creditMemoIncrement) = $creditmemoInfo;
+
+        //Test list
+        $creditmemoList = Magento_Test_Helper_Api::call($this, 'salesOrderCreditmemoList');
+        $this->assertInternalType('array', $creditmemoList);
+        $this->assertNotEmpty($creditmemoList, 'Creditmemo list is empty');
+
+        //Test add comment
+        $commentText = 'Creditmemo comment';
+        $this->assertTrue(
+            (bool)Magento_Test_Helper_Api::call(
+                $this,
+                'salesOrderCreditmemoAddComment',
+                array(
+                    'creditmemoIncrementId' => $creditMemoIncrement,
+                    'comment' => $commentText
+                )
+            )
+        );
+
+        //Test info
+        $creditmemoInfo = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoInfo',
+            array(
+                'creditmemoIncrementId' => $creditMemoIncrement
+            )
+        );
+
+        $this->assertInternalType('array', $creditmemoInfo);
+        $this->assertNotEmpty($creditmemoInfo);
+        $this->assertEquals($creditMemoIncrement, $creditmemoInfo['increment_id']);
+
+        //Test adjustments fees were added
+        $this->assertEquals($adjustmentPositive, $creditmemoInfo['adjustment_positive']);
+        $this->assertEquals($adjustmentNegative, $creditmemoInfo['adjustment_negative']);
+
+        //Test order items were refunded
+        $this->assertArrayHasKey('items', $creditmemoInfo);
+        $this->assertInternalType('array', $creditmemoInfo['items']);
+        $this->assertGreaterThan(0, count($creditmemoInfo['items']));
+
+        if (!isset($creditmemoInfo['items'][0])) { // workaround for WSI plain array response
+            $creditmemoInfo['items'] = array($creditmemoInfo['items']);
+        }
+
+        $this->assertEquals($creditmemoInfo['items'][0]['order_item_id'], $qtys[0]['order_item_id']);
+        $this->assertEquals($product->getId(), $creditmemoInfo['items'][0]['product_id']);
+
+        if (!isset($creditmemoInfo['comments'][0])) { // workaround for WSI plain array response
+            $creditmemoInfo['comments'] = array($creditmemoInfo['comments']);
+        }
+
+        //Test comment was added correctly
+        $this->assertArrayHasKey('comments', $creditmemoInfo);
+        $this->assertInternalType('array', $creditmemoInfo['comments']);
+        $this->assertGreaterThan(0, count($creditmemoInfo['comments']));
+        $this->assertEquals($commentText, $creditmemoInfo['comments'][0]['comment']);
+
+        //Test cancel
+        //Situation when creditmemo is possible to cancel was not found
+        $this->setExpectedException('SoapFault');
+        Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoCancel',
+            array('creditmemoIncrementId' => $creditMemoIncrement)
+        );
+    }
+
+    /**
+     * Test Exception when refund amount greater than available to refund amount
+     *
+     * @expectedException SoapFault
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/multiple_invoices.php
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     */
+    public function testNegativeRefundException()
+    {
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+        $overRefundAmount = $order->getGrandTotal() + 10;
+
+        Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoCreate',
+            array(
+                'creditmemoIncrementId' => $order->getIncrementId(),
+                'creditmemoData' => (object)array(
+                    'adjustment_positive' => $overRefundAmount
+                )
+            )
+        );
+    }
+
+    /**
+     * Test filtered list empty if filter contains incorrect order id
+     */
+    public function testListEmptyFilter()
+    {
+        $filter = array(
+            'filter' => array((object)array('key' => 'order_id', 'value' => 'invalid-id'))
+        );
+        $creditmemoList = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoList',
+            (object)array('filters' => $filter)
+        );
+        $this->assertEquals(0, count($creditmemoList));
+    }
+
+    /**
+     * Test Exception on invalid creditmemo create data
+     *
+     * @expectedException SoapFault
+     */
+    public function testCreateInvalidOrderException()
+    {
+        Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoCreate',
+            array(
+                'orderIncrementId' => 'invalid-id',
+                'creditmemoData' => array()
+            )
+        );
+    }
+
+    /**
+     * Test Exception on invalid credit memo while adding comment
+     *
+     * @expectedException SoapFault
+     */
+    public function testAddCommentInvalidCreditmemoException()
+    {
+        Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoAddComment',
+            array(
+                'creditmemoIncrementId' => 'invalid-id',
+                'comment' => 'Comment'
+            )
+        );
+    }
+
+    /**
+     * Test Exception on invalid credit memo while getting info
+     *
+     * @expectedException SoapFault
+     */
+    public function testInfoInvalidCreditmemoException()
+    {
+        Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoInfo',
+            array('creditmemoIncrementId' => 'invalid-id')
+        );
+    }
+
+    /**
+     * Test exception on invalid credit memo cancel
+     *
+     * @expectedException SoapFault
+     */
+    public function testCancelInvalidIdException()
+    {
+        Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoCancel',
+            array('creditmemoIncrementId' => 'invalid-id')
+        );
+    }
+
+    /**
+     * Test credit memo create API call results
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/multiple_invoices.php
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     */
+    public function testAutoIncrementType()
+    {
+        // Set creditmemo increment id prefix
+        $prefix = '01';
+        Magento_Test_Helper_Eav::setIncrementIdPrefix('creditmemo', $prefix);
+
+        $order = Mage::registry('order2');
+
+        $orderItems = $order->getAllItems();
+        $qtys = array();
+
+        /** @var $orderItem Mage_Sales_Model_Order_Item */
+        foreach ($orderItems as $orderItem) {
+            $qtys[] = array('order_item_id' => $orderItem->getId(), 'qty' => 1);
+        }
+        $adjustmentPositive = 2;
+        $adjustmentNegative = 1;
+        $data = array(
+            'qtys' => $qtys,
+            'adjustment_positive' => $adjustmentPositive,
+            'adjustment_negative' => $adjustmentNegative
+        );
+        $orderIncrementalId = $order->getIncrementId();
+
+        //Test create
+        $creditMemoIncrement = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoCreate',
+            array(
+                'creditmemoIncrementId' => $orderIncrementalId,
+                'creditmemoData' => $data
+            )
+        );
+        Mage::register('creditmemoIncrementId', $creditMemoIncrement);
+
+        $this->assertTrue(is_string($creditMemoIncrement), 'Increment Id is not a string');
+        $this->assertStringStartsWith(
+            $prefix,
+            $creditMemoIncrement,
+            'Increment Id returned by API is not correct'
+        );
+    }
+
+    /**
+     * Test order creditmemo list. With filters
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/multiple_invoices.php
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     * @depends testCRUD
+     */
+    public function testListWithFilters()
+    {
+        $creditmemoInfo = $this->_createCreditmemo();
+        $creditMemoIncrement = end($creditmemoInfo);
+
+        /** @var $creditmemo Mage_Sales_Model_Order_Creditmemo */
+        $creditmemo = Mage::getModel('Mage_Sales_Model_Order_Creditmemo')->load($creditMemoIncrement, 'increment_id');
+
+        $filters = array(
+            'filters' => (object)array(
+                'filter' => array(
+                    (object)array('key' => 'state', 'value' => $creditmemo->getData('state')),
+                    (object)array('key' => 'created_at', 'value' => $creditmemo->getData('created_at'))
+                ),
+                'complex_filter' => array(
+                    (object)array(
+                        'key' => 'creditmemo_id',
+                        'value' => (object)array('key' => 'in', 'value' => array($creditmemo->getId(), 0))
+                    ),
+                )
+            )
+        );
+
+        $result = Magento_Test_Helper_Api::call($this, 'salesOrderCreditmemoList', $filters);
+
+        if (!isset($result[0])) { // workaround for WS-I
+            $result = array($result);
+        }
+        $this->assertInternalType('array', $result, "Response has invalid format");
+        $this->assertEquals(1, count($result), "Invalid creditmemos quantity received");
+        foreach (reset($result) as $field => $value) {
+            if ($field == 'creditmemo_id') {
+                // process field mapping
+                $field = 'entity_id';
+            }
+            $this->assertEquals($creditmemo->getData($field), $value, "Field '{$field}' has invalid value");
+        }
+    }
+
+    /**
+     * Create creditmemo using API. Invoice fixture must be initialized for this method
+     *
+     * @return array
+     */
+    protected function _createCreditmemo()
+    {
+        /** @var $product Mage_Catalog_Model_Product */
+        $product = Mage::registry('product_virtual');
+
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+
+        $orderItems = $order->getAllItems();
+        $qtys = array();
+
+        /** @var $orderItem Mage_Sales_Model_Order_Item */
+        foreach ($orderItems as $orderItem) {
+            $qtys[] = array('order_item_id' => $orderItem->getId(), 'qty' => 1);
+        }
+
+        $adjustmentPositive = 2;
+        $adjustmentNegative = 3;
+        $data = array(
+            'qtys' => $qtys,
+            'adjustment_positive' => $adjustmentPositive,
+            'adjustment_negative' => $adjustmentNegative
+        );
+        $orderIncrementalId = $order->getIncrementId();
+
+        //Test create
+        $creditMemoIncrement = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderCreditmemoCreate',
+            array(
+                'creditmemoIncrementId' => $orderIncrementalId,
+                'creditmemoData' => (object)$data
+            )
+        );
+
+        /** Add creditmemo to fixtures to ensure that it is removed in teardown. */
+        /** @var Mage_Sales_Model_Order_Creditmemo $createdCreditmemo */
+        $createdCreditmemo = Mage::getModel('Mage_Sales_Model_Order_Creditmemo');
+        $createdCreditmemo->load($creditMemoIncrement, 'increment_id');
+        Mage::register('creditmemo', $createdCreditmemo);
+
+        $this->assertNotEmpty($creditMemoIncrement, 'Creditmemo was not created');
+        return array($product, $qtys, $adjustmentPositive, $adjustmentNegative, $creditMemoIncrement);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/CreditmemoTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/CreditmemoTest.php
index a061b1a909a..98c69769eb8 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/CreditmemoTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/CreditmemoTest.php
@@ -28,7 +28,7 @@
 class Mage_Sales_Model_Order_CreditmemoTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * @magentoConfigFixture current_store design/theme/full_name default/demo
+     * @magentoConfigFixture frontend/design/theme/full_name default/demo
      * @magentoDataFixture Mage/Sales/_files/order.php
      */
     public function testSendEmail()
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Invoice/ApiTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Invoice/ApiTest.php
new file mode 100644
index 00000000000..c6da08418ba
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Invoice/ApiTest.php
@@ -0,0 +1,319 @@
+<?php
+/**
+ * Tests for invoice API.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Sales_Model_Order_Invoice_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test create and read created invoice
+     *
+     * @magentoDataFixture Mage/Sales/_files/order.php
+     * @magentoDbIsolation enabled
+     */
+    public function testCreate()
+    {
+        /** Prepare data. */
+        $order = $this->_getFixtureOrder();
+        $this->assertCount(
+            0,
+            $order->getInvoiceCollection(),
+            'There must be 0 invoices before invoice creation via API.'
+        );
+
+        /** Create new invoice via API. */
+        $newInvoiceId = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderInvoiceCreate',
+            array(
+                'orderIncrementId' => $order->getIncrementId(),
+                'itemsQty' => array(),
+                'comment' => 'invoice Created',
+                'email' => true,
+                'includeComment' => true
+            )
+        );
+        $this->assertGreaterThan(0, (int)$newInvoiceId, 'Invoice was not created.');
+
+        /** Ensure that invoice was created. */
+        /** @var Mage_Sales_Model_Order $invoicedOrder */
+        $invoicedOrder = Mage::getModel('Mage_Sales_Model_Order');
+        $invoicedOrder->loadByIncrementId($order->getIncrementId());
+        $invoiceCollection = $invoicedOrder->getInvoiceCollection();
+        $this->assertCount(1, $invoiceCollection->getItems(), 'Invoice was not created.');
+        /** @var Mage_Sales_Model_Order_Invoice $createdInvoice */
+        $createdInvoice = $invoiceCollection->getFirstItem();
+        $this->assertEquals(
+            $createdInvoice->getIncrementId(),
+            $newInvoiceId,
+            'Invoice ID in call response is invalid.'
+        );
+    }
+
+    /**
+     * Test create and read created invoice
+     *
+     * @magentoDataFixture Mage/Sales/_files/invoice.php
+     */
+    public function testInfo()
+    {
+        /** Retrieve invoice data via API. */
+        $invoiceData = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderInvoiceInfo',
+            array(
+                $this->_getFixtureInvoice()->getIncrementId(),
+            )
+        );
+
+        /** Check received data validity. */
+        $fieldsToCheck = array(
+            'increment_id',
+            'parent_id',
+            'store_id',
+            'order_id',
+            'state',
+            'entity_id' => 'invoice_id',
+            'base_grand_total'
+        );
+        Magento_Test_Helper_Api::checkEntityFields(
+            $this,
+            $this->_getFixtureInvoice()->getData(),
+            $invoiceData,
+            $fieldsToCheck
+        );
+    }
+
+    /**
+     * Test adding comment to invoice via API.
+     *
+     * @magentoDataFixture Mage/Sales/_files/invoice.php
+     * @magentoDbIsolation enabled
+     */
+    public function testAddComment()
+    {
+        /** Prepare data. */
+        $commentText = "Test invoice comment.";
+
+        /** Retrieve invoice data via API. */
+        $isAdded = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderInvoiceAddComment',
+            array(
+                $this->_getFixtureInvoice()->getIncrementId(),
+                $commentText,
+                true, // send invoice via email
+                true // include comment in email
+            )
+        );
+        $this->assertTrue($isAdded, "Comment was not added to the invoice.");
+
+        /** Verify that comment was actually added. */
+        /** @var Mage_Sales_Model_Resource_Order_Invoice_Comment_Collection $commentsCollection */
+        $commentsCollection = $this->_getFixtureInvoice()->getCommentsCollection(true);
+        $this->assertCount(1, $commentsCollection->getItems(), "There must be exactly 1 invoice comment.");
+        /** @var Mage_Sales_Model_Order_Invoice_Comment $createdComment */
+        $createdComment = $commentsCollection->getFirstItem();
+        $this->assertEquals($commentText, $createdComment->getComment(), 'Invoice comment text is invalid.');
+    }
+
+    /**
+     * Test capturing invoice via API.
+     *
+     * @magentoDataFixture Mage/Sales/_files/invoice_verisign.php
+     */
+    public function testCapture()
+    {
+        /**
+         * To avoid complicated environment emulation for online payment,
+         * we can check if proper error message from payment gateway was received or not.
+         */
+        $this->setExpectedException('SoapFault', 'Invalid vendor account');
+
+        /** Capture invoice data via API. */
+        $invoiceBefore = $this->_getFixtureInvoice();
+        $this->assertTrue($invoiceBefore->canCapture(), "Invoice fixture cannot be captured.");
+        Magento_Test_Helper_Api::call($this, 'salesOrderInvoiceCapture', array($invoiceBefore->getIncrementId()));
+    }
+
+    /**
+     * Test voiding captured invoice via API.
+     *
+     * @magentoDataFixture Mage/Sales/_files/invoice_verisign.php
+     */
+    public function testVoid()
+    {
+        /**
+         * To avoid complicated environment emulation for online voiding,
+         * we can check if proper error message from payment gateway was received or not.
+         */
+        $this->setExpectedException('SoapFault', 'Invalid vendor account');
+
+        /** Prepare data. Make invoice voidable. */
+        $invoiceBefore = $this->_getFixtureInvoice();
+        $invoiceBefore->setState(Mage_Sales_Model_Order_Invoice::STATE_PAID)->setCanVoidFlag(true)->save();
+
+        /** Capture invoice data via API. */
+        $this->assertTrue($invoiceBefore->canVoid(), "Invoice fixture cannot be voided.");
+        Magento_Test_Helper_Api::call($this, 'salesOrderInvoiceVoid', array($invoiceBefore->getIncrementId()));
+    }
+
+    /**
+     * Test cancelling invoice via API.
+     *
+     * @magentoDataFixture Mage/Sales/_files/invoice_verisign.php
+     */
+    public function testCancel()
+    {
+        /** Capture invoice data via API. */
+        $invoiceBefore = $this->_getFixtureInvoice();
+        $this->assertTrue($invoiceBefore->canCancel(), "Invoice fixture cannot be cancelled.");
+        $isCanceled = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderInvoiceCancel',
+            array($invoiceBefore->getIncrementId())
+        );
+        $this->assertTrue($isCanceled, "Invoice was not canceled successfully.");
+
+        /** Ensure that invoice was actually cancelled. */
+        $invoiceAfter = $this->_getFixtureInvoice();
+        $this->assertEquals(
+            Mage_Sales_Model_Order_Invoice::STATE_CANCELED,
+            $invoiceAfter->getState(),
+            "Invoice was not cancelled."
+        );
+    }
+
+    /**
+     * Retrieve invoice declared in fixture.
+     *
+     * This method reloads data and creates new object with each call.
+     *
+     * @return Mage_Sales_Model_Order_Invoice
+     */
+    protected function _getFixtureInvoice()
+    {
+        $order = $this->_getFixtureOrder();
+        $invoiceCollection = $order->getInvoiceCollection();
+        $this->assertCount(1, $invoiceCollection->getItems(), 'There must be exactly 1 invoice assigned to the order.');
+        /** @var Mage_Sales_Model_Order_Invoice $invoice */
+        $invoice = $invoiceCollection->getFirstItem();
+        return $invoice;
+    }
+
+    /**
+     * Retrieve order declared in fixture.
+     *
+     * This method reloads data and creates new object with each call.
+     *
+     * @return Mage_Sales_Model_Order
+     */
+    protected function _getFixtureOrder()
+    {
+        $orderIncrementId = '100000001';
+        /** @var Mage_Sales_Model_Order $order */
+        $order = Mage::getModel('Mage_Sales_Model_Order');
+        $order->loadByIncrementId($orderIncrementId);
+        return $order;
+    }
+
+    /**
+     * Test credit memo create API call results
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/order.php
+     * @magentoAppIsolation enabled
+     * @magentoDbIsolation enabled
+     */
+    public function testAutoIncrementType()
+    {
+        /** @var $quote Mage_Sales_Model_Quote */
+        $order = Mage::registry('order2');
+        $incrementId = $order->getIncrementId();
+
+        // Set invoice increment id prefix
+        $prefix = '01';
+        Magento_Test_Helper_Eav::setIncrementIdPrefix('invoice', $prefix);
+
+        // Create new invoice
+        $newInvoiceId = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderInvoiceCreate',
+            array(
+                'orderIncrementId' => $incrementId,
+                'itemsQty' => array(),
+                'comment' => 'invoice Created',
+                'email' => true,
+                'includeComment' => true
+            )
+        );
+
+        $this->assertTrue(is_string($newInvoiceId), 'Increment Id is not a string');
+        $this->assertStringStartsWith($prefix, $newInvoiceId, 'Increment Id returned by API is not correct');
+        Mage::register('invoiceIncrementId', $newInvoiceId);
+    }
+
+    /**
+     * Test order invoice list. With filters
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/multiple_invoices.php
+     * @magentoAppIsolation enabled
+     */
+    public function testListWithFilters()
+    {
+        /** @var $invoice Mage_Sales_Model_Order_Invoice */
+        $invoice = Mage::registry('invoice');
+
+        $filters = array(
+            'filters' => (object)array(
+                'filter' => array(
+                    (object)array('key' => 'state', 'value' => $invoice->getData('state')),
+                    (object)array('key' => 'created_at', 'value' => $invoice->getData('created_at'))
+                ),
+                'complex_filter' => array(
+                    (object)array(
+                        'key' => 'invoice_id',
+                        'value' => (object)array('key' => 'in', 'value' => array($invoice->getId(), 0))
+                    ),
+                )
+            )
+        );
+
+        $result = Magento_Test_Helper_Api::call($this, 'salesOrderInvoiceList', $filters);
+
+        if (!isset($result[0])) { // workaround for WS-I
+            $result = array($result);
+        }
+        $this->assertInternalType('array', $result, "Response has invalid format");
+        $this->assertEquals(1, count($result), "Invalid invoices quantity received");
+
+        /** Reload invoice data to ensure it is up to date. */
+        $invoice->load($invoice->getId());
+        foreach (reset($result) as $field => $value) {
+            if ($field == 'invoice_id') {
+                // process field mapping
+                $field = 'entity_id';
+            }
+            $this->assertEquals($invoice->getData($field), $value, "Field '{$field}' has invalid value");
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/InvoiceTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/InvoiceTest.php
index d3e741bb3e8..f0e82db4d90 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/InvoiceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/InvoiceTest.php
@@ -28,7 +28,7 @@
 class Mage_Sales_Model_Order_InvoiceTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * @magentoConfigFixture current_store design/theme/full_name default/demo
+     * @magentoConfigFixture frontend/design/theme/full_name default/demo
      * @magentoDataFixture Mage/Sales/_files/order.php
      */
     public function testSendEmail()
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/OrderTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/OrderTest.php
index 3ac50925631..22171182e7a 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/OrderTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/OrderTest.php
@@ -28,7 +28,7 @@
 class Mage_Sales_Model_OrderTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * @magentoConfigFixture current_store design/theme/full_name default/demo
+     * @magentoConfigFixture frontend/design/theme/full_name default/demo
      * @magentoDataFixture Mage/Sales/_files/order.php
      */
     public function testSendNewOrderEmail()
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Shipment/ApiTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Shipment/ApiTest.php
new file mode 100644
index 00000000000..f6e72eef056
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/Shipment/ApiTest.php
@@ -0,0 +1,279 @@
+<?php
+/**
+ * Tests for shipment API.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Sales_Model_Order_Shipment_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test retrieving the list of shipments related to the order via API.
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/shipment.php
+     */
+    public function testItems()
+    {
+        /** Prepare data. */
+        $shipmentFixture = $this->_getShipmentFixture();
+        $filters = array(
+            'filters' => (object)array(
+                'filter' => array(
+                    (object)array('key' => 'increment_id', 'value' => $shipmentFixture->getIncrementId()),
+                )
+            )
+        );
+
+        /** Retrieve list of shipments via API. */
+        $shipmentsList = Magento_Test_Helper_Api::call($this, 'salesOrderShipmentList', $filters);
+
+        /** Verify received list of shipments. */
+        $this->assertCount(1, $shipmentsList, "Exactly 1 shipment is expected to be in the list results.");
+        $fieldsToCompare = array('increment_id', 'total_qty', 'entity_id' => 'shipment_id');
+        Magento_Test_Helper_Api::checkEntityFields(
+            $this,
+            $shipmentFixture->getData(),
+            reset($shipmentsList),
+            $fieldsToCompare
+        );
+    }
+
+    /**
+     * Test retrieving available carriers for the specified order.
+     *
+     * @magentoDataFixture Mage/Sales/_files/order.php
+     */
+    public function testGetCarriers()
+    {
+        /** Prepare data. */
+        /** @var Mage_Sales_Model_Order $order */
+        $order = Mage::getModel('Mage_Sales_Model_Order');
+        $order->loadByIncrementId('100000001');
+
+        /** Retrieve carriers list */
+        $carriersList = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderShipmentGetCarriers',
+            array($order->getIncrementId())
+        );
+
+        /** Verify carriers list. */
+        $this->assertCount(6, $carriersList, "Carriers list contains unexpected quantity of items.");
+        $dhlCarrierData = end($carriersList);
+        $expectedDhlData = array('key' => 'dhlint', 'value' => 'DHL');
+        $this->assertEquals($expectedDhlData, $dhlCarrierData, "Carriers list item is invalid.");
+    }
+
+    /**
+     * Test adding comment to shipment via API.
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/shipment.php
+     */
+    public function testAddComment()
+    {
+        if (Magento_Test_Bootstrap::getInstance()->getDbVendorName() != 'mysql') {
+            $this->markTestIncomplete('Legacy API is expected to support MySQL only.');
+        }
+        /** Add comment to shipment via API. */
+        $commentText = 'Shipment test comment.';
+        $isAdded = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderShipmentAddComment',
+            array(
+                $this->_getShipmentFixture()->getIncrementId(),
+                $commentText,
+                true, // should email be sent?
+                true, // should comment be included into email body?
+            )
+        );
+        $this->assertTrue($isAdded, "Comment was not added to the shipment.");
+
+        /** Ensure that comment was actually added to the shipment. */
+        /** @var Mage_Sales_Model_Resource_Order_Shipment_Comment_Collection $commentsCollection */
+        $commentsCollection = $this->_getShipmentFixture()->getCommentsCollection(true);
+        $this->assertCount(1, $commentsCollection->getItems(), "Exactly 1 shipment comment is expected to exist.");
+        /** @var Mage_Sales_Model_Order_Shipment_Comment $comment */
+        $comment = $commentsCollection->getFirstItem();
+        $this->assertEquals($commentText, $comment->getComment(), 'Comment text was saved to DB incorrectly.');
+    }
+
+    /**
+     * Test adding and removing tracking information via shipment API.
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/shipment.php
+     */
+    public function testTrackOperations()
+    {
+        if (Magento_Test_Bootstrap::getInstance()->getDbVendorName() != 'mysql') {
+            $this->markTestIncomplete('Legacy API is expected to support MySQL only.');
+        }
+        /** Prepare data. */
+        $carrierCode = 'ups';
+        $trackingTitle = 'Tracking title';
+        $trackingNumber = 'N123456';
+
+        /** Add tracking information via API. */
+        $trackingNumberId = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderShipmentAddTrack',
+            array($this->_getShipmentFixture()->getIncrementId(), $carrierCode, $trackingTitle, $trackingNumber)
+        );
+        $this->assertGreaterThan(0, (int)$trackingNumberId, "Tracking information was not added.");
+
+        /** Ensure that tracking data was saved correctly. */
+        $tracksCollection = $this->_getShipmentFixture()->getTracksCollection();
+        $this->assertCount(1, $tracksCollection->getItems(), "Tracking information was not saved to DB.");
+        /** @var Mage_Sales_Model_Order_Shipment_Track $track */
+        $track = $tracksCollection->getFirstItem();
+        $this->assertEquals(
+            array($carrierCode, $trackingTitle, $trackingNumber),
+            array($track->getCarrierCode(), $track->getTitle(), $track->getNumber()),
+            'Tracking data was saved incorrectly.'
+        );
+
+        /** Remove tracking information via API. */
+        $isRemoved = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderShipmentRemoveTrack',
+            array($this->_getShipmentFixture()->getIncrementId(), $trackingNumberId)
+        );
+        $this->assertTrue($isRemoved, "Tracking information was not removed.");
+
+        /** Ensure that tracking data was saved correctly. */
+        /** @var Mage_Sales_Model_Order_Shipment $updatedShipment */
+        $updatedShipment = Mage::getModel('Mage_Sales_Model_Order_Shipment');
+        $updatedShipment->load($this->_getShipmentFixture()->getId());
+        $tracksCollection = $updatedShipment->getTracksCollection();
+        $this->assertCount(0, $tracksCollection->getItems(), "Tracking information was not removed from DB.");
+    }
+
+    /**
+     * Test shipment create and info via API.
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/order_with_shipping.php
+     * @magentoDbIsolation enabled
+     */
+    public function testCRUD()
+    {
+        // Create new shipment
+        $newShipmentId = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderShipmentCreate',
+            array(
+                'orderIncrementId' => $this->_getOrderFixture()->getIncrementId(),
+                'itemsQty' => array(),
+                'comment' => 'Shipment Created',
+                'email' => true,
+                'includeComment' => true
+            )
+        );
+        Mage::register('shipmentIncrementId', $newShipmentId);
+
+        // View new shipment
+        $shipment = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderShipmentInfo',
+            array(
+                'shipmentIncrementId' => $newShipmentId
+            )
+        );
+
+        $this->assertEquals($newShipmentId, $shipment['increment_id']);
+    }
+
+    /**
+     * Test shipment create API.
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/order_with_shipping.php
+     * @magentoDbIsolation enabled
+     */
+    public function testAutoIncrementType()
+    {
+        // Set shipping increment id prefix
+        $prefix = '01';
+        Magento_Test_Helper_Eav::setIncrementIdPrefix('shipment', $prefix);
+
+        // Create new shipment
+        $newShipmentId = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderShipmentCreate',
+            array(
+                'orderIncrementId' => $this->_getOrderFixture()->getIncrementId(),
+                'itemsQty' => array(),
+                'comment' => 'Shipment Created',
+                'email' => true,
+                'includeComment' => true
+            )
+        );
+        Mage::unregister('shipmentIncrementId');
+        Mage::register('shipmentIncrementId', $newShipmentId);
+
+        $this->assertTrue(is_string($newShipmentId), 'Increment Id is not a string');
+        $this->assertStringStartsWith($prefix, $newShipmentId, 'Increment Id returned by API is not correct');
+    }
+
+    /**
+     * Test send shipping info API
+     *
+     * @magentoDataFixture Mage/Sales/Model/Order/Api/_files/shipment.php
+     * @magentoDbIsolation enabled
+     */
+    public function testSendInfo()
+    {
+        if (Magento_Test_Bootstrap::getInstance()->getDbVendorName() != 'mysql') {
+            $this->markTestIncomplete('Legacy API is expected to support MySQL only.');
+        }
+        $isSent = Magento_Test_Helper_Api::call(
+            $this,
+            'salesOrderShipmentSendInfo',
+            array(
+                'shipmentIncrementId' => $this->_getShipmentFixture()->getIncrementId(),
+                'comment' => 'Comment text.'
+            )
+        );
+
+        $this->assertTrue((bool)$isSent);
+    }
+
+    /**
+     * Retrieve order from fixture.
+     *
+     * @return Mage_Sales_Model_Order
+     */
+    protected function _getOrderFixture()
+    {
+        /** @var $order Mage_Sales_Model_Order */
+        $order = Mage::registry('order');
+        return $order;
+    }
+
+    /**
+     * Retrieve shipment from fixture.
+     *
+     * @return Mage_Sales_Model_Order_Shipment
+     */
+    protected function _getShipmentFixture()
+    {
+        /** @var $shipment Mage_Sales_Model_Order_Shipment */
+        $shipment = Mage::registry('shipment');
+        return $shipment;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/ShipmentTest.php b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/ShipmentTest.php
index f1a5823b9f5..e86b076a52c 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/Model/Order/ShipmentTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/Model/Order/ShipmentTest.php
@@ -28,7 +28,7 @@
 class Mage_Sales_Model_Order_ShipmentTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * @magentoConfigFixture current_store design/theme/full_name default/demo
+     * @magentoConfigFixture frontend/design/theme/full_name default/demo
      * @magentoDataFixture Mage/Sales/_files/order.php
      */
     public function testSendEmail()
diff --git a/dev/tests/integration/testsuite/Mage/Sales/_files/invoice.php b/dev/tests/integration/testsuite/Mage/Sales/_files/invoice.php
new file mode 100644
index 00000000000..70881cf68c4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/_files/invoice.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Paid invoice fixture.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+require 'order.php';
+/** @var Mage_Sales_Model_Order $order */
+
+$orderService = new Mage_Sales_Model_Service_Order($order);
+$invoice = $orderService->prepareInvoice();
+$invoice->register();
+$order->setIsInProcess(true);
+$transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction');
+$transactionSave->addObject($invoice)->addObject($order)->save();
diff --git a/dev/tests/integration/testsuite/Mage/Sales/_files/invoice_verisign.php b/dev/tests/integration/testsuite/Mage/Sales/_files/invoice_verisign.php
new file mode 100644
index 00000000000..a38c3eef184
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Sales/_files/invoice_verisign.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Not paid invoice fixture for online payment method.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+require 'order_paid_with_verisign.php';
+/** @var Mage_Sales_Model_Order $order */
+
+$orderService = new Mage_Sales_Model_Service_Order($order);
+$invoice = $orderService->prepareInvoice();
+/** To allow invoice cancelling it should be created without capturing. */
+$invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::NOT_CAPTURE)->register();
+$order->setIsInProcess(true);
+$transactionSave = Mage::getModel('Mage_Core_Model_Resource_Transaction');
+$transactionSave->addObject($invoice)->addObject($order)->save();
diff --git a/dev/tests/integration/testsuite/Mage/Sales/_files/order.php b/dev/tests/integration/testsuite/Mage/Sales/_files/order.php
index 25460f62ab0..30bd4bd363c 100644
--- a/dev/tests/integration/testsuite/Mage/Sales/_files/order.php
+++ b/dev/tests/integration/testsuite/Mage/Sales/_files/order.php
@@ -25,6 +25,9 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+require __DIR__ . '/../../Catalog/_files/product_simple.php';
+/** @var Mage_Catalog_Model_Product $product */
+
 $addressData = include(__DIR__ . '/address_data.php');
 $billingAddress = Mage::getModel('Mage_Sales_Model_Order_Address', array('data' => $addressData));
 $billingAddress->setAddressType('billing');
@@ -36,6 +39,11 @@ $shippingAddress->setId(null)
 $payment = Mage::getModel('Mage_Sales_Model_Order_Payment');
 $payment->setMethod('checkmo');
 
+/** @var Mage_Sales_Model_Order_Item $orderItem */
+$orderItem = Mage::getModel('Mage_Sales_Model_Order_Item');
+$orderItem->setProductId($product->getId())->setQtyOrdered(2);
+
+/** @var Mage_Sales_Model_Order $order */
 $order = Mage::getModel('Mage_Sales_Model_Order');
 $order->setIncrementId('100000001')
     ->setSubtotal(100)
@@ -43,7 +51,8 @@ $order->setIncrementId('100000001')
     ->setCustomerIsGuest(true)
     ->setBillingAddress($billingAddress)
     ->setShippingAddress($shippingAddress)
+    ->setCustomerEmail('customer@null.com')
     ->setStoreId(Mage::app()->getStore()->getId())
-    ->setPayment($payment)
-;
+    ->addItem($orderItem)
+    ->setPayment($payment);
 $order->save();
diff --git a/dev/tests/integration/testsuite/Mage/Sitemap/Model/Resource/Catalog/ProductTest.php b/dev/tests/integration/testsuite/Mage/Sitemap/Model/Resource/Catalog/ProductTest.php
index 122fbb88acd..efac2a414ea 100644
--- a/dev/tests/integration/testsuite/Mage/Sitemap/Model/Resource/Catalog/ProductTest.php
+++ b/dev/tests/integration/testsuite/Mage/Sitemap/Model/Resource/Catalog/ProductTest.php
@@ -160,7 +160,6 @@ class Mage_Sitemap_Model_Resource_Catalog_ProductTest extends PHPUnit_Framework_
      * @param array $products
      * @param int $expectedCount
      * @param array $expectedKeys
-     * @return void
      */
     protected function _checkProductCollection(array $products, $expectedCount, array $expectedKeys)
     {
diff --git a/dev/tests/integration/testsuite/Mage/Tag/Model/Api/_files/tag.php b/dev/tests/integration/testsuite/Mage/Tag/Model/Api/_files/tag.php
new file mode 100644
index 00000000000..e91c9feedfb
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Tag/Model/Api/_files/tag.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Fixture for tag.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/** @var Mage_Tag_Model_Tag $tag */
+$tag = Mage::getModel('Mage_Tag_Model_Tag');
+$tag->setName('tag_name')->setStatus(Mage_Tag_Model_Tag::STATUS_APPROVED);
+$tag->save();
diff --git a/dev/tests/integration/testsuite/Mage/Tag/Model/ApiTest.php b/dev/tests/integration/testsuite/Mage/Tag/Model/ApiTest.php
new file mode 100644
index 00000000000..9312b2493b0
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Tag/Model/ApiTest.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ * Product tag API test.
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @magentoDataFixture Mage/Tag/Model/Api/_files/tag.php
+ */
+class Mage_Tag_Model_ApiTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Test info method.
+     */
+    public function testInfo()
+    {
+        $tagName = 'tag_name';
+        $tagStatus = Mage_Tag_Model_Tag::STATUS_APPROVED;
+        /** @var Mage_Tag_Model_Tag $tag */
+        $tag = Mage::getModel('Mage_Tag_Model_Tag');
+        $tagId = $tag->loadByName($tagName)->getTagId();
+        /** Retrieve tag info. */
+        $tagInfo = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductTagInfo',
+            array($tagId)
+        );
+        /** Assert response is not empty. */
+        $this->assertNotEmpty($tagInfo, 'Tag info is not retrieved.');
+        /** Assert base fields are present in the response. */
+        $expectedFields = array('status', 'name', 'base_popularity', 'products');
+        $missingFields = array_diff($expectedFields, array_keys($tagInfo));
+        $this->assertEmpty(
+            $missingFields,
+            sprintf("The following fields must be present in response: %s.", implode(', ', $missingFields))
+        );
+        /** Assert retrieved tag data is correct. */
+        $this->assertEquals($tagInfo->name, $tagName, 'Tag name is incorrect.');
+        $this->assertEquals($tagInfo->status, $tagStatus, 'Tag status is incorrect.');
+    }
+
+    /**
+     * Test update method.
+     */
+    public function testUpdate()
+    {
+        /** @var Mage_Tag_Model_Tag $tag */
+        $tagId = Mage::getModel('Mage_Tag_Model_Tag')->loadByName('tag_name')->getTagId();
+        $updateData = array('name' => 'new_tag_name', 'status' => Mage_Tag_Model_Tag::STATUS_DISABLED);
+        /** Update tag. */
+        $tagUpdateResponse = Magento_Test_Helper_Api::call(
+            $this,
+            'catalogProductTagUpdate',
+            array($tagId, (object)$updateData)
+        );
+        /** Check tag update result. */
+        $this->assertTrue((bool)$tagUpdateResponse, 'Tag update was unsuccessful.');
+        /** Assert updated fields. */
+        /** @var Mage_Tag_Model_Tag $updatedTag */
+        $updatedTag = Mage::getModel('Mage_Tag_Model_Tag')->loadByName($updateData['name']);
+        $this->assertNotEmpty($updatedTag->getTagId(), 'Tag name update was unsuccessful.');
+        $this->assertEquals($updateData['status'], $updatedTag->getStatus(), 'Tag status update was unsuccessful.');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Usa/Block/Adminhtml/Dhl/UnitofmeasureTest.php b/dev/tests/integration/testsuite/Mage/Usa/Block/Adminhtml/Dhl/UnitofmeasureTest.php
new file mode 100644
index 00000000000..552e6cf4f57
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Usa/Block/Adminhtml/Dhl/UnitofmeasureTest.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Usa_Block_Adminhtml_Dhl_UnitofmeasureTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @magentoAppIsolation enabled
+     */
+    public function testToHtml()
+    {
+        /** @var $layout Mage_Core_Model_Layout */
+        $layout = Mage::getSingleton('Mage_Core_Model_Layout', array('area' => 'adminhtml'));
+        /** @var $block Mage_Usa_Block_Adminhtml_Dhl_Unitofmeasure */
+        $block = $layout->createBlock('Mage_Usa_Block_Adminhtml_Dhl_Unitofmeasure');
+        $this->assertNotEmpty($block->toHtml());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/FormTestAbstract.php b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/FormTestAbstract.php
index e8d011c797f..4422ea35384 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/FormTestAbstract.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/FormTestAbstract.php
@@ -78,11 +78,11 @@ class Mage_Webapi_Block_Adminhtml_FormTestAbstract extends PHPUnit_Framework_Tes
     }
 
     /**
-     * Test _prepareForm method
+     * Test _prepareForm method.
      */
     public function testPrepareForm()
     {
-        // TODO Move to unit tests after MAGETWO-4015 complete
+        // TODO: Move to unit tests after MAGETWO-4015 complete.
         $this->assertEmpty($this->_block->getForm());
 
         $this->_urlBuilder->expects($this->once())
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/FormTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/FormTest.php
index a3b86fa4304..4cecb1c70a6 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/FormTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Block_Adminhtml_Role_Edit_Form block
+ * Test for Mage_Webapi_Block_Adminhtml_Role_Edit_Form block.
  *
  * Magento
  *
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/MainTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/MainTest.php
index 0efee579d1c..4af05990574 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/MainTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/MainTest.php
@@ -62,7 +62,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_MainTest extends PHPUnit_Framewo
     }
 
     /**
-     * Test _prepareForm method
+     * Test _prepareForm method.
      *
      * @dataProvider prepareFormDataProvider
      * @param Varien_Object $apiRole
@@ -70,7 +70,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_MainTest extends PHPUnit_Framewo
      */
     public function testPrepareForm($apiRole, array $formElements)
     {
-        // TODO Move to unit tests after MAGETWO-4015 complete
+        // TODO: Move to unit tests after MAGETWO-4015 complete
         $this->assertEmpty($this->_block->getForm());
 
         $this->_block->setApiRole($apiRole);
@@ -84,7 +84,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_MainTest extends PHPUnit_Framewo
         $elements = $fieldset->getElements();
         foreach ($formElements as $elementId) {
             $element = $elements->searchById($elementId);
-            $this->assertNotEmpty($element, "Element '$elementId' not found in form fieldset");
+            $this->assertNotEmpty($element, "Element '$elementId' is not found in form fieldset");
             $this->assertEquals($apiRole->getData($elementId), $element->getValue());
         }
     }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/ResourceTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/ResourceTest.php
index d392f5f7bb7..76d918f3ea2 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/ResourceTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/ResourceTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_Resource block
+ * Test for Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_Resource block.
  *
  * Magento
  *
@@ -84,7 +84,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_ResourceTest extends PHPUnit_Fra
     }
 
     /**
-     * Test _prepareForm method
+     * Test _prepareForm method.
      *
      * @dataProvider prepareFormDataProvider
      * @param array $originResTree
@@ -93,7 +93,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_ResourceTest extends PHPUnit_Fra
      */
     public function testPrepareForm($originResTree, $selectedRes, $expectedRes)
     {
-        // TODO Move to unit tests after MAGETWO-4015 complete
+        // TODO: Move to unit tests after MAGETWO-4015 complete.
         $apiRole = new Varien_Object(array(
             'role_id' => 1
         ));
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/FormTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/FormTest.php
index aa29ac04c83..d2c222801ab 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/FormTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Block_Adminhtml_User_Edit_Form block
+ * Test for Mage_Webapi_Block_Adminhtml_User_Edit_Form block.
  *
  * Magento
  *
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/Tab/MainTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/Tab/MainTest.php
index ac50ebd6857..0df9ce33c94 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/Tab/MainTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/Tab/MainTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Block_Adminhtml_User_Edit_Tab_Main block
+ * Test for Mage_Webapi_Block_Adminhtml_User_Edit_Tab_Main block.
  *
  * Magento
  *
@@ -61,7 +61,7 @@ class Mage_Webapi_Block_Adminhtml_User_Edit_Tab_MainTest extends PHPUnit_Framewo
     }
 
     /**
-     * Test _prepareForm method
+     * Test _prepareForm method.
      *
      * @dataProvider prepareFormDataProvider
      * @param Varien_Object $apiUser
@@ -69,7 +69,7 @@ class Mage_Webapi_Block_Adminhtml_User_Edit_Tab_MainTest extends PHPUnit_Framewo
      */
     public function testPrepareForm($apiUser, array $formElements)
     {
-        // TODO Move to unit tests after MAGETWO-4015 complete
+        // TODO: Move to unit tests after MAGETWO-4015 complete.
         $this->assertEmpty($this->_block->getForm());
 
         $this->_block->setApiUser($apiUser);
@@ -83,7 +83,7 @@ class Mage_Webapi_Block_Adminhtml_User_Edit_Tab_MainTest extends PHPUnit_Framewo
         $elements = $fieldset->getElements();
         foreach ($formElements as $elementId) {
             $element = $elements->searchById($elementId);
-            $this->assertNotEmpty($element, "Element '$elementId' not found in form fieldset");
+            $this->assertNotEmpty($element, "Element '$elementId' is not found in form fieldset");
             $this->assertEquals($apiUser->getData($elementId), $element->getValue());
         }
     }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/TabsTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/TabsTest.php
index c582c9d0053..d07cb7f778c 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/TabsTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/Edit/TabsTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Block_Adminhtml_User_Edit_Tabs block
+ * Test for Mage_Webapi_Block_Adminhtml_User_Edit_Tabs block.
  *
  * Magento
  *
@@ -55,11 +55,11 @@ class Mage_Webapi_Block_Adminhtml_User_Edit_TabsTest extends PHPUnit_Framework_T
     }
 
     /**
-     * Test _beforeToHtml method
+     * Test _beforeToHtml method.
      */
     public function testBeforeToHtml()
     {
-        // TODO Move to unit tests after MAGETWO-4015 complete
+        // TODO: Move to unit tests after MAGETWO-4015 complete.
         /** @var Mage_Webapi_Block_Adminhtml_User_Edit_Tab_Main $mainTabBlock */
         $mainTabBlock = $this->_layout->addBlock(
             'Mage_Core_Block_Text',
@@ -107,7 +107,7 @@ class Mage_Webapi_Block_Adminhtml_User_Edit_TabsTest extends PHPUnit_Framework_T
     }
 
     /**
-     * Get protected _tabs property of Mage_Backend_Block_Widget_Tabs block
+     * Get protected _tabs property of Mage_Backend_Block_Widget_Tabs block.
      *
      * @param Mage_Backend_Block_Widget_Tabs $tabs
      * @return array
@@ -124,7 +124,7 @@ class Mage_Webapi_Block_Adminhtml_User_Edit_TabsTest extends PHPUnit_Framework_T
             $this->fail('Cannot get tabs value');
 
         }
-        $this->assertInternalType('array', $result, 'Tabs value expected to be an array');
+        $this->assertInternalType('array', $result, 'Tabs value is expected to be an array');
         return $result;
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/EditTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/EditTest.php
index 4179520f747..a98babbaa95 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/EditTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Block/Adminhtml/User/EditTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Block_Adminhtml_User_Edit block
+ * Test for Mage_Webapi_Block_Adminhtml_User_Edit block.
  *
  * Magento
  *
@@ -41,7 +41,7 @@ class Mage_Webapi_Block_Adminhtml_User_EditTest extends PHPUnit_Framework_TestCa
     protected $_block;
 
     /**
-     * Initialize block
+     * Initialize block.
      */
     protected function setUp()
     {
@@ -51,7 +51,7 @@ class Mage_Webapi_Block_Adminhtml_User_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Clear clock
+     * Clear block.
      */
     protected function tearDown()
     {
@@ -59,11 +59,11 @@ class Mage_Webapi_Block_Adminhtml_User_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Test _beforeToHtml method
+     * Test _beforeToHtml method.
      */
     public function testBeforeToHtml()
     {
-        // TODO Move to unit tests after MAGETWO-4015 complete
+        // TODO: Move to unit tests after MAGETWO-4015 complete.
         $apiUser = new Varien_Object();
         $this->_block->setApiUser($apiUser);
         $this->_block->toHtml();
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Helper/ConfigTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Helper/ConfigTest.php
index 5b9399fefa7..049cb051766 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Helper/ConfigTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Helper/ConfigTest.php
@@ -175,7 +175,7 @@ class Mage_Webapi_Helper_ConfigTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(
             $expectedParts,
             $this->_helper->getResourceNameParts($className),
-            "Resource parts for rest route were identified incorrectly."
+            "Resource parts for REST route were identified incorrectly."
         );
     }
 
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Helper/DataTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Helper/DataTest.php
index dd878c4534e..6def23b3b88 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Helper/DataTest.php
@@ -29,6 +29,7 @@
  */
 include_once __DIR__ . '/../_files/data_types/Customer/AddressData.php';
 include_once __DIR__ . '/../_files/data_types/CustomerData.php';
+include_once __DIR__ . '/../_files/autodiscovery/resource_class_fixture.php';
 include_once __DIR__ . '/../_files/autodiscovery/subresource_class_fixture.php';
 /**#@-*/
 
@@ -59,7 +60,12 @@ class Mage_Webapi_Helper_DataTest extends PHPUnit_Framework_TestCase
             /** Prepare arguments for SUT constructor. */
             $pathToFixtures = __DIR__ . '/../_files/autodiscovery';
             /** @var Mage_Webapi_Model_Config_Reader_Soap $reader */
-            $reader = $objectManager->get('Mage_Webapi_Model_Config_Reader_Soap');
+            $reader = $objectManager->get(
+                'Mage_Webapi_Model_Config_Reader_Soap',
+                array(
+                    'cache' => $this->getMock('Mage_Core_Model_Cache', array(), array(), '', false)
+                )
+            );
             $reader->setDirectoryScanner(new Zend\Code\Scanner\DirectoryScanner($pathToFixtures));
             /** Initialize SUT. */
             self::$_apiConfig = $objectManager->create('Mage_Webapi_Model_Config_Soap', array('reader' => $reader));
@@ -111,49 +117,49 @@ class Mage_Webapi_Helper_DataTest extends PHPUnit_Framework_TestCase
         $optionalNotSetOutput->password = "123123q";
 
         return array(
-            // Test valid data that does not need transformations
+            // Test valid data that does not need transformations.
             array(
                 'Vendor_Module_Controller_Webapi_Resource_Subresource',
                 'createV1',
                 array('param1' => 1, 'param2' => 2, 'param3' => array($customerDataObject), 'param4' => 4),
                 array('param1' => 1, 'param2' => 2, 'param3' => array($customerDataObject), 'param4' => 4),
             ),
-            // Test filtering unnecessary data
+            // Test filtering unnecessary data.
             array(
                 'Vendor_Module_Controller_Webapi_Resource_Subresource',
                 'createV2',
                 array('param1' => 1, 'param2' => 2, 'param3' => array($customerDataObject), 'param4' => 4),
                 array('param1' => 1, 'param2' => 2),
             ),
-            // Test parameters sorting
+            // Test parameters sorting.
             array(
                 'Vendor_Module_Controller_Webapi_Resource_Subresource',
                 'createV1',
                 array('param4' => 4, 'param2' => 2, 'param3' => array($customerDataObject), 'param1' => 1),
                 array('param1' => 1, 'param2' => 2, 'param3' => array($customerDataObject), 'param4' => 4),
             ),
-            // Test default values setting
+            // Test default values setting.
             array(
                 'Vendor_Module_Controller_Webapi_Resource_Subresource',
                 'createV1',
                 array('param1' => 1, 'param2' => 2),
                 array('param1' => 1, 'param2' => 2, 'param3' => array(), 'param4' => 'default_value'),
             ),
-            // Test with object instead of class name
+            // Test with object instead of class name.
             array(
                 new Vendor_Module_Controller_Webapi_Resource_Subresource(),
                 'createV2',
                 array('param2' => 2, 'param1' => 1),
                 array('param1' => 1, 'param2' => 2),
             ),
-            // Test passing of partially formatted objects
+            // Test passing of partially formatted objects.
             array(
                 new Vendor_Module_Controller_Webapi_Resource_Subresource(),
                 'updateV1',
                 array('param1' => 1, 'param2' => get_object_vars($customerDataObject)),
                 array('param1' => 1, 'param2' => $customerDataObject),
             ),
-            // Test passing of complex type parameter with optional field not set
+            // Test passing of complex type parameter with optional field not set.
             array(
                 new Vendor_Module_Controller_Webapi_Resource_Subresource(),
                 'updateV1',
@@ -225,7 +231,7 @@ class Mage_Webapi_Helper_DataTest extends PHPUnit_Framework_TestCase
             'email' => "test_email@example.com"
         );
         return array(
-            // Test exception in case of missing required parameter
+            // Test exception in case of missing required parameter.
             array(
                 'Vendor_Module_Controller_Webapi_Resource_Subresource',
                 'createV1',
@@ -233,7 +239,7 @@ class Mage_Webapi_Helper_DataTest extends PHPUnit_Framework_TestCase
                 'Mage_Webapi_Exception',
                 'Required parameter "param1" is missing.'
             ),
-            // Test passing of complex type parameter with not specified required field
+            // Test passing of complex type parameter with not specified required field.
             array(
                 new Vendor_Module_Controller_Webapi_Resource_Subresource(),
                 'updateV1',
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/RoleTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/RoleTest.php
index 76a426447fa..a491dd257ce 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/RoleTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/RoleTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Model_Acl_Role model
+ * Test for Mage_Webapi_Model_Acl_Role model.
  *
  * Magento
  *
@@ -37,7 +37,7 @@ class Mage_Webapi_Model_Acl_RoleTest extends PHPUnit_Framework_TestCase
     protected $_model;
 
     /**
-     * Initialize model
+     * Initialize model.
      */
     protected function setUp()
     {
@@ -46,7 +46,7 @@ class Mage_Webapi_Model_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Cleanup model instance
+     * Cleanup model instance.
      */
     protected function tearDown()
     {
@@ -54,7 +54,7 @@ class Mage_Webapi_Model_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test Web API Role CRUD
+     * Test Web API Role CRUD.
      */
     public function testCRUD()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/RuleTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/RuleTest.php
index ffbc421e402..b10fb7f3cd0 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/RuleTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/RuleTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Model_Acl_Rule model
+ * Test for Mage_Webapi_Model_Acl_Rule model.
  *
  * Magento
  *
@@ -49,7 +49,7 @@ class Mage_Webapi_Model_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Cleanup model instance
+     * Cleanup model instance.
      */
     protected function tearDown()
     {
@@ -57,7 +57,7 @@ class Mage_Webapi_Model_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test Web API Rule CRUD
+     * Test Web API Role CRUD.
      */
     public function testCRUD()
     {
@@ -72,7 +72,7 @@ class Mage_Webapi_Model_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test method Mage_Webapi_Model_Acl_Rule::saveResources()
+     * Test Mage_Webapi_Model_Acl_Rule::saveResources() method.
      */
     public function testSaveResources()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/UserTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/UserTest.php
index c5cc69f88ae..c347ebb66c5 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/UserTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Acl/UserTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Model_Acl_User model
+ * Test for Mage_Webapi_Model_Acl_User model.
  *
  * Magento
  *
@@ -42,7 +42,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     protected $_roleFactory;
 
     /**
-     * Initialize model
+     * Initialize model.
      */
     protected function setUp()
     {
@@ -52,7 +52,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Cleanup model instance
+     * Cleanup model instance.
      */
     protected function tearDown()
     {
@@ -60,7 +60,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test Web API User CRUD
+     * Test Web API User CRUD.
      */
     public function testCRUD()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/Reader/Rest/RouteGeneratorTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/Reader/Rest/RouteGeneratorTest.php
index a3abc195eed..5f88e81087a 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/Reader/Rest/RouteGeneratorTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/Reader/Rest/RouteGeneratorTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * File with unit tests for REST routes generator class: Mage_Webapi_Model_Config_Reader_Rest_RouteGenerator
+ * File with unit tests for REST routes generator class: Mage_Webapi_Model_Config_Reader_Rest_RouteGenerator.
  *
  * Magento
  *
@@ -204,7 +204,7 @@ class Mage_Webapi_Model_Config_Reader_Rest_RouteGeneratorTest extends PHPUnit_Fr
     }
 
     /**
-     * Check if list of REST routes are equal.
+     * Check if list of REST routes is equal.
      *
      * @param array $expectedRoutes
      * @param array $actualRoutes
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/RestTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/RestTest.php
index a6e389e4a63..473e39df392 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/RestTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/RestTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * File with unit tests for API configuration class: Mage_Webapi_Model_Config_Rest
+ * File with unit tests for API configuration class: Mage_Webapi_Model_Config_Rest.
  *
  * Magento
  *
@@ -37,18 +37,28 @@ require_once __DIR__ . '/../_files/resource_with_invalid_name.php';
 
 
 /**
- * Test of API configuration class: Mage_Webapi_Model_Config
+ * Test of API configuration class: Mage_Webapi_Model_Config.
  */
 class Mage_Webapi_Model_Config_RestTest extends PHPUnit_Framework_TestCase
 {
+    const WEBAPI_AREA_FRONT_NAME = 'webapi';
+
     /**
      * @var Mage_Webapi_Model_Config_Rest
      */
     protected static $_apiConfig;
 
+    /**
+     * App mock clone usage helps to improve performance. It is required because mock will be removed in tear down.
+     *
+     * @var Mage_Core_Model_App
+     */
+    protected static $_appClone;
+
     public static function tearDownAfterClass()
     {
         self::$_apiConfig = null;
+        self::$_appClone = null;
         parent::tearDownAfterClass();
     }
 
@@ -96,9 +106,9 @@ class Mage_Webapi_Model_Config_RestTest extends PHPUnit_Framework_TestCase
         /**
          * Vendor_Module_Controller_Webapi_Resource fixture contains two methods getV2 and deleteV3 that have
          * different names of ID param.
-         * If there will be two different routes generated for these methods with different ID param names,
+         * If there are two different routes generated for these methods with different ID param names,
          * it will be impossible to identify which route should be used as they both will match the same requests.
-         * E.g. DELETE /resource/:deleteId and GET /resource/:getId will match same requests.
+         * E.g. DELETE /resource/:deleteId and GET /resource/:getId will match the same requests.
          */
         $this->assertNotCount(
             $expectedRoutesCount + 1,
@@ -106,7 +116,7 @@ class Mage_Webapi_Model_Config_RestTest extends PHPUnit_Framework_TestCase
             "Some resource methods seem to have different routes, in case when should have the same ones."
         );
 
-        $this->assertCount($expectedRoutesCount, $actualRoutes, "Routes quantity does not equal to expected one.");
+        $this->assertCount($expectedRoutesCount, $actualRoutes, "Routes quantity is not equal to expected one.");
         /** @var $actualRoute Mage_Webapi_Controller_Router_Route_Rest */
         foreach ($actualRoutes as $actualRoute) {
             $this->assertInstanceOf('Mage_Webapi_Controller_Router_Route_Rest', $actualRoute);
@@ -161,12 +171,22 @@ class Mage_Webapi_Model_Config_RestTest extends PHPUnit_Framework_TestCase
         /** Prepare arguments for SUT constructor. */
         /** @var Mage_Core_Model_Cache $cache */
         $cache = $this->getMockBuilder('Mage_Core_Model_Cache')->disableOriginalConstructor()->getMock();
+        $configMock = $this->getMockBuilder('Mage_Core_Model_Config')->disableOriginalConstructor()->getMock();
+        $configMock->expects($this->any())->method('getAreaFrontName')->will(
+            $this->returnValue(self::WEBAPI_AREA_FRONT_NAME)
+        );
+        $appMock = $this->getMockBuilder('Mage_Core_Model_App')->disableOriginalConstructor()->getMock();
+        $appMock->expects($this->any())->method('getConfig')->will($this->returnValue($configMock));
+        self::$_appClone = clone $appMock;
         /** @var Mage_Webapi_Model_Config_Reader_Rest $reader */
         $reader = $objectManager->get('Mage_Webapi_Model_Config_Reader_Rest', array('cache' => $cache));
         $reader->setDirectoryScanner(new Zend\Code\Scanner\DirectoryScanner($pathToResources));
 
         /** Initialize SUT. */
-        $apiConfig = $objectManager->create('Mage_Webapi_Model_Config_Rest', array('reader' => $reader));
+        $apiConfig = $objectManager->create(
+            'Mage_Webapi_Model_Config_Rest',
+            array('reader' => $reader, 'application' => self::$_appClone)
+        );
         return $apiConfig;
     }
 
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/Soap/DataTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/Soap/DataTest.php
index c2ea7457eec..b6c65bcf2e0 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/Soap/DataTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/Soap/DataTest.php
@@ -44,7 +44,7 @@ class Mage_Webapi_Model_Config_Soap_DataTest extends PHPUnit_Framework_TestCase
     protected $_config;
 
     /**
-     * Set up config with fixture controllers directory scanner
+     * Set up config with fixture controllers directory scanner.
      */
     protected function setUp()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/SoapTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/SoapTest.php
index 07d0d2e50df..a53f1e51f91 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/SoapTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Config/SoapTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * File with unit tests for API configuration class: Mage_Webapi_Model_Config_Soap
+ * File with unit tests for API configuration class: Mage_Webapi_Model_Config_Soap.
  *
  * Magento
  *
@@ -42,7 +42,7 @@ require_once __DIR__ . '/../_files/autodiscovery/reference_to_invalid_type/class
 /**#@-*/
 
 /**
- * Test of API configuration class: Mage_Webapi_Model_Config
+ * Test of API configuration class: Mage_Webapi_Model_Config.
  */
 class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
 {
@@ -137,8 +137,13 @@ class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
     public function dataProviderTestGetResourceNameByOperationNegative()
     {
         return array(
-            array('customerUpdate', 'v1', false, "In case when resource not found 'false' is expected."),
-            array('vendorModuleResourceCreate', 'v100', false, "In case when version not found 'false' is expected."),
+            array('customerUpdate', 'v1', false, "In case when resource is not found, 'false' is expected."),
+            array(
+                'vendorModuleResourceCreate',
+                'v100',
+                false,
+                "In case when version is not found, 'false' is expected."
+            ),
         );
     }
 
@@ -160,7 +165,7 @@ class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
     {
         return array(
             array('customerMultiDeleteExcessiveSuffix', 'v2', 'Excessive suffix is ignored.'),
-            array('customerInvalid', 'v1', "In case when operation not found 'false' is expected."),
+            array('customerInvalid', 'v1', "In case when operation is not found, 'false' is expected."),
         );
     }
 
@@ -189,7 +194,7 @@ class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
                 'vendorModuleResourceMultiUpdate',
                 'v2',
                 'multiUpdate',
-                'Compound method names seem be be identified incorrectly or version processing is broken.'
+                'Compound method names seem to be identified incorrectly or version processing is broken.'
             ),
             array(
                 'vendorModuleResourceSubresourceMultiDelete',
@@ -197,7 +202,12 @@ class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
                 'multiDelete',
                 "If version is not set - no check must be performed for operation existence in resource."
             ),
-            array('vendorModuleResourceUpdate', 'v100', false, "In case when version not found 'false' is expected."),
+            array(
+                'vendorModuleResourceUpdate',
+                'v100',
+                false,
+                "In case when version is not found, 'false' is expected."
+            ),
         );
     }
 
@@ -219,7 +229,7 @@ class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
     {
         return array(
             array('vendorModuleResourceMultiUpdateExcessiveSuffix', 'v2', 'Excessive suffix is ignored.'),
-            array('vendorModuleResourceInvalid', 'v1', "In case when operation not found 'false' is expected."),
+            array('vendorModuleResourceInvalid', 'v1', "In case when operation is not found, 'false' is expected."),
         );
     }
 
@@ -247,7 +257,7 @@ class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
     {
         return array(
             array('customerMultiDeleteExcessiveSuffix', 'Excessive suffix is ignored.'),
-            array('customerInvalid', "In case when operation not found 'false' is expected."),
+            array('customerInvalid', "In case when operation is not found, 'false' is expected."),
         );
     }
 
@@ -270,7 +280,7 @@ class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(
             $expectedMaxVersion,
             $this->_getModel()->getResourceMaxVersion($resourceName),
-            "Resource Maximum available version was identified incorrectly."
+            "Resource maximum available version was identified incorrectly."
         );
     }
 
@@ -457,7 +467,7 @@ class Mage_Webapi_Model_Config_SoapTest extends PHPUnit_Framework_TestCase
                 ),
                 '@apiDeprecated vendorModuleResource::listV3'
             ),
-            array('vendorModuleResource', 'list', 3, false, 'No policy defined.'),
+            array('vendorModuleResource', 'list', 3, false, 'No policy is defined.'),
             array(
                 'vendorModuleResource',
                 'delete',
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Resource/Acl/RoleTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Resource/Acl/RoleTest.php
index 93d8aa38aef..d40957ab062 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Resource/Acl/RoleTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Resource/Acl/RoleTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Model_Resource_Acl_Role
+ * Test for Mage_Webapi_Model_Resource_Acl_Role.
  *
  * Magento
  *
@@ -26,7 +26,7 @@
 class Mage_Webapi_Model_Resource_Acl_RoleTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * Test for Mage_Webapi_Model_Resource_Acl_Role::getRolesIds()
+     * Test for Mage_Webapi_Model_Resource_Acl_Role::getRolesIds().
      *
      * @magentoDataFixture Mage/Webapi/_files/role.php
      * @magentoDataFixture Mage/Webapi/_files/role_with_rule.php
@@ -47,7 +47,7 @@ class Mage_Webapi_Model_Resource_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for Mage_Webapi_Model_Resource_Acl_Role::getRolesList()
+     * Test for Mage_Webapi_Model_Resource_Acl_Role::getRolesList().
      *
      * @magentoDataFixture Mage/Webapi/_files/role.php
      * @magentoDataFixture Mage/Webapi/_files/role_with_rule.php
@@ -66,7 +66,7 @@ class Mage_Webapi_Model_Resource_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for Mage_Webapi_Model_Resource_Acl_Role::_initUniqueFields()
+     * Test for Mage_Webapi_Model_Resource_Acl_Role::_initUniqueFields().
      *
      * @expectedException Mage_Core_Exception
      * @expectedExceptionMessage Role Name already exists.
@@ -91,7 +91,7 @@ class Mage_Webapi_Model_Resource_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for Mage_Webapi_Model_Resource_Acl_Role::delete()
+     * Test for Mage_Webapi_Model_Resource_Acl_Role::delete().
      *
      * @magentoDataFixture Mage/Webapi/_files/user_with_role.php
      */
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Resource/Acl/RuleTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Resource/Acl/RuleTest.php
index c01442b937f..d16419e7e65 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Resource/Acl/RuleTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Resource/Acl/RuleTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test for Mage_Webapi_Model_Resource_Acl_Rule
+ * Test for Mage_Webapi_Model_Resource_Acl_Rule.
  *
  * Magento
  *
@@ -49,7 +49,7 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for Mage_Webapi_Model_Resource_Acl_Role::getRolesIds()
+     * Test for Mage_Webapi_Model_Resource_Acl_Role::getRolesIds().
      */
     public function testGetRuleList()
     {
@@ -63,7 +63,7 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for Mage_Webapi_Model_Resource_Acl_Role::getResourceIdsByRole()
+     * Test for Mage_Webapi_Model_Resource_Acl_Role::getResourceIdsByRole().
      */
     public function testGetResourceIdsByRole()
     {
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/AutoDiscoverTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/AutoDiscoverTest.php
index 35863f1542b..032f01ae7fc 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/AutoDiscoverTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/AutoDiscoverTest.php
@@ -77,7 +77,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     protected $_xpath;
 
     /**
-     * Set up config with fixture controllers directory scanner
+     * Set up config with fixture controllers directory scanner.
      */
     protected function setUp()
     {
@@ -87,7 +87,12 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
         $app = $this->getMockBuilder('Mage_Core_Model_App')->disableOriginalConstructor()->getMock();
         $objectManager = new Magento_Test_ObjectManager();
         $this->_helper = $objectManager->get('Mage_Webapi_Helper_Config');
-        $reader = $objectManager->get('Mage_Webapi_Model_Config_Reader_Soap');
+        $reader = $objectManager->get(
+            'Mage_Webapi_Model_Config_Reader_Soap',
+            array(
+                'cache' => $this->getMock('Mage_Core_Model_Cache', array(), array(), '', false)
+            )
+        );
         $reader->setDirectoryScanner($directoryScanner);
         $this->_config = new Mage_Webapi_Model_Config_Soap($reader, $this->_helper, $app);
         $objectManager->addSharedInstance($this->_config, 'Mage_Webapi_Model_Config_Soap');
@@ -116,7 +121,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
      * Test WSDL operations Generation.
      * Generate WSDL XML using AutoDiscover and prepared config.
      * Walk through all methods from "vendorModuleB resource" (_files/controllers/AutoDiscover/ModuleBController.php)
-     * Assert that service, portType and binding has been generated correctly for resource.
+     * Assert that service, portType and binding have been generated correctly for resource.
      * Assert that each method from controller has generated operations in portType and binding nodes.
      * Assert that each method has input and output messages and complexTypes generated correctly.
      */
@@ -274,7 +279,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert docInstructions appinfo node and it's subnodes.
+     * Assert docInstructions appinfo node and its subnodes.
      *
      * @param DOMElement $appInfoNode
      * @param array $appInfoData
@@ -297,7 +302,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert 'seeLink' annotation node and it's subnodes.
+     * Assert 'seeLink' annotation node and its subnodes.
      *
      * @param DOMElement $appInfoNode
      * @param array $appInfoData
@@ -324,7 +329,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert 'callInfo' annotation node and it's subnodes.
+     * Assert 'callInfo' annotation node and its subnodes.
      *
      * @param DOMElement $appInfoNode
      * @param array $appInfoData
@@ -360,7 +365,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
             $conditionNode = $this->_xpath->query("{$infNs}:{$direction}[text()='{$condition}']", $callNode->parentNode)
                 ->item(0);
             $this->assertNotNull($conditionNode,
-                sprintf('"%s" node with value "%s" not found for callName "%s" in element "%s"', $direction,
+                sprintf('"%s" node with value "%s" was not found for callName "%s" in element "%s"', $direction,
                     $condition, $callName, $elementName));
         }
     }
@@ -384,7 +389,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert operation message (input/output) and that message node is present in WSDL
+     * Assert operation message (input/output) and that message node is present in WSDL.
      *
      * @param DOMElement $operationMessage
      * @param $methodName
@@ -412,16 +417,16 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
         /** @var DOMElement $message */
         $expression = "//{$wsdlNs}:message[@name='{$messageName}']";
         $message = $this->_xpath->query($expression)->item(0);
-        $this->assertNotNull($message, sprintf('Message "%s" not found in WSDL.', $messageName));
+        $this->assertNotNull($message, sprintf('Message "%s" is not found in WSDL.', $messageName));
         $partXpath = "{$wsdlNs}:part[@element='{$tns}:{$messageName}']";
         $messagePart = $this->_xpath->query($partXpath, $message)->item(0);
-        $this->assertNotNull($messagePart, sprintf('Message part not found in "%s".', $messageName));
+        $this->assertNotNull($messagePart, sprintf('Message part is not found in "%s".', $messageName));
 
         return $messageComplexType;
     }
 
     /**
-     * Assert operation is present in portType node and return it.
+     * Assert that operation is present in portType node and return it.
      *
      * @param $operationName
      * @param DOMElement $portType
@@ -438,7 +443,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert operation is present in binding node.
+     * Assert that operation is present in binding node.
      *
      * @param string $operationName
      * @param DOMElement $binding
@@ -453,7 +458,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert binding node is present and return it.
+     * Assert that binding node is present and return it.
      *
      * @return DOMElement
      */
@@ -473,7 +478,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
         /** @var DOMElement $soapBinding */
         $soapBinding = $binding->getElementsByTagNameNS(Wsdl::SOAP_12_NS_URI, 'binding')
             ->item(0);
-        $this->assertNotNull($soapBinding, sprintf('Missing soap binding in "%s"', $bindingName));
+        $this->assertNotNull($soapBinding, sprintf('SOAP binding in "%s" is missing', $bindingName));
         $this->assertTrue($soapBinding->hasAttribute('style'));
         $this->assertEquals('document', $soapBinding->getAttribute('style'));
 
@@ -481,7 +486,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert port type node is present and return it.
+     * Assert that portType node is present and return it.
      *
      * @return DOMElement
      */
@@ -499,7 +504,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert port node is present within service node.
+     * Assert that port node is present within service node.
      *
      * @param DOMElement $service
      */
@@ -507,7 +512,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     {
         /** @var DOMElement $port */
         $port = $service->getElementsByTagName('port')->item(0);
-        $this->assertNotNull($port, 'port node not found within service node.');
+        $this->assertNotNull($port, 'port node is not found within service node.');
         $this->assertTrue($port->hasAttribute('name'));
         $this->assertEquals($this->_autoDiscover->getPortName($this->_resourceName), $port->getAttribute('name'));
         $bindingName = $this->_autoDiscover->getBindingName($this->_resourceName);
@@ -515,7 +520,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Assert service node is present in xml.
+     * Assert that service node is present in XML.
      *
      * @return DOMElement
      */
@@ -523,7 +528,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     {
         /** @var DOMElement $service */
         $service = $this->_dom->getElementsByTagNameNS(Wsdl::WSDL_NS_URI, 'service')->item(0);
-        $this->assertNotNull($service, 'service node not found in WSDL.');
+        $this->assertNotNull($service, 'service node is not found in WSDL.');
         $this->assertTrue($service->hasAttribute('name'));
         $this->assertEquals($this->_autoDiscover->getServiceName($this->_resourceName), $service->getAttribute('name'));
 
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/Security/UsernameTokenTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/Security/UsernameTokenTest.php
index df1184f2a08..112cfe7bb6e 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/Security/UsernameTokenTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/Security/UsernameTokenTest.php
@@ -35,8 +35,8 @@ class Mage_Webapi_Model_Soap_Security_UsernameTokenTest extends PHPUnit_Framewor
      */
     protected $_objectManager;
 
-    /** @var Mage_Webapi_Model_Acl_User_Factory */
-    protected $_userFactory;
+    /** @var Mage_Webapi_Model_Acl_User */
+    protected $_user;
 
     /**
      * Set up object manager and user factory.
@@ -44,7 +44,13 @@ class Mage_Webapi_Model_Soap_Security_UsernameTokenTest extends PHPUnit_Framewor
     protected function setUp()
     {
         $this->_objectManager = new Magento_Test_ObjectManager();
-        $this->_userFactory = new Mage_Webapi_Model_Acl_User_Factory($this->_objectManager);
+        $this->_objectManager->addSharedInstance(
+            Mage::getObjectManager()->get('Mage_Core_Model_Dir'),
+            'Mage_Core_Model_Dir'
+        );
+        $userFactory = new Mage_Webapi_Model_Acl_User_Factory($this->_objectManager);
+        $this->_user = $userFactory->create();
+        $this->_user->load('test_username', 'api_key');
     }
 
     /**
@@ -53,16 +59,14 @@ class Mage_Webapi_Model_Soap_Security_UsernameTokenTest extends PHPUnit_Framewor
     protected function tearDown()
     {
         unset($this->_objectManager);
-        unset($this->_userFactory);
+        unset($this->_user);
     }
 
     /**
-     * Test positive authenticate with text password type.
+     * Test positive authentication with text password type.
      */
     public function testAuthenticatePasswordText()
     {
-        $user = $this->_userFactory->create();
-        $user->load('test_username', 'api_key');
         /** @var Mage_Webapi_Model_Soap_Security_UsernameToken $usernameToken */
         $usernameToken = $this->_objectManager->create('Mage_Webapi_Model_Soap_Security_UsernameToken', array(
             'passwordType' => Mage_Webapi_Model_Soap_Security_UsernameToken::PASSWORD_TYPE_TEXT
@@ -70,26 +74,25 @@ class Mage_Webapi_Model_Soap_Security_UsernameTokenTest extends PHPUnit_Framewor
 
         $created = date('c');
         $nonce = base64_encode(mt_rand());
-        $authenticatedUser = $usernameToken->authenticate($user->getApiKey(), $user->getSecret(), $created, $nonce);
-        $this->assertEquals($user->getRoleId(), $authenticatedUser->getRoleId());
+        $authenticatedUser = $usernameToken->authenticate($this->_user->getApiKey(), $this->_user->getSecret(),
+            $created, $nonce);
+        $this->assertEquals($this->_user->getRoleId(), $authenticatedUser->getRoleId());
     }
 
     /**
-     * Test positive authenticate with digest password type
+     * Test positive authentication with digest password type.
      */
     public function testAuthenticatePasswordDigest()
     {
-        $user = $this->_userFactory->create();
-        $user->load('test_username', 'api_key');
         /** @var Mage_Webapi_Model_Soap_Security_UsernameToken $usernameToken */
         $usernameToken = $this->_objectManager->create('Mage_Webapi_Model_Soap_Security_UsernameToken');
 
         $created = date('c');
         $nonce = mt_rand();
-        $password = base64_encode(hash('sha1', $nonce . $created . $user->getSecret(), true));
+        $password = base64_encode(hash('sha1', $nonce . $created . $this->_user->getSecret(), true));
         $nonce = base64_encode($nonce);
-        $authenticatedUser = $usernameToken->authenticate($user->getApiKey(), $password, $created, $nonce);
-        $this->assertEquals($user->getRoleId(), $authenticatedUser->getRoleId());
+        $authenticatedUser = $usernameToken->authenticate($this->_user->getApiKey(), $password, $created, $nonce);
+        $this->assertEquals($this->_user->getRoleId(), $authenticatedUser->getRoleId());
     }
 
     /**
@@ -99,18 +102,16 @@ class Mage_Webapi_Model_Soap_Security_UsernameTokenTest extends PHPUnit_Framewor
      */
     public function testAuthenticateWithNonceUsed()
     {
-        $user = $this->_userFactory->create();
-        $user->load('test_username', 'api_key');
         /** @var Mage_Webapi_Model_Soap_Security_UsernameToken $usernameToken */
         $usernameToken = $this->_objectManager->create('Mage_Webapi_Model_Soap_Security_UsernameToken');
 
         $created = date('c');
         $nonce = mt_rand();
-        $password = base64_encode(hash('sha1', $nonce . $created . $user->getSecret(), true));
+        $password = base64_encode(hash('sha1', $nonce . $created . $this->_user->getSecret(), true));
         $nonce = base64_encode($nonce);
-        $authenticatedUser = $usernameToken->authenticate($user->getApiKey(), $password, $created, $nonce);
-        $this->assertEquals($user, $authenticatedUser);
+        $authenticatedUser = $usernameToken->authenticate($this->_user->getApiKey(), $password, $created, $nonce);
+        $this->assertEquals($this->_user, $authenticatedUser);
         // Try to authenticate with the same nonce and timestamp
-        $usernameToken->authenticate($user->getApiKey(), $password, $created, $nonce);
+        $usernameToken->authenticate($this->_user->getApiKey(), $password, $created, $nonce);
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/ServerTest.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/ServerTest.php
index 928bfe7f8bd..091d243b9f3 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/ServerTest.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/Soap/ServerTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test Soap server model.
+ * Test SOAP server model.
  *
  * Magento
  *
@@ -61,38 +61,38 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test Soap server construction with WSDL cache enabling.
+     * Test SOAP server construction with WSDL cache enabling.
      */
     public function testConstructEnableWsdlCache()
     {
         /** Mock getConfig method to return true. */
         $this->_storeMock->expects($this->any())->method('getConfig')->will($this->returnValue(true));
-        /** Create Soap server object. */
+        /** Create SOAP server object. */
         $server = new Mage_Webapi_Model_Soap_Server(
             $this->_applicationMock,
             $this->_requestMock,
             $this->_domDocumentFactory
         );
         $server->initWsdlCache();
-        /** Assert soap wsdl caching option was enabled after soap server initialization. */
+        /** Assert that SOAP WSDL caching option was enabled after SOAP server initialization. */
         $this->assertTrue((bool)ini_get('soap.wsdl_cache_enabled'), 'WSDL caching was not enabled.');
     }
 
     /**
-     * Test Soap server construction with WSDL cache disabling.
+     * Test SOAP server construction with WSDL cache disabling.
      */
     public function testConstructDisableWsdlCache()
     {
         /** Mock getConfig method to return false. */
         $this->_storeMock->expects($this->any())->method('getConfig')->will($this->returnValue(false));
-        /** Create Soap server object. */
+        /** Create SOAP server object. */
         $server = new Mage_Webapi_Model_Soap_Server(
             $this->_applicationMock,
             $this->_requestMock,
             $this->_domDocumentFactory
         );
         $server->initWsdlCache();
-        /** Assert soap wsdl caching option was disabled after soap server initialization. */
+        /** Assert that SOAP WSDL caching option was disabled after SOAP server initialization. */
         $this->assertFalse((bool)ini_get('soap.wsdl_cache_enabled'), 'WSDL caching was not disabled.');
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_property_description/class.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_property_description/class.php
index c19be66f841..552532e7a0c 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_property_description/class.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_property_description/class.php
@@ -31,6 +31,6 @@ class Vendor_Module_Controller_Webapi_Empty_Property_Description
      */
     public function createV1($data)
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_var_tags/class.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_var_tags/class.php
index d0ea0828715..ce5da5bc2ed 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_var_tags/class.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_var_tags/class.php
@@ -31,6 +31,6 @@ class Vendor_Module_Controller_Webapi_Empty_Var_Tag
      */
     public function createV1($data)
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_var_tags/data_type.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_var_tags/data_type.php
index 116005c9984..822511c2dd3 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_var_tags/data_type.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/empty_var_tags/data_type.php
@@ -26,7 +26,7 @@
 class Vendor_Module_Model_Webapi_Property_Without_Var
 {
     /**
-     * Property without var tag
+     * Property without var tag.
      */
     public $propertyWithoutVar;
 
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/invalid_deprecation_policy/class.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/invalid_deprecation_policy/class.php
index d9183b141a6..50267f1e169 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/invalid_deprecation_policy/class.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/invalid_deprecation_policy/class.php
@@ -31,7 +31,7 @@ class Invalid_Deprecation_Controller_Webapi_Policy
      */
     public function getV1()
     {
-        // Body was intentionally left empty
+        // Body was intentionally left empty.
     }
 }
 
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/no_resources/class.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/no_resources/class.php
index 7d542a29406..e41d5994814 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/no_resources/class.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/no_resources/class.php
@@ -31,6 +31,6 @@ class Invalid_Resource_Name
      */
     public function createV1($data)
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/reference_to_invalid_type/class.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/reference_to_invalid_type/class.php
index d0da23c5f47..69557f436f0 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/reference_to_invalid_type/class.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/reference_to_invalid_type/class.php
@@ -31,6 +31,6 @@ class Vendor_Module_Controller_Webapi_Invalid_Type
      */
     public function createV1($data)
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/several_classes_in_one_file/file_with_classes.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/several_classes_in_one_file/file_with_classes.php
index 99c823a51f7..29c7ed4e210 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/several_classes_in_one_file/file_with_classes.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/autodiscovery/several_classes_in_one_file/file_with_classes.php
@@ -25,10 +25,10 @@
  */
 class First_Class
 {
-    // Body was intentionally left empty
+    // Body was intentionally left empty.
 }
 
 class Second_Class
 {
-    // Body was intentionally left empty
+    // Body was intentionally left empty.
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/resource_with_invalid_interface.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/resource_with_invalid_interface.php
index f9fc68ea3f1..3c010c77693 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/resource_with_invalid_interface.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/resource_with_invalid_interface.php
@@ -33,17 +33,17 @@ class Vendor_Module_Controller_Webapi_Invalid_Interface
      */
     public function updateV1($resourceId)
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 
     public function updateV2()
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 
     public function emptyInterfaceV2()
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 
     /**
@@ -51,6 +51,6 @@ class Vendor_Module_Controller_Webapi_Invalid_Interface
      */
     public function invalidMethodNameV2($resourceId)
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/resource_with_invalid_name.php b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/resource_with_invalid_name.php
index 2eeb636d0f0..320154f5bff 100644
--- a/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/resource_with_invalid_name.php
+++ b/dev/tests/integration/testsuite/Mage/Webapi/Model/_files/resource_with_invalid_name.php
@@ -33,6 +33,6 @@ class Vendor_Module_Webapi_Resource_Invalid
      */
     public function updateV1($resourceId)
     {
-        // Body is intentionally left empty
+        // Body is intentionally left empty.
     }
 }
diff --git a/dev/tests/integration/testsuite/Mage/Widget/Model/WidgetTest.php b/dev/tests/integration/testsuite/Mage/Widget/Model/WidgetTest.php
index 4d73f963e32..819215a9309 100644
--- a/dev/tests/integration/testsuite/Mage/Widget/Model/WidgetTest.php
+++ b/dev/tests/integration/testsuite/Mage/Widget/Model/WidgetTest.php
@@ -97,11 +97,16 @@ class Mage_Widget_Model_WidgetTest extends PHPUnit_Framework_TestCase
     /**
      * Tests, that theme file is found anywhere in theme folders, not only in module directory.
      *
+     * @magentoDataFixture Mage/Widget/_files/themes.php
      * @magentoAppIsolation enabled
      */
     public function testGetPlaceholderImageUrlAtTheme()
     {
-        Mage::getConfig()->getOptions()->setDesignDir(dirname(__DIR__) . '/_files/design');
+        Magento_Test_Bootstrap::getInstance()->reinitialize(array(
+            Mage_Core_Model_App::INIT_OPTION_DIRS => array(
+                Mage_Core_Model_Dir::THEMES => dirname(__DIR__) . '/_files/design'
+            )
+        ));
         $actualFile = $this->testGetPlaceholderImageUrl(
             'Mage_Catalog_Block_Product_Widget_New',
             'Mage_Catalog/images/product_widget_new.gif'
diff --git a/dev/tests/integration/testsuite/Mage/Widget/_files/themes.php b/dev/tests/integration/testsuite/Mage/Widget/_files/themes.php
new file mode 100644
index 00000000000..947fbd4ff83
--- /dev/null
+++ b/dev/tests/integration/testsuite/Mage/Widget/_files/themes.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Widget
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $registration Mage_Core_Model_Theme_Registration */
+$registration = Mage::getModel('Mage_Core_Model_Theme_Registration');
+$registration->register(
+    __DIR__ . DIRECTORY_SEPARATOR . 'design',
+    implode(DIRECTORY_SEPARATOR, array('*', '*', '*', 'theme.xml'))
+);
diff --git a/dev/tests/integration/testsuite/Mage/Wishlist/Block/AbstractTest.php b/dev/tests/integration/testsuite/Mage/Wishlist/Block/AbstractTest.php
index 95a608042c3..d2ff23e03d8 100644
--- a/dev/tests/integration/testsuite/Mage/Wishlist/Block/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Mage/Wishlist/Block/AbstractTest.php
@@ -44,6 +44,8 @@ class Mage_Wishlist_Block_AbstractTest extends PHPUnit_Framework_TestCase
         'Mage_Core_Model_Store_Config',
         'Mage_Core_Controller_Varien_Front',
         'Mage_Core_Model_Factory_Helper',
+        'Mage_Core_Model_Dir',
+        'Mage_Core_Model_Logger',
         'Magento_Filesystem',
     );
 
@@ -81,7 +83,7 @@ class Mage_Wishlist_Block_AbstractTest extends PHPUnit_Framework_TestCase
     {
         $arguments = array();
         foreach ($this->_blockInjections as $injectionClass) {
-            $arguments[] = Mage::getModel($injectionClass);
+            $arguments[] = Mage::getObjectManager()->get($injectionClass);
         }
         return $arguments;
     }
diff --git a/dev/tests/integration/testsuite/Magento/Di/GeneratorTest.php b/dev/tests/integration/testsuite/Magento/Di/GeneratorTest.php
index 971b60ea01e..da42f8feb9a 100644
--- a/dev/tests/integration/testsuite/Magento/Di/GeneratorTest.php
+++ b/dev/tests/integration/testsuite/Magento/Di/GeneratorTest.php
@@ -47,9 +47,9 @@ class Magento_Di_GeneratorTest extends PHPUnit_Framework_TestCase
     {
         $this->_includePath = get_include_path();
 
-        /** @var $config Mage_Core_Model_Config */
-        $config = Mage::getObjectManager()->get('Mage_Core_Model_Config');
-        $generationDirectory = $config->getVarDir() . '/generation';
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = Mage::getObjectManager()->get('Mage_Core_Model_Dir');
+        $generationDirectory = $dirs->getDir(Mage_Core_Model_Dir::VAR_DIR) . '/generation';
 
         Magento_Autoload_IncludePath::addIncludePath($generationDirectory);
 
@@ -63,9 +63,9 @@ class Magento_Di_GeneratorTest extends PHPUnit_Framework_TestCase
 
     protected function tearDown()
     {
-        /** @var $config Mage_Core_Model_Config */
-        $config = Mage::getObjectManager()->get('Mage_Core_Model_Config');
-        $generationDirectory = $config->getVarDir() . '/generation';
+        /** @var $dirs Mage_Core_Model_Dir */
+        $dirs = Mage::getObjectManager()->get('Mage_Core_Model_Dir');
+        $generationDirectory = $dirs->getDir(Mage_Core_Model_Dir::VAR_DIR) . '/generation';
         Varien_Io_File::rmdirRecursive($generationDirectory);
 
         set_include_path($this->_includePath);
diff --git a/dev/tests/integration/testsuite/Magento/Filesystem/Adapter/LocalTest.php b/dev/tests/integration/testsuite/Magento/Filesystem/Adapter/LocalTest.php
index 029feab6d87..1bccb1871ed 100644
--- a/dev/tests/integration/testsuite/Magento/Filesystem/Adapter/LocalTest.php
+++ b/dev/tests/integration/testsuite/Magento/Filesystem/Adapter/LocalTest.php
@@ -342,28 +342,32 @@ class Magento_Filesystem_Adapter_LocalTest extends PHPUnit_Framework_TestCase
      */
     public function testGetNestedKeys($path, $expectedKeys)
     {
-        $this->assertEquals($expectedKeys, $this->_adapter->getNestedKeys($path));
+        $actualKeys = $this->_adapter->getNestedKeys($path);
+        $this->assertEquals(sort($expectedKeys), sort($actualKeys));
     }
 
     /**
      * @return array
+     *
+     * @SuppressWarnings(PHPMD.ShortVariable)
      */
     public function getNestedKeysDataProvider()
     {
+        $ds = Magento_Filesystem::DIRECTORY_SEPARATOR;
         return array(
             array(
                 $this->_getFixturesPath() . 'foo',
                 array(
-                    $this->_getFixturesPath() . 'foo' . DS . 'bar' . DS . 'baz' . DS . 'file_one.txt',
-                    $this->_getFixturesPath() . 'foo' . DS . 'bar' . DS . 'baz',
-                    $this->_getFixturesPath() . 'foo' . DS . 'bar' . DS . 'file_two.txt',
-                    $this->_getFixturesPath() . 'foo' . DS . 'bar',
-                    $this->_getFixturesPath() . 'foo' . DS . 'file_three.txt',
+                    $this->_getFixturesPath() . 'foo' . $ds . 'bar' . $ds . 'baz' . $ds . 'file_one.txt',
+                    $this->_getFixturesPath() . 'foo' . $ds . 'bar' . $ds . 'baz',
+                    $this->_getFixturesPath() . 'foo' . $ds . 'bar' . $ds . 'file_two.txt',
+                    $this->_getFixturesPath() . 'foo' . $ds . 'bar',
+                    $this->_getFixturesPath() . 'foo' . $ds . 'file_three.txt',
                 )
             ),
             array(
-                $this->_getFixturesPath() . 'foo' . DS . 'bar' . DS . 'baz',
-                array($this->_getFixturesPath() . 'foo' . DS . 'bar' . DS . 'baz' . DS . 'file_one.txt')
+                $this->_getFixturesPath() . 'foo' . $ds . 'bar' . $ds . 'baz',
+                array($this->_getFixturesPath() . 'foo' . $ds . 'bar' . $ds . 'baz' . $ds . 'file_one.txt')
             )
         );
     }
@@ -389,21 +393,24 @@ class Magento_Filesystem_Adapter_LocalTest extends PHPUnit_Framework_TestCase
 
     /**
      * @return array
+     *
+     * @SuppressWarnings(PHPMD.ShortVariable)
      */
     public function getNestedFilesDataProvider()
     {
+        $ds = Magento_Filesystem::DIRECTORY_SEPARATOR;
         return array(
             array(
                 $this->_getFixturesPath() . 'foo/*',
                 array(
-                    $this->_getFixturesPath() . 'foo' . DS . 'bar',
-                    $this->_getFixturesPath() . 'foo' . DS . 'file_three.txt',
+                    $this->_getFixturesPath() . 'foo' . $ds . 'bar',
+                    $this->_getFixturesPath() . 'foo' . $ds . 'file_three.txt',
                 )
             ),
             array(
                 $this->_getFixturesPath() . 'foo/*/file_*',
                 array(
-                    $this->_getFixturesPath() . 'foo' . DS . 'bar' . DS . 'file_two.txt',
+                    $this->_getFixturesPath() . 'foo' . $ds . 'bar' . $ds . 'file_two.txt',
                 )
             )
         );
diff --git a/dev/tests/integration/testsuite/MemoryUsageTest.php b/dev/tests/integration/testsuite/MemoryUsageTest.php
new file mode 100644
index 00000000000..92b80dfade9
--- /dev/null
+++ b/dev/tests/integration/testsuite/MemoryUsageTest.php
@@ -0,0 +1,192 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Mage_Core
+ * @subpackage  integration_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class MemoryUsageTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Number of application reinitialization iterations to be conducted by tests
+     */
+    const APP_REINITIALIZATION_LOOPS = 20;
+
+    /**
+     * Test that application reinitialization produces no memory leaks
+     */
+    public function testAppReinitializationNoMemoryLeak()
+    {
+        $this->_deallocateUnusedMemory();
+        $actualMemoryUsage = $this->_getRealMemoryUsage();
+        for ($i = 0; $i < self::APP_REINITIALIZATION_LOOPS; $i++) {
+            Magento_Test_Bootstrap::getInstance()->reinitialize();
+            $this->_deallocateUnusedMemory();
+        }
+        $actualMemoryUsage = $this->_getRealMemoryUsage() - $actualMemoryUsage;
+        $this->assertLessThanOrEqual($this->_getAllowedMemoryUsage(), $actualMemoryUsage, sprintf(
+            "Application reinitialization causes the memory leak of %u bytes per %u iterations.",
+            $actualMemoryUsage,
+            self::APP_REINITIALIZATION_LOOPS
+        ));
+    }
+
+    /**
+     * Force to deallocate no longer used memory
+     */
+    protected function _deallocateUnusedMemory()
+    {
+        gc_collect_cycles();
+    }
+
+    /**
+     * Retrieve the allowed memory usage in bytes, depending on the environment
+     *
+     * @return int
+     */
+    protected function _getAllowedMemoryUsage()
+    {
+        // Memory usage limits should not be further increased, corresponding memory leaks have to be fixed instead!
+        if ($this->_isWindowsOs()) {
+            return $this->_convertToBytes('1M');
+        }
+        return 0;
+    }
+
+    /**
+     * Whether the operating system belongs to the Windows family
+     *
+     * @link http://php.net/manual/en/function.php-uname.php
+     * @return bool
+     */
+    protected function _isWindowsOs()
+    {
+        return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
+    }
+
+    /**
+     * Retrieve the effective memory usage of the current process
+     *
+     * memory_get_usage() cannot be used because of the bug
+     * @link https://bugs.php.net/bug.php?id=62467
+     *
+     * @return int Memory usage in bytes
+     */
+    protected function _getRealMemoryUsage()
+    {
+        $pid = getmypid();
+        $shell = new Magento_Shell();
+        if ($this->_isWindowsOs()) {
+            $result = $this->_getWinProcessMemoryUsage($shell, $pid);
+        } else {
+            $result = $this->_getUnixProcessMemoryUsage($shell, $pid);
+        }
+        return $result;
+    }
+
+    /**
+     * Retrieve the current process' memory usage using Unix command line interface
+     *
+     * @param Magento_Shell $shell
+     * @param int $pid
+     * @return int Memory usage in bytes
+     */
+    protected function _getUnixProcessMemoryUsage(Magento_Shell $shell, $pid)
+    {
+        /**
+         * @link http://linux.die.net/man/1/top
+         *
+         * Output format invariant:
+         *   PID USER    PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
+         * 12345 root    20   0  215m  36m  10m S   98  0.5   0:32.96 php
+         */
+        $output = $shell->execute('top -p %s -n 1 -b | grep PID -A 1', array($pid));
+
+        $output = preg_split('/\n+/', $output, -1, PREG_SPLIT_NO_EMPTY);
+        $keys = preg_split('/\s+/', $output[0], -1, PREG_SPLIT_NO_EMPTY);
+        $values = preg_split('/\s+/', $output[1], -1, PREG_SPLIT_NO_EMPTY);
+        $stats = array_combine($keys, $values);
+
+        $result = $stats['RES']; // resident set size, the non-swapped physical memory
+
+        if (is_numeric($result)) {
+            $result .= 'k'; // kilobytes by default
+        }
+
+        return $this->_convertToBytes($result);
+    }
+
+    /**
+     * Retrieve the current process' memory usage using Windows command line interface
+     *
+     * @param Magento_Shell $shell
+     * @param int $pid
+     * @return int Memory usage in bytes
+     */
+    protected function _getWinProcessMemoryUsage(Magento_Shell $shell, $pid)
+    {
+        /**
+         * @link http://technet.microsoft.com/en-us/library/bb491010.aspx
+         *
+         * Output format invariant:
+         * "Image Name","PID","Session Name","Session#","Mem Usage"
+         * "php.exe","12345","N/A","0","26,321 K"
+         */
+        $output = $shell->execute('tasklist /fi %s /fo CSV', array("PID eq $pid"));
+
+        /** @link http://www.php.net/manual/en/wrappers.data.php */
+        $csvStream = 'data://text/plain;base64,' . base64_encode($output);
+        $csvHandle = fopen($csvStream, 'r');
+        $keys = fgetcsv($csvHandle);
+        $values = fgetcsv($csvHandle);
+        fclose($csvHandle);
+        $stats = array_combine($keys, $values);
+
+        $result = $stats['Mem Usage'];
+
+        return $this->_convertToBytes($result);
+    }
+
+    /**
+     * Convert a number optionally followed by the unit symbol (B, K, M, G, etc.) to bytes
+     *
+     * @param string $number String representation of a number
+     * @return int
+     * @throws InvalidArgumentException
+     */
+    protected function _convertToBytes($number)
+    {
+        $number = str_replace(array(',', ' '), '', $number);
+        $number = strtoupper($number);
+        $units = 'BKMGTPEZY';
+        if (!preg_match("/^(\d+(?:\.\d+)?)([$units]?)$/", $number, $matches)) {
+            throw new InvalidArgumentException("Number format '$number' is not recognized.");
+        }
+        $result = (float)$matches[1];
+        $unitSymbol = $matches[2];
+        if ($unitSymbol) {
+            $result *= pow(1024, strpos($units, $unitSymbol));
+        }
+        return (int)$result;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Varien/Db/Adapter/Pdo/MysqlTest.php b/dev/tests/integration/testsuite/Varien/Db/Adapter/Pdo/MysqlTest.php
index 79877153058..0036e5e65ed 100644
--- a/dev/tests/integration/testsuite/Varien/Db/Adapter/Pdo/MysqlTest.php
+++ b/dev/tests/integration/testsuite/Varien/Db/Adapter/Pdo/MysqlTest.php
@@ -31,23 +31,20 @@
 class Varien_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * DB connection instance
+     * Database adapter instance
      *
      * @var Varien_Db_Adapter_Pdo_Mysql
      */
-    protected $_connection = null;
-
+    protected $_dbAdapter = null;
 
     protected function tearDown()
     {
-        $this->_connection = null;
+        $this->_dbAdapter = null;
     }
 
     /**
      * Test lost connection re-initializing
      *
-     * @covers Varien_Db_Adapter_Pdo_Mysql::raw_query
-     * @covers Varien_Db_Adapter_Pdo_Mysql::query
      * @throws Exception
      */
     public function testWaitTimeout()
@@ -55,7 +52,7 @@ class Varien_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase
         if (Magento_Test_Bootstrap::getInstance()->getDbVendorName() != 'mysql') {
             $this->markTestSkipped('Test is designed to run on MySQL only.');
         }
-        if (!($this->_getConnection() instanceof Varien_Db_Adapter_Pdo_Mysql)) {
+        if (!($this->_getDbAdapter() instanceof Varien_Db_Adapter_Pdo_Mysql)) {
             $this->markTestSkipped('This test is for Varien_Db_Adapter_Pdo_Mysql');
         }
         try {
@@ -66,14 +63,14 @@ class Varien_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase
 
             // Sleep for time greater than wait_timeout and try to perform query
             sleep($minWaitTimeout + 1);
-            $result = $this->_getConnection()->raw_query('SELECT 1');
+            $result = $this->_executeQuery('SELECT 1');
             $this->assertInstanceOf('Varien_Db_Statement_Pdo_Mysql', $result);
             // Restore wait_timeout
             $this->_setWaitTimeout($defaultWaitTimeout);
             $this->assertEquals($defaultWaitTimeout, $this->_getWaitTimeout(), 'Default wait timeout was not restored');
         } catch (Exception $e) {
             // Reset connection on failure to restore global variables
-            $this->_getConnection()->closeConnection();
+            $this->_getDbAdapter()->closeConnection();
             throw $e;
         }
     }
@@ -85,7 +82,8 @@ class Varien_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase
      */
     protected function _getWaitTimeout()
     {
-        return (int) $this->_getConnection()->fetchOne('SELECT @@wait_timeout');
+        $result = $this->_executeQuery('SELECT @@session.wait_timeout');
+        return (int)$result->fetchColumn();
     }
 
     /**
@@ -95,21 +93,51 @@ class Varien_Db_Adapter_Pdo_MysqlTest extends PHPUnit_Framework_TestCase
      */
     protected function _setWaitTimeout($waitTimeout)
     {
-        $this->_getConnection()->query("SET wait_timeout = {$waitTimeout}");
+        $this->_executeQuery("SET @@session.wait_timeout = {$waitTimeout}");
+    }
+
+    /**
+     * Execute SQL query and return result statement instance
+     *
+     * @param string $sql
+     * @return Zend_Db_Statement_Interface
+     * @throws Exception
+     */
+    protected function _executeQuery($sql)
+    {
+        /**
+         * Suppress PDO warnings to work around the bug
+         * @link https://bugs.php.net/bug.php?id=63812
+         */
+        $phpErrorReporting = error_reporting();
+        /** @var $pdoConnection PDO */
+        $pdoConnection = $this->_getDbAdapter()->getConnection();
+        $pdoWarningsEnabled = $pdoConnection->getAttribute(PDO::ATTR_ERRMODE) & PDO::ERRMODE_WARNING;
+        if (!$pdoWarningsEnabled) {
+            error_reporting($phpErrorReporting & ~E_WARNING);
+        }
+        try {
+            $result = $this->_getDbAdapter()->query($sql);
+            error_reporting($phpErrorReporting);
+        } catch (Exception $e) {
+            error_reporting($phpErrorReporting);
+            throw $e;
+        }
+        return $result;
     }
 
     /**
-     * Get DB connection
+     * Retrieve database adapter instance
      *
      * @return Varien_Db_Adapter_Pdo_Mysql
      */
-    protected function _getConnection()
+    protected function _getDbAdapter()
     {
-        if (is_null($this->_connection)) {
+        if (is_null($this->_dbAdapter)) {
             /** @var $coreResource Mage_Core_Model_Resource */
             $coreResource = Mage::getSingleton('Mage_Core_Model_Resource');
-            $this->_connection = $coreResource->getConnection(Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE);
+            $this->_dbAdapter = $coreResource->getConnection(Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE);
         }
-        return $this->_connection;
+        return $this->_dbAdapter;
     }
 }
diff --git a/dev/tests/integration/testsuite/Varien/Image/Adapter/InterfaceTest.php b/dev/tests/integration/testsuite/Varien/Image/Adapter/InterfaceTest.php
index 01cc27f9474..68e2c285706 100644
--- a/dev/tests/integration/testsuite/Varien/Image/Adapter/InterfaceTest.php
+++ b/dev/tests/integration/testsuite/Varien/Image/Adapter/InterfaceTest.php
@@ -244,7 +244,7 @@ class Varien_Image_Adapter_InterfaceTest extends PHPUnit_Framework_TestCase
 
     public function saveDataProvider()
     {
-        $dir = Magento_Test_Bootstrap::getInstance()->getTmpDir() . DIRECTORY_SEPARATOR;
+        $dir = Magento_Test_Bootstrap::getInstance()->getInstallDir() . DIRECTORY_SEPARATOR;
         return $this->_prepareData(array(
             array(
                 $this->_getFixture('image_adapters_test.png'),
diff --git a/dev/tests/integration/testsuite/integrity/modular/AclConfigFilesTest.php b/dev/tests/integration/testsuite/integrity/modular/AclConfigFilesTest.php
index 4e69671d377..6ef04333c32 100644
--- a/dev/tests/integration/testsuite/integrity/modular/AclConfigFilesTest.php
+++ b/dev/tests/integration/testsuite/integrity/modular/AclConfigFilesTest.php
@@ -50,8 +50,6 @@ class Integrity_Modular_AclConfigFilesTest extends PHPUnit_Framework_TestCase
 
     /**
      * Prepare file list of ACL resources
-     *
-     * @return void
      */
     protected function _prepareFileList()
     {
diff --git a/dev/tests/integration/testsuite/integrity/modular/TemplateFilesTest.php b/dev/tests/integration/testsuite/integrity/modular/TemplateFilesTest.php
index 762a3d49d30..4df52e3ad6d 100644
--- a/dev/tests/integration/testsuite/integrity/modular/TemplateFilesTest.php
+++ b/dev/tests/integration/testsuite/integrity/modular/TemplateFilesTest.php
@@ -57,8 +57,7 @@ class Integrity_Modular_TemplateFilesTest extends Magento_Test_TestCase_Integrit
     {
         /** @var $website Mage_Core_Model_Website */
         $website = Mage::getModel('Mage_Core_Model_Website');
-        Mage::app()->getStore()->setWebsiteId(0)->setWebsite($website);
-
+        Mage::app()->getStore()->setWebsiteId(0);
 
         $templates = array();
         foreach (Utility_Classes::collectModuleClasses('Block') as $blockClass => $module) {
@@ -85,7 +84,8 @@ class Integrity_Modular_TemplateFilesTest extends Magento_Test_TestCase_Integrit
             $block = Mage::getModel($blockClass);
             $template = $block->getTemplate();
             if ($template) {
-                $templates[] = array($module, $template, $blockClass, $area);
+                $templates[$module . ', ' . $template . ', ' . $blockClass . ', ' . $area] =
+                    array($module, $template, $blockClass, $area);
             }
         }
         return $templates;
diff --git a/dev/tests/performance/run_scenarios.php b/dev/tests/performance/run_scenarios.php
index 0c98de2a57b..fce5308b7ab 100755
--- a/dev/tests/performance/run_scenarios.php
+++ b/dev/tests/performance/run_scenarios.php
@@ -29,7 +29,11 @@
 /** @var $config Magento_Performance_Config */
 $config = require_once __DIR__ . '/framework/bootstrap.php';
 
-$shell = new Magento_Shell(true);
+$logWriter = new Zend_Log_Writer_Stream('php://output');
+$logWriter->setFormatter(new Zend_Log_Formatter_Simple('%message%' . PHP_EOL));
+$logger = new Zend_Log($logWriter);
+
+$shell = new Magento_Shell($logger);
 $scenarioHandler = new Magento_Performance_Scenario_Handler_FileFormat();
 $scenarioHandler
     ->register('jmx', new Magento_Performance_Scenario_Handler_Jmeter($shell))
@@ -41,15 +45,17 @@ $testsuite = new Magento_Performance_Testsuite($config, new Magento_Application(
 $scenarioTotalCount = count($config->getScenarios());
 $scenarioCount = 1;
 $scenarioFailCount = 0;
-$testsuite->onScenarioRun(function (Magento_Performance_Scenario $scenario) use (&$scenarioCount, $scenarioTotalCount) {
-    echo "Scenario $scenarioCount of $scenarioTotalCount: '{$scenario->getTitle()}'" . PHP_EOL;
-    $scenarioCount++;
-});
+$testsuite->onScenarioRun(
+    function (Magento_Performance_Scenario $scenario) use ($logger, &$scenarioCount, $scenarioTotalCount) {
+        $logger->log("Scenario $scenarioCount of $scenarioTotalCount: '{$scenario->getTitle()}'", Zend_Log::INFO);
+        $scenarioCount++;
+    }
+);
 $testsuite->onScenarioFailure(
-    function (Magento_Performance_Scenario_FailureException $scenarioFailure) use (&$scenarioFailCount) {
+    function (Magento_Performance_Scenario_FailureException $scenarioFailure) use ($logger, &$scenarioFailCount) {
         $scenario = $scenarioFailure->getScenario();
-        echo "Scenario '{$scenario->getTitle()}' has failed!" . PHP_EOL
-            . $scenarioFailure->getMessage() . PHP_EOL . PHP_EOL;
+        $logger->log("Scenario '{$scenario->getTitle()}' has failed!", Zend_Log::ERR);
+        $logger->log($scenarioFailure->getMessage(), Zend_Log::ERR);
         $scenarioFailCount++;
     }
 );
@@ -57,8 +63,8 @@ $testsuite->onScenarioFailure(
 $testsuite->run();
 
 if ($scenarioFailCount) {
-    echo "Failed $scenarioFailCount of $scenarioTotalCount scenario(s)" . PHP_EOL;
+    $logger->log("Failed $scenarioFailCount of $scenarioTotalCount scenario(s)", Zend_Log::INFO);
     exit(1);
 } else {
-    echo 'Successful' . PHP_EOL;
+    $logger->log('Successful', Zend_Log::INFO);
 }
diff --git a/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer.php b/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer.php
index a2d11e997c3..13780feaecd 100644
--- a/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer.php
+++ b/dev/tests/static/framework/CodingStandard/Tool/CodeSniffer.php
@@ -56,6 +56,7 @@ class CodingStandard_Tool_CodeSniffer implements CodingStandard_ToolInterface
      *
      * @param string $rulesetDir Directory that locates the inspection rules
      * @param string $reportFile Destination file to write inspection report to
+     * @param CodingStandard_Tool_CodeSniffer_Wrapper $wrapper
      */
     public function __construct($rulesetDir, $reportFile, CodingStandard_Tool_CodeSniffer_Wrapper $wrapper)
     {
@@ -110,4 +111,13 @@ class CodingStandard_Tool_CodeSniffer implements CodingStandard_ToolInterface
         return $result;
     }
 
+    /**
+     * Get report file
+     *
+     * @return string
+     */
+    public function getReportFile()
+    {
+        return $this->_reportFile;
+    }
 }
diff --git a/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSnifferTest.php b/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSnifferTest.php
index baa50c33e45..47b475b5b2b 100644
--- a/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSnifferTest.php
+++ b/dev/tests/static/framework/tests/unit/testsuite/CodingStandard/Tool/CodeSnifferTest.php
@@ -82,4 +82,9 @@ class CodingStandard_Tool_CodeSnifferTest extends PHPUnit_Framework_TestCase
 
         $this->_tool->run($whiteList, $blackList, $extensions);
     }
+
+    public function testGetReportFile()
+    {
+        $this->assertEquals(self::REPORT_FILE, $this->_tool->getReportFile());
+    }
 }
diff --git a/dev/tests/static/testsuite/Js/_files/blacklist/ee.txt b/dev/tests/static/testsuite/Js/_files/blacklist/ee.txt
deleted file mode 100644
index 373ec3a9d98..00000000000
--- a/dev/tests/static/testsuite/Js/_files/blacklist/ee.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-app/code/core/Enterprise/Cms/view/adminhtml/cms.js
-app/code/core/Enterprise/Rma/view/adminhtml/rma.js
diff --git a/dev/tests/static/testsuite/Legacy/ConfigTest.php b/dev/tests/static/testsuite/Legacy/ConfigTest.php
index 7de62090a3c..9490ff3602d 100644
--- a/dev/tests/static/testsuite/Legacy/ConfigTest.php
+++ b/dev/tests/static/testsuite/Legacy/ConfigTest.php
@@ -51,6 +51,9 @@ class Legacy_ConfigTest extends PHPUnit_Framework_TestCase
                 'Event has been replaced with "core_layout_render_element"',
             '/config/*/events/catalog_controller_product_delete' => '',
             '/config//observers/*/args' => 'This was an undocumented and unused feature in event subscribers',
+            '/config/default/design/theme' => 'Relocated to /config/<area>/design/theme',
+            '/config/default/web/*/base_js_url' => 'See /config/default/web/*/base_lib_url',
+            '/config/default/web/*/base_skin_url' => '',
         );
         $xml = simplexml_load_file($file);
         foreach ($obsoleteNodes as $xpath => $suggestion) {
diff --git a/dev/tests/static/testsuite/Legacy/EmailTemplateTest.php b/dev/tests/static/testsuite/Legacy/EmailTemplateTest.php
index 65bda42b5c9..de5241a5b86 100644
--- a/dev/tests/static/testsuite/Legacy/EmailTemplateTest.php
+++ b/dev/tests/static/testsuite/Legacy/EmailTemplateTest.php
@@ -36,11 +36,10 @@ class Legacy_EmailTemplateTest extends PHPUnit_Framework_TestCase
      */
     public function testObsoleteDirectives($file)
     {
-        $suggestion = sprintf(Legacy_ObsoleteCodeTest::SUGGESTION_MESSAGE, '{{escapehtml}}');
         $this->assertNotRegExp(
             '/\{\{htmlescape.*?\}\}/i',
             file_get_contents($file),
-            'Directive {{htmlescape}} is obsolete. ' . $suggestion
+            'Directive {{htmlescape}} is obsolete. Use {{escapehtml}} instead.'
         );
     }
 
diff --git a/dev/tests/static/testsuite/Legacy/LayoutTest.php b/dev/tests/static/testsuite/Legacy/LayoutTest.php
index c1b3f980734..d469ed1197f 100644
--- a/dev/tests/static/testsuite/Legacy/LayoutTest.php
+++ b/dev/tests/static/testsuite/Legacy/LayoutTest.php
@@ -101,7 +101,6 @@ class Legacy_LayoutTest extends PHPUnit_Framework_TestCase
      */
     public function testLayoutFile($layoutFile)
     {
-        $suggestion = sprintf(Legacy_ObsoleteCodeTest::SUGGESTION_MESSAGE, 'addCss/addJss');
         $layoutXml = simplexml_load_file($layoutFile);
 
         $this->_testObsoleteReferences($layoutXml);
@@ -113,7 +112,7 @@ class Legacy_LayoutTest extends PHPUnit_Framework_TestCase
             $layoutXml->xpath(
                 '//*[' . $selectorHeadBlock . ']/action[@method="addItem"]'
             ),
-            "Mage_Page_Block_Html_Head::addItem is obsolete. $suggestion"
+            'Mage_Page_Block_Html_Head::addItem is obsolete. Use addCss()/addJs() instead.'
         );
         $this->assertSame(array(),
             $layoutXml->xpath(
diff --git a/dev/tests/static/testsuite/Legacy/ObsoleteCodeTest.php b/dev/tests/static/testsuite/Legacy/ObsoleteCodeTest.php
index b602d5168d7..1a6fd978b7c 100644
--- a/dev/tests/static/testsuite/Legacy/ObsoleteCodeTest.php
+++ b/dev/tests/static/testsuite/Legacy/ObsoleteCodeTest.php
@@ -36,12 +36,92 @@ class Legacy_ObsoleteCodeTest extends PHPUnit_Framework_TestCase
      */
     const SUGGESTION_MESSAGE = 'Use "%s" instead.';
 
-    /**
-     * In-memory cache for the configuration files
+    /**@#+
+     * Lists of obsolete entities from fixtures
      *
      * @var array
      */
-    protected static $_configFilesCache = array();
+    protected static $_classes    = array();
+    protected static $_constants  = array();
+    protected static $_methods    = array();
+    protected static $_attributes = array();
+    /**#@-*/
+
+    /**
+     * Read fixtures into memory as arrays
+     */
+    public static function setUpBeforeClass()
+    {
+        $errors = array();
+        self::_populateList(self::$_classes, $errors, 'obsolete_classes*.php', false);
+        self::_populateList(self::$_constants, $errors, 'obsolete_constants*.php');
+        self::_populateList(self::$_methods, $errors, 'obsolete_methods*.php');
+        self::_populateList(self::$_attributes, $errors, 'obsolete_properties*.php');
+        if ($errors) {
+            $message = 'Duplicate patterns identified in list declarations:' . PHP_EOL . PHP_EOL;
+            foreach ($errors as $file => $list) {
+                $message .= $file . PHP_EOL;
+                foreach ($list as $key) {
+                    $message .= "    {$key}" . PHP_EOL;
+                }
+                $message .= PHP_EOL;
+            }
+            throw new Exception($message);
+        }
+    }
+
+    /**
+     * Read the specified file pattern and merge it with the list
+     *
+     * Duplicate entries will be recorded into errors array.
+     *
+     * @param array $list
+     * @param array $errors
+     * @param string $filePattern
+     * @param bool $hasScope
+     */
+    protected static function _populateList(array &$list, array &$errors, $filePattern, $hasScope = true)
+    {
+
+        foreach (glob(__DIR__ . '/_files/' . $filePattern) as $file) {
+            foreach (self::_readList($file) as $row) {
+                list($item, $scope, $replacement) = self::_padRow($row, $hasScope);
+                $key = "{$item}|{$scope}";
+                if (isset($list[$key])) {
+                    $errors[$file][] = $key;
+                } else {
+                    $list[$key] = array($item, $scope, $replacement);
+                }
+            }
+        }
+    }
+
+    /**
+     * Populate insufficient row elements regarding to whether the row supposed to have scope value
+     *
+     * @param array $row
+     * @param bool $hasScope
+     * @return array
+     */
+    protected static function _padRow($row, $hasScope)
+    {
+        if ($hasScope) {
+            return array_pad($row, 3, '');
+        }
+        list($item, $replacement) = array_pad($row, 2, '');
+        return array($item, '', $replacement);
+    }
+
+    /**
+     * Isolate including a file into a method to reduce scope
+     *
+     * @param $file
+     * @return array
+     */
+    protected static function _readList($file)
+    {
+        return include($file);
+    }
 
     /**
      * @param string $file
@@ -50,12 +130,14 @@ class Legacy_ObsoleteCodeTest extends PHPUnit_Framework_TestCase
     public function testPhpFile($file)
     {
         $content = file_get_contents($file);
-        $this->_testObsoleteClasses($content, $file);
-        $this->_testObsoleteMethods($content, $file);
+        $this->_testObsoleteClasses($content);
+        $this->_testObsoleteMethods($content);
+        $this->_testGetChildSpecialCase($content, $file);
+        $this->_testGetOptionsSpecialCase($content);
         $this->_testObsoleteMethodArguments($content);
-        $this->_testObsoleteProperties($content, $file);
-        $this->_testObsoleteActions($content, $file);
-        $this->_testObsoleteConstants($content, $file);
+        $this->_testObsoleteProperties($content);
+        $this->_testObsoleteActions($content);
+        $this->_testObsoleteConstants($content);
         $this->_testObsoletePropertySkipCalculate($content);
     }
 
@@ -105,34 +187,82 @@ class Legacy_ObsoleteCodeTest extends PHPUnit_Framework_TestCase
 
     /**
      * @param string $content
-     * @param string $file
      */
-    protected function _testObsoleteClasses($content, $file)
+    protected function _testObsoleteClasses($content)
     {
-        $declarations = $this->_getRelevantConfigEntities('obsolete_classes*.php', $content, $file);
-        foreach ($declarations as $declaration) {
-            list($entity, $suggestion) = $declaration;
+        foreach (self::$_classes as $row) {
+            list($entity, , $suggestion) = $row;
             $this->_assertNotRegExp('/[^a-z\d_]' . preg_quote($entity, '/') . '[^a-z\d_]/iS', $content,
-                "Class '$entity' is obsolete. $suggestion"
+                sprintf("Class '%s' is obsolete. Replacement suggestion: %s", $entity, $suggestion)
             );
         }
     }
 
     /**
+     * Determine if content should be skipped based on specified class scope
+     *
+     * @param string $content
+     * @param string $class
+     * @return bool
+     */
+    protected function _isClassSkipped($content, $class)
+    {
+        $regexp = '/(class|extends)\s+' . preg_quote($class, '/') . '(\s|;)/S';
+        /* Note: strpos is used just to prevent excessive preg_match calls */
+        if ($class && (!strpos($content, $class) || !preg_match($regexp, $content))) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * @param string $content
+     */
+    protected function _testObsoleteMethods($content)
+    {
+        foreach (self::$_methods as $row) {
+            list($method, $class, $suggestion) = $row;
+            if (!$this->_isClassSkipped($content, $class)) {
+                $this->_assertNotRegExp('/[^a-z\d_]' . preg_quote($method, '/') . '\s*\(/iS', $content,
+                    sprintf("Method '%s' is obsolete. Replacement suggestion: %s", $method, $suggestion)
+                );
+            }
+        }
+    }
+
+    /**
+     * Special case: don't allow usage of getChild() method anywhere within app directory
+     *
+     * In Magento 1.x it used to belong only to abstract block (therefore all blocks)
+     * At the same time, the name is pretty generic and can be encountered in other directories, such as lib
+     *
      * @param string $content
      * @param string $file
      */
-    protected function _testObsoleteMethods($content, $file)
+    protected function _testGetChildSpecialCase($content, $file)
     {
-        $declarations = $this->_getRelevantConfigEntities('obsolete_methods*.php', $content, $file);
-        foreach ($declarations as $declaration) {
-            list($method, $suggestion) = $declaration;
-            $this->_assertNotRegExp('/[^a-z\d_]' . preg_quote($method, '/') . '\s*\(/iS', $content,
-                "Method '$method' is obsolete. $suggestion"
+        if (0 === strpos($file, Utility_Files::init()->getPathToSource() . '/app/')) {
+            $this->_assertNotRegexp('/[^a-z\d_]getChild\s*\(/iS', $content,
+                'Block method getChild() is obsolete. Replacement suggestion: Mage_Core_Block_Abstract::getChildBlock()'
             );
         }
     }
 
+    /**
+     * Special case for ->getConfig()->getOptions()->
+     *
+     * @param string $content
+     */
+    protected function _testGetOptionsSpecialCase($content)
+    {
+        $this->_assertNotRegexp(
+            '/getOptions\(\)\s*->get(Base|App|Code|Design|Etc|Lib|Locale|Js|Media'
+                .'|Var|Tmp|Cache|Log|Session|Upload|Export)?Dir\(/S',
+            $content,
+            'The class Mage_Core_Model_Config_Options is obsolete. Replacement suggestion: Mage_Core_Model_Dir'
+        );
+    }
+
     /**
      * @param string $content
      */
@@ -168,16 +298,16 @@ class Legacy_ObsoleteCodeTest extends PHPUnit_Framework_TestCase
 
     /**
      * @param string $content
-     * @param string $file
      */
-    protected function _testObsoleteProperties($content, $file)
+    protected function _testObsoleteProperties($content)
     {
-        $declarations = $this->_getRelevantConfigEntities('obsolete_properties*.php', $content, $file);
-        foreach ($declarations as $declaration) {
-            list($entity, $suggestion) = $declaration;
-            $this->_assertNotRegExp('/[^a-z\d_]' . preg_quote($entity, '/') . '[^a-z\d_]/iS', $content,
-                "Property '$entity' is obsolete. $suggestion"
-            );
+        foreach (self::$_attributes as $row) {
+            list($attribute, $class, $suggestion) = $row;
+            if (!$this->_isClassSkipped($content, $class)) {
+                $this->_assertNotRegExp('/[^a-z\d_]' . preg_quote($attribute, '/') . '[^a-z\d_]/iS', $content,
+                    sprintf("Class attribute '%s' is obsolete. Replacement suggestion: %s", $attribute, $suggestion)
+                );
+            }
         }
     }
 
@@ -194,16 +324,16 @@ class Legacy_ObsoleteCodeTest extends PHPUnit_Framework_TestCase
 
     /**
      * @param string $content
-     * @param string $file
      */
-    protected function _testObsoleteConstants($content, $file)
+    protected function _testObsoleteConstants($content)
     {
-        $declarations = $this->_getRelevantConfigEntities('obsolete_constants*.php', $content, $file);
-        foreach ($declarations as $declaration) {
-            list($entity, $suggestion) = $declaration;
-            $this->_assertNotRegExp('/[^a-z\d_]' . preg_quote($entity, '/') . '[^a-z\d_]/iS', $content,
-                "Constant '$entity' is obsolete. $suggestion"
-            );
+        foreach (self::$_constants as $row) {
+            list($constant, $class, $suggestion) = $row;
+            if (!$this->_isClassSkipped($content, $class)) {
+                $this->_assertNotRegExp('/[^a-z\d_]' . preg_quote($constant, '/') . '[^a-z\d_]/iS', $content,
+                    sprintf("Constant '%s' is obsolete. Replacement suggestion: %s", $constant, $suggestion)
+                );
+            }
         }
     }
 
@@ -217,57 +347,6 @@ class Legacy_ObsoleteCodeTest extends PHPUnit_Framework_TestCase
         );
     }
 
-    /**
-     * Retrieve configuration items, whose 'class_scope' match to the content, in the following format:
-     *   array(
-     *     array('<entity>', '<suggestion>'),
-     *     ...
-     *   )
-     *
-     * @param string $fileNamePattern
-     * @param string $content
-     * @param string $file
-     * @return array
-     */
-    protected function _getRelevantConfigEntities($fileNamePattern, $content, $file)
-    {
-        $result = array();
-        foreach ($this->_loadConfigFiles($fileNamePattern) as $info) {
-            $class = $info['class_scope'];
-            $regexp = '/(class|extends)\s+' . preg_quote($class, '/') . '(\s|;)/S';
-            /* Note: strpos is used just to prevent excessive preg_match calls */
-            if ($class && (!strpos($content, $class) || !preg_match($regexp, $content))) {
-                continue;
-            }
-            if ($info['directory']) {
-                if (0 !== strpos(str_replace('\\', '/', $file), str_replace('\\', '/', $info['directory']))) {
-                    continue;
-                }
-            }
-            $result[] = array($info['obsolete_entity'], $info['suggestion']);
-        }
-        return $result;
-    }
-
-    /**
-     * Load configuration data from the files that match a glob-pattern
-     *
-     * @param string $fileNamePattern
-     * @return array
-     */
-    protected function _loadConfigFiles($fileNamePattern)
-    {
-        if (isset(self::$_configFilesCache[$fileNamePattern])) {
-            return self::$_configFilesCache[$fileNamePattern];
-        }
-        $config = array();
-        foreach (glob(dirname(__FILE__) . '/_files/' . $fileNamePattern, GLOB_BRACE) as $configFile) {
-            $config = array_merge($config, include($configFile));
-        }
-        self::$_configFilesCache[$fileNamePattern] = $config;
-        return $config;
-    }
-
     /**
      * Custom replacement for assertNotRegexp()
      *
@@ -282,36 +361,4 @@ class Legacy_ObsoleteCodeTest extends PHPUnit_Framework_TestCase
     {
         $this->assertSame(0, preg_match($regex, $content), $message);
     }
-
-    /**
-     * Add class rule
-     *
-     * @param string $name
-     * @param null|string $suggestion
-     * @param null|string $directory
-     * @return array
-     */
-    protected function _getClassRule($name, $suggestion = null, $directory = null)
-    {
-        return $this->_getRule($name, null, $suggestion, $directory);
-    }
-
-    /**
-     * Get rule
-     *
-     * @param string $obsoleteEntity
-     * @param null|string $classScope
-     * @param null|string $suggestion
-     * @param null|string $directory
-     * @return array
-     */
-    protected function _getRule($obsoleteEntity, $classScope = null, $suggestion = null, $directory = null)
-    {
-        return array(
-            'obsolete_entity' => $obsoleteEntity,
-            'class_scope' => $classScope,
-            'suggestion' => $suggestion,
-            'directory' => $directory
-        );
-    }
 }
diff --git a/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php
index b5116d51b44..b8d72cb763a 100644
--- a/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Legacy/_files/obsolete_classes.php
@@ -1,5 +1,9 @@
 <?php
 /**
+ * Obsolete classes
+ *
+ * Format: array(<class_name>[, <replacement>])
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -18,696 +22,705 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    tests
- * @package     static
- * @subpackage  Legacy
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 return array(
-    $this->_getClassRule('Mage_Admin_Helper_Data', 'Mage_Backend_Helper_Data'),
-    $this->_getClassRule('Mage_Admin_Model_Acl', 'Magento_Acl'),
-    $this->_getClassRule('Mage_Admin_Model_Acl_Role'),
-    $this->_getClassRule('Mage_Admin_Model_Acl_Resource', 'Magento_Acl_Resource'),
-    $this->_getClassRule('Mage_Admin_Model_Acl_Role_Registry', 'Magento_Acl_Role_Registry'),
-    $this->_getClassRule('Mage_Admin_Model_Acl_Role_Generic', 'Mage_User_Model_Acl_Role_Generic'),
-    $this->_getClassRule('Mage_Admin_Model_Acl_Role_Group', 'Mage_User_Model_Acl_Role_Group'),
-    $this->_getClassRule('Mage_Admin_Model_Acl_Role_User', 'Mage_User_Model_Acl_Role_User'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Acl', 'Mage_User_Model_Resource_Acl'),
-    $this->_getClassRule('Mage_Admin_Model_Observer'),
-    $this->_getClassRule('Mage_Admin_Model_Session', 'Mage_Backend_Model_Auth_Session'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Acl_Role'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Acl_Role_Collection'),
-    $this->_getClassRule('Mage_Admin_Model_User', 'Mage_User_Model_User'),
-    $this->_getClassRule('Mage_Admin_Model_Config'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_User', 'Mage_User_Model_Resource_User'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_User_Collection', 'Mage_User_Model_Resource_User_Collection'),
-    $this->_getClassRule('Mage_Admin_Model_Role', 'Mage_User_Model_Role'),
-    $this->_getClassRule('Mage_Admin_Model_Roles', 'Mage_User_Model_Roles'),
-    $this->_getClassRule('Mage_Admin_Model_Rules', 'Mage_User_Model_Rules'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Role', 'Mage_User_Model_Resource_Role'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Roles', 'Mage_User_Model_Resource_Roles'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Rules', 'Mage_User_Model_Resource_Rules'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Role_Collection', 'Mage_User_Model_Resource_Role_Collection'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Roles_Collection', 'Mage_User_Model_Resource_Roles_Collection'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Roles_User_Collection',
+    array('Mage_Admin_Helper_Data', 'Mage_Backend_Helper_Data'),
+    array('Mage_Admin_Model_Acl', 'Magento_Acl'),
+    array('Mage_Admin_Model_Acl_Role'),
+    array('Mage_Admin_Model_Acl_Resource', 'Magento_Acl_Resource'),
+    array('Mage_Admin_Model_Acl_Role_Registry', 'Magento_Acl_Role_Registry'),
+    array('Mage_Admin_Model_Acl_Role_Generic', 'Mage_User_Model_Acl_Role_Generic'),
+    array('Mage_Admin_Model_Acl_Role_Group', 'Mage_User_Model_Acl_Role_Group'),
+    array('Mage_Admin_Model_Acl_Role_User', 'Mage_User_Model_Acl_Role_User'),
+    array('Mage_Admin_Model_Resource_Acl', 'Mage_User_Model_Resource_Acl'),
+    array('Mage_Admin_Model_Observer'),
+    array('Mage_Admin_Model_Session', 'Mage_Backend_Model_Auth_Session'),
+    array('Mage_Admin_Model_Resource_Acl_Role'),
+    array('Mage_Admin_Model_Resource_Acl_Role_Collection'),
+    array('Mage_Admin_Model_User', 'Mage_User_Model_User'),
+    array('Mage_Admin_Model_Config'),
+    array('Mage_Admin_Model_Resource_User', 'Mage_User_Model_Resource_User'),
+    array('Mage_Admin_Model_Resource_User_Collection', 'Mage_User_Model_Resource_User_Collection'),
+    array('Mage_Admin_Model_Role', 'Mage_User_Model_Role'),
+    array('Mage_Admin_Model_Roles', 'Mage_User_Model_Roles'),
+    array('Mage_Admin_Model_Rules', 'Mage_User_Model_Rules'),
+    array('Mage_Admin_Model_Resource_Role', 'Mage_User_Model_Resource_Role'),
+    array('Mage_Admin_Model_Resource_Roles', 'Mage_User_Model_Resource_Roles'),
+    array('Mage_Admin_Model_Resource_Rules', 'Mage_User_Model_Resource_Rules'),
+    array('Mage_Admin_Model_Resource_Role_Collection', 'Mage_User_Model_Resource_Role_Collection'),
+    array('Mage_Admin_Model_Resource_Roles_Collection', 'Mage_User_Model_Resource_Roles_Collection'),
+    array('Mage_Admin_Model_Resource_Roles_User_Collection',
         'Mage_User_Model_Resource_Roles_User_Collection'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Rules_Collection', 'Mage_User_Model_Resource_Rules_Collection'),
-    $this->_getClassRule('Mage_Admin_Model_Resource_Permissions_Collection',
+    array('Mage_Admin_Model_Resource_Rules_Collection', 'Mage_User_Model_Resource_Rules_Collection'),
+    array('Mage_Admin_Model_Resource_Permissions_Collection',
         'Mage_User_Model_Resource_Permissions_Collection'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Api_Edituser'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Api_Tab_Userroles'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Backup_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Catalog'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Catalog_Product_Attribute_Set_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Catalog_Search_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Newsletter_Problem_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Newsletter_Queue_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Newsletter_Queue'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Page_Menu', 'Mage_Backend_Block_Menu'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User_Edit'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User_Edit_Tabs'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User_Edit_Tab_Main'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User_Edit_Tab_Roles'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_User_Edit_Form'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Role'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Buttons'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Role_Grid_User'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Grid_Role'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Grid_User'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Tab_Roleinfo'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Tab_Rolesedit'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Tab_Rolesusers'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Tab_Useredit'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Editroles'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Roles'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Users'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Edituser'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Tab_Userroles'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Permissions_Usernroles'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Store_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Permissions_UserController'),
-    $this->_getClassRule('Mage_Adminhtml_Permissions_RoleController'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Grid', 'Mage_Reports_Block_Adminhtml_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Customer_Accounts',
+    array('Mage_Adminhtml_Block_Abstract', 'Mage_Core_Block_Template'),
+    array('Mage_Adminhtml_Block_Api_Edituser'),
+    array('Mage_Adminhtml_Block_Api_Tab_Userroles'),
+    array('Mage_Adminhtml_Block_Backup_Grid'),
+    array('Mage_Adminhtml_Block_Catalog'),
+    array('Mage_Adminhtml_Block_Catalog_Product_Attribute_Set_Grid'),
+    array('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config_Grid'),
+    array('Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Group_Grid'),
+    array('Mage_Adminhtml_Block_Catalog_Search_Grid'),
+    array('Mage_Adminhtml_Block_Html_Date', 'Mage_Core_Block_Html_Date'),
+    array('Mage_Adminhtml_Block_Html_Select', 'Mage_Core_Block_Html_Select'),
+    array('Mage_Adminhtml_Block_Messages', 'Mage_Core_Block_Messages'),
+    array('Mage_Adminhtml_Block_Newsletter_Problem_Grid'),
+    array('Mage_Adminhtml_Block_Newsletter_Queue'),
+    array('Mage_Adminhtml_Block_Newsletter_Queue_Grid'),
+    array('Mage_Adminhtml_Block_Page_Menu', 'Mage_Backend_Block_Menu'),
+    array('Mage_Adminhtml_Block_Permissions_User'),
+    array('Mage_Adminhtml_Block_Permissions_User_Grid'),
+    array('Mage_Adminhtml_Block_Permissions_User_Edit'),
+    array('Mage_Adminhtml_Block_Permissions_User_Edit_Tabs'),
+    array('Mage_Adminhtml_Block_Permissions_User_Edit_Tab_Main'),
+    array('Mage_Adminhtml_Block_Permissions_User_Edit_Tab_Roles'),
+    array('Mage_Adminhtml_Block_Permissions_User_Edit_Form'),
+    array('Mage_Adminhtml_Block_Permissions_Role'),
+    array('Mage_Adminhtml_Block_Permissions_Buttons'),
+    array('Mage_Adminhtml_Block_Permissions_Role_Grid_User'),
+    array('Mage_Adminhtml_Block_Permissions_Grid_Role'),
+    array('Mage_Adminhtml_Block_Permissions_Grid_User'),
+    array('Mage_Adminhtml_Block_Permissions_Tab_Roleinfo'),
+    array('Mage_Adminhtml_Block_Permissions_Tab_Rolesedit'),
+    array('Mage_Adminhtml_Block_Permissions_Tab_Rolesusers'),
+    array('Mage_Adminhtml_Block_Permissions_Tab_Useredit'),
+    array('Mage_Adminhtml_Block_Permissions_Editroles'),
+    array('Mage_Adminhtml_Block_Permissions_Roles'),
+    array('Mage_Adminhtml_Block_Permissions_Users'),
+    array('Mage_Adminhtml_Block_Permissions_Edituser'),
+    array('Mage_Adminhtml_Block_Permissions_Tab_Userroles'),
+    array('Mage_Adminhtml_Block_Permissions_Usernroles'),
+    array('Mage_Adminhtml_Permissions_UserController'),
+    array('Mage_Adminhtml_Permissions_RoleController'),
+    array('Mage_Adminhtml_Block_Report_Grid', 'Mage_Reports_Block_Adminhtml_Grid'),
+    array('Mage_Adminhtml_Block_Report_Customer_Accounts',
         'Mage_Reports_Block_Adminhtml_Customer_Accounts'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Customer_Accounts_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Customer_Totals', 'Mage_Reports_Block_Adminhtml_Customer_Totals'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Customer_Totals_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Product_Sold', 'Mage_Reports_Block_Adminhtml_Product_Sold'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Product_Sold_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Review_Customer_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Review_Product_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Refresh_Statistics',
-        'Mage_Reports_Block_Adminhtml_Refresh_Statistics'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Refresh_Statistics_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Customer_Orders', 'Mage_Reports_Block_Adminhtml_Customer_Orders'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Customer_Orders_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Product_Ordered'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Report_Product_Ordered_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Sales'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid_Renderer_Giftmessage'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Edit', 'Mage_Backend_Block_System_Config_Edit'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form', 'Mage_Backend_Block_System_Config_Form'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Tabs', 'Mage_Backend_Block_System_Config_Tabs'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_System_Storage_Media_Synchronize',
-        'Mage_Backend_Block_System_Config_System_Storage_Media_Synchronize'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Fieldset_Modules_DisableOutput',
-        'Mage_Backend_Block_System_Config_Form_Fieldset_Modules_DisableOutput'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Regexceptions',
-        'Mage_Backend_Block_System_Config_Form_Field_Regexceptions'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Notification',
+    array('Mage_Adminhtml_Block_Report_Customer_Accounts_Grid'),
+    array('Mage_Adminhtml_Block_Report_Customer_Totals', 'Mage_Reports_Block_Adminhtml_Customer_Totals'),
+    array('Mage_Adminhtml_Block_Report_Customer_Totals_Grid'),
+    array('Mage_Adminhtml_Block_Report_Product_Sold', 'Mage_Reports_Block_Adminhtml_Product_Sold'),
+    array('Mage_Adminhtml_Block_Report_Product_Sold_Grid'),
+    array('Mage_Adminhtml_Block_Report_Customer_Orders', 'Mage_Reports_Block_Adminhtml_Customer_Orders'),
+    array('Mage_Adminhtml_Block_Report_Customer_Orders_Grid'),
+    array('Mage_Adminhtml_Block_Report_Product_Ordered'),
+    array('Mage_Adminhtml_Block_Report_Product_Ordered_Grid'),
+    array('Mage_Adminhtml_Block_Report_Review_Product_Grid'),
+    array('Mage_Adminhtml_Block_Report_Refresh_Statistics', 'Mage_Reports_Block_Adminhtml_Refresh_Statistics'),
+    array('Mage_Adminhtml_Block_Report_Refresh_Statistics_Grid'),
+    array('Mage_Adminhtml_Block_Sales'),
+    array('Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid_Renderer_Giftmessage'),
+    array('Mage_Adminhtml_Block_Sitemap_Grid'),
+    array('Mage_Adminhtml_Block_System_Config_Edit', 'Mage_Backend_Block_System_Config_Edit'),
+    array('Mage_Adminhtml_Block_System_Config_Form', 'Mage_Backend_Block_System_Config_Form'),
+    array('Mage_Adminhtml_Block_System_Config_Tabs', 'Mage_Backend_Block_System_Config_Tabs'),
+    array('Mage_Adminhtml_Block_System_Config_System_Storage_Media_Synchronize',
+        'Mage_Backend_Block_System_Config_System_Storage_Media_Synchronize'
+    ),
+    array('Mage_Adminhtml_Block_System_Config_Form_Fieldset_Modules_DisableOutput',
+        'Mage_Backend_Block_System_Config_Form_Fieldset_Modules_DisableOutput'
+    ),
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Regexceptions',
+        'Mage_Backend_Block_System_Config_Form_Field_Regexceptions'
+    ),
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Notification',
         'Mage_Backend_Block_System_Config_Form_Field_Notification'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Heading',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Heading',
         'Mage_Backend_Block_System_Config_Form_Field_Heading'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Datetime',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Datetime',
         'Mage_Backend_Block_System_Config_Form_Field_Datetime'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract',
         'Mage_Backend_Block_System_Config_Form_Field_Array_Abstract'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Fieldset',
+    array('Mage_Adminhtml_Block_System_Config_Form_Fieldset',
         'Mage_Backend_Block_System_Config_Form_Fieldset'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field',
         'Mage_Backend_Block_System_Config_Form_Field'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Import',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Import',
         'Mage_Backend_Block_System_Config_Form_Field_Import'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Image',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Image',
         'Mage_Backend_Block_System_Config_Form_Field_Image'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Export',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Export',
         'Mage_Backend_Block_System_Config_Form_Field_Export'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Select_Allowspecific',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Select_Allowspecific',
         'Mage_Backend_Block_System_Config_Form_Field_Select_Allowspecific'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_File',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_File',
         'Mage_Backend_Block_System_Config_Form_Field_File'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Select_Flatproduct',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Select_Flatproduct',
         'Mage_Catalog_Block_Adminhtml_System_Config_Form_Field_Select_Flatproduct'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Field_Select_Flatcatalog',
+    array('Mage_Adminhtml_Block_System_Config_Form_Field_Select_Flatcatalog',
         'Mage_Catalog_Block_Adminhtml_System_Config_Form_Field_Select_Flatcatalog'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Form_Fieldset_Order_Statuses',
+    array('Mage_Adminhtml_Block_System_Config_Form_Fieldset_Order_Statuses',
         'Mage_Sales_Block_Adminhtml_System_Config_Form_Fieldset_Order_Statuses'
-    ), $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Dwstree', 'Mage_Backend_Block_System_Config_Dwstree'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Config_Switcher', 'Mage_Backend_Block_System_Config_Switcher'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Design_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Email_Template_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Store_Switcher', 'Mage_Backend_Block_Store_Switcher'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Store_Switcher_Form_Renderer_Fieldset',
+    ),
+    array('Mage_Adminhtml_Block_System_Config_Dwstree', 'Mage_Backend_Block_System_Config_Dwstree'),
+    array('Mage_Adminhtml_Block_System_Config_Switcher', 'Mage_Backend_Block_System_Config_Switcher'),
+    array('Mage_Adminhtml_Block_System_Design_Grid'),
+    array('Mage_Adminhtml_Block_System_Email_Template_Grid'),
+    array('Mage_Adminhtml_Block_System_Variable_Grid'),
+    array('Mage_Adminhtml_Block_Store_Switcher', 'Mage_Backend_Block_Store_Switcher'),
+    array('Mage_Adminhtml_Block_Store_Switcher_Form_Renderer_Fieldset',
         'Mage_Backend_Block_Store_Switcher_Form_Renderer_Fieldset'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_Store_Switcher_Form_Renderer_Fieldset_Element',
+    array('Mage_Adminhtml_Block_Store_Switcher_Form_Renderer_Fieldset_Element',
         'Mage_Backend_Block_Store_Switcher_Form_Renderer_Fieldset_Element'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Block_Sitemap_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Tag_Tag_Edit'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Tag_Tag_Edit_Form'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Tax_Rate_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Tree'),
-    $this->_getClassRule('Mage_Adminhtml_Block_Urlrewrite_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Block_System_Variable_Grid'),
-    $this->_getClassRule('Mage_Adminhtml_Helper_Rss'),
-    $this->_getClassRule('Mage_Adminhtml_Model_Config', 'Mage_Backend_Model_Config_Structure'),
-    $this->_getClassRule('Mage_Adminhtml_Model_Config_Data', 'Mage_Backend_Model_Config'),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Shipping_Allowedmethods'),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Admin_Password_Link_Expirationperiod',
+    array('Mage_Adminhtml_Block_Tag_Tag_Edit'),
+    array('Mage_Adminhtml_Block_Tag_Tag_Edit_Form'),
+    array('Mage_Adminhtml_Block_Tax_Rate_Grid'),
+    array('Mage_Adminhtml_Block_Tree'),
+    array('Mage_Adminhtml_Block_Urlrewrite_Grid'),
+    array('Mage_Adminhtml_Helper_Rss'),
+    array('Mage_Adminhtml_Model_Config', 'Mage_Backend_Model_Config_Structure'),
+    array('Mage_Adminhtml_Model_Config_Data', 'Mage_Backend_Model_Config'),
+    array('Mage_Adminhtml_Model_Extension'),
+    array('Mage_Adminhtml_Model_System_Config_Source_Shipping_Allowedmethods'),
+    array('Mage_Adminhtml_Model_System_Config_Backend_Admin_Password_Link_Expirationperiod',
         'Mage_Backend_Model_Config_Backend_Admin_Password_Link_Expirationperiod'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Admin_Custom',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Admin_Custom',
         'Mage_Backend_Model_Config_Backend_Admin_Custom'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Admin_Custompath',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Admin_Custompath',
         'Mage_Backend_Model_Config_Backend_Admin_Custompath'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Admin_Observer',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Admin_Observer',
         'Mage_Backend_Model_Config_Backend_Admin_Observer'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Admin_Robots',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Admin_Robots',
         'Mage_Backend_Model_Config_Backend_Admin_Robots'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Admin_Usecustom',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Admin_Usecustom',
         'Mage_Backend_Model_Config_Backend_Admin_Usecustom'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Admin_Usecustompath',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Admin_Usecustompath',
         'Mage_Backend_Model_Config_Backend_Admin_Usecustompath'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Admin_Usesecretkey',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Admin_Usesecretkey',
         'Mage_Backend_Model_Config_Backend_Admin_Usesecretkey'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Catalog_Inventory_Managestock',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Catalog_Inventory_Managestock',
         'Mage_CatalogInventory_Model_Config_Backend_Managestock'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Catalog_Search_Type',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Catalog_Search_Type',
         'Mage_CatalogSearch_Model_Config_Backend_Search_Type'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Currency_Abstract',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Currency_Abstract',
         'Mage_Backend_Model_Config_Backend_Currency_Abstract'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Currency_Allow',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Currency_Allow',
         'Mage_Backend_Model_Config_Backend_Currency_Allow'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Currency_Base',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Currency_Base',
         'Mage_Backend_Model_Config_Backend_Currency_Base'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Currency_Cron',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Currency_Cron',
         'Mage_Backend_Model_Config_Backend_Currency_Cron'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Currency_Default',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Currency_Default',
         'Mage_Backend_Model_Config_Backend_Currency_Default'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Customer_Address_Street',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Customer_Address_Street',
         'Mage_Customer_Model_Config_Backend_Address_Street'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Customer_Password_Link_Expirationperiod',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Customer_Password_Link_Expirationperiod',
         'Mage_Customer_Model_Config_Backend_Password_Link_Expirationperiod'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Customer_Show_Address',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Customer_Show_Address',
         'Mage_Customer_Model_Config_Backend_Show_Address'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Customer_Show_Customer',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Customer_Show_Customer',
         'Mage_Customer_Model_Config_Backend_Show_Customer'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Design_Exception',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Design_Exception',
         'Mage_Backend_Model_Config_Backend_Design_Exception'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Email_Address',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Email_Address',
         'Mage_Backend_Model_Config_Backend_Email_Address'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Email_Logo',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Email_Logo',
         'Mage_Backend_Model_Config_Backend_Email_Logo'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Email_Sender',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Email_Sender',
         'Mage_Backend_Model_Config_Backend_Email_Sender'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Image_Adapter',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Image_Adapter',
         'Mage_Backend_Model_Config_Backend_Image_Adapter'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Image_Favicon',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Image_Favicon',
         'Mage_Backend_Model_Config_Backend_Image_Favicon'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Image_Pdf',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Image_Pdf',
         'Mage_Backend_Model_Config_Backend_Image_Pdf'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Locale_Timezone',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Locale_Timezone',
         'Mage_Backend_Model_Config_Backend_Locale_Timezone'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Log_Cron',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Log_Cron',
         'Mage_Backend_Model_Config_Backend_Log_Cron'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Price_Scope'),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Product_Alert_Cron',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Price_Scope'),
+    array('Mage_Adminhtml_Model_System_Config_Backend_Product_Alert_Cron',
         'Mage_Cron_Model_Config_Backend_Product_Alert'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Seo_Product',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Seo_Product',
         'Mage_Catalog_Model_Config_Backend_Seo_Product'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Serialized_Array',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Serialized_Array',
         'Mage_Backend_Model_Config_Backend_Serialized_Array'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Shipping_Tablerate',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Shipping_Tablerate',
         'Mage_Shipping_Model_Config_Backend_Tablerate'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Sitemap_Cron',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Sitemap_Cron',
         'Mage_Cron_Model_Config_Backend_Sitemap'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Storage_Media_Database',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Storage_Media_Database',
         'Mage_Backend_Model_Config_Backend_Storage_Media_Database'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Baseurl',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Baseurl',
         'Mage_Backend_Model_Config_Backend_Baseurl'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Cache',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Cache',
         'Mage_Backend_Model_Config_Backend_Cache'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Category',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Category',
         'Mage_Catalog_Model_Config_Backend_Category'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Cookie',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Cookie',
         'Mage_Backend_Model_Config_Backend_Cookie'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Datashare',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Datashare',
         'Mage_Backend_Model_Config_Backend_Datashare'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Encrypted',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Encrypted',
         'Mage_Backend_Model_Config_Backend_Encrypted'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_File',
+    array('Mage_Adminhtml_Model_System_Config_Backend_File',
         'Mage_Backend_Model_Config_Backend_File'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Filename',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Filename',
         'Mage_Backend_Model_Config_Backend_Filename'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Image',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Image',
         'Mage_Backend_Model_Config_Backend_Image'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Locale',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Locale',
         'Mage_Backend_Model_Config_Backend_Locale'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Secure',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Secure',
         'Mage_Backend_Model_Config_Backend_Secure'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Serialized',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Serialized',
         'Mage_Backend_Model_Config_Backend_Serialized'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Sitemap',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Sitemap',
         'Mage_Sitemap_Model_Config_Backend_Priority'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Store',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Store',
         'Mage_Backend_Model_Config_Backend_Store'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Backend_Translate',
+    array('Mage_Adminhtml_Model_System_Config_Backend_Translate',
         'Mage_Backend_Model_Config_Backend_Translate'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Clone_Media_Image',
+    array('Mage_Adminhtml_Model_System_Config_Clone_Media_Image',
         'Mage_Catalog_Model_Config_Clone_Media_Image'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Admin_Page',
+    array('Mage_Adminhtml_Model_System_Config_Source_Admin_Page',
         'Mage_Backend_Model_Config_Source_Admin_Page'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Catalog_Search_Type',
+    array('Mage_Adminhtml_Model_System_Config_Source_Catalog_Search_Type',
         'Mage_CatalogSearch_Model_Config_Source_Search_Type'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Catalog_GridPerPage',
+    array('Mage_Adminhtml_Model_System_Config_Source_Catalog_GridPerPage',
         'Mage_Catalog_Model_Config_Source_GridPerPage'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Catalog_ListMode',
+    array('Mage_Adminhtml_Model_System_Config_Source_Catalog_ListMode',
         'Mage_Catalog_Model_Config_Source_ListMode'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Catalog_ListPerPage',
+    array('Mage_Adminhtml_Model_System_Config_Source_Catalog_ListPerPage',
         'Mage_Catalog_Model_Config_Source_ListPerPage'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Catalog_ListSort',
+    array('Mage_Adminhtml_Model_System_Config_Source_Catalog_ListSort',
         'Mage_Catalog_Model_Config_Source_ListSort'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Catalog_TimeFormat',
+    array('Mage_Adminhtml_Model_System_Config_Source_Catalog_TimeFormat',
         'Mage_Catalog_Model_Config_Source_TimeFormat'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Cms_Wysiwyg_Enabled',
+    array('Mage_Adminhtml_Model_System_Config_Source_Cms_Wysiwyg_Enabled',
         'Mage_Cms_Model_Config_Source_Wysiwyg_Enabled'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Cms_Page',
+    array('Mage_Adminhtml_Model_System_Config_Source_Cms_Page',
         'Mage_Cms_Model_Config_Source_Page'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Country_Full',
+    array('Mage_Adminhtml_Model_System_Config_Source_Country_Full',
         'Mage_Directory_Model_Config_Source_Country_Full'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency',
+    array('Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency',
         'Mage_Cron_Model_Config_Source_Frequency'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Currency_Service',
+    array('Mage_Adminhtml_Model_System_Config_Source_Currency_Service',
         'Mage_Backend_Model_Config_Source_Currency'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Customer_Address_Type',
+    array('Mage_Adminhtml_Model_System_Config_Source_Customer_Address_Type',
         'Mage_Customer_Model_Config_Source_Address_Type'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Customer_Group_Multiselect',
+    array('Mage_Adminhtml_Model_System_Config_Source_Customer_Group_Multiselect',
         'Mage_Customer_Model_Config_Source_Group_Multiselect'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Customer_Group',
+    array('Mage_Adminhtml_Model_System_Config_Source_Customer_Group',
         'Mage_Customer_Model_Config_Source_Group'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Date_Short',
+    array('Mage_Adminhtml_Model_System_Config_Source_Date_Short',
         'Mage_Backend_Model_Config_Source_Date_Short'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Design_Package'),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Design_Robots',
+    array('Mage_Adminhtml_Model_System_Config_Source_Design_Package'),
+    array('Mage_Adminhtml_Model_System_Config_Source_Design_Robots',
         'Mage_Backend_Model_Config_Source_Design_Robots'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Dev_Dbautoup',
+    array('Mage_Adminhtml_Model_System_Config_Source_Dev_Dbautoup',
         'Mage_Backend_Model_Config_Source_Dev_Dbautoup'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Email_Identity',
+    array('Mage_Adminhtml_Model_System_Config_Source_Email_Identity',
         'Mage_Backend_Model_Config_Source_Email_Identity'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Email_Method',
+    array('Mage_Adminhtml_Model_System_Config_Source_Email_Method',
         'Mage_Backend_Model_Config_Source_Email_Method'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Email_Smtpauth',
+    array('Mage_Adminhtml_Model_System_Config_Source_Email_Smtpauth',
         'Mage_Backend_Model_Config_Source_Email_Smtpauth'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Email_Template',
+    array('Mage_Adminhtml_Model_System_Config_Source_Email_Template',
         'Mage_Backend_Model_Config_Source_Email_Template'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Image_Adapter',
+    array('Mage_Adminhtml_Model_System_Config_Source_Image_Adapter',
         'Mage_Backend_Model_Config_Source_Image_Adapter'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Locale_Country',
+    array('Mage_Adminhtml_Model_System_Config_Source_Locale_Country',
         'Mage_Backend_Model_Config_Source_Locale_Country'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Locale_Currency_All',
+    array('Mage_Adminhtml_Model_System_Config_Source_Locale_Currency_All',
         'Mage_Backend_Model_Config_Source_Locale_Currency_All'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Locale_Currency',
+    array('Mage_Adminhtml_Model_System_Config_Source_Locale_Currency',
         'Mage_Backend_Model_Config_Source_Locale_Currency'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Locale_Timezone',
+    array('Mage_Adminhtml_Model_System_Config_Source_Locale_Timezone',
         'Mage_Backend_Model_Config_Source_Locale_Timezone'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Locale_Weekdays',
+    array('Mage_Adminhtml_Model_System_Config_Source_Locale_Weekdays',
         'Mage_Backend_Model_Config_Source_Locale_Weekdays'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Notification_Frequency',
+    array('Mage_Adminhtml_Model_System_Config_Source_Notification_Frequency',
         'Mage_AdminNotification_Model_Config_Source_Frequency'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Order_Status_New',
+    array('Mage_Adminhtml_Model_System_Config_Source_Order_Status_New',
         'Mage_Sales_Model_Config_Source_Order_Status_New'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Order_Status_Newprocessing',
+    array('Mage_Adminhtml_Model_System_Config_Source_Order_Status_Newprocessing',
         'Mage_Sales_Model_Config_Source_Order_Status_Newprocessing'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Order_Status_Processing',
+    array('Mage_Adminhtml_Model_System_Config_Source_Order_Status_Processing',
         'Mage_Sales_Model_Config_Source_Order_Status_Processing'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Order_Status',
+    array('Mage_Adminhtml_Model_System_Config_Source_Order_Status',
         'Mage_Sales_Model_Config_Source_Order_Status'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Payment_Allmethods',
+    array('Mage_Adminhtml_Model_System_Config_Source_Payment_Allmethods',
         'Mage_Payment_Model_Config_Source_Allmethods'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Payment_Allowedmethods',
+    array('Mage_Adminhtml_Model_System_Config_Source_Payment_Allowedmethods',
         'Mage_Payment_Model_Config_Source_Allowedmethods'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Payment_Allspecificcountries',
+    array('Mage_Adminhtml_Model_System_Config_Source_Payment_Allspecificcountries',
         'Mage_Payment_Model_Config_Source_Allspecificcountries'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Payment_Cctype',
+    array('Mage_Adminhtml_Model_System_Config_Source_Payment_Cctype',
         'Mage_Payment_Model_Config_Source_Cctype'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Price_Scope',
+    array('Mage_Adminhtml_Model_System_Config_Source_Price_Scope',
         'Mage_Catalog_Model_Config_Source_Price_Scope'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Price_Step',
+    array('Mage_Adminhtml_Model_System_Config_Source_Price_Step',
         'Mage_Catalog_Model_Config_Source_Price_Step'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Product_Options_Price',
+    array('Mage_Adminhtml_Model_System_Config_Source_Product_Options_Price',
         'Mage_Catalog_Model_Config_Source_Product_Options_Price'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Product_Options_Type',
+    array('Mage_Adminhtml_Model_System_Config_Source_Product_Options_Type',
         'Mage_Catalog_Model_Config_Source_Product_Options_Type'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Product_Thumbnail',
+    array('Mage_Adminhtml_Model_System_Config_Source_Product_Thumbnail',
         'Mage_Catalog_Model_Config_Source_Product_Thumbnail'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Reports_Scope',
+    array('Mage_Adminhtml_Model_System_Config_Source_Reports_Scope',
         'Mage_Backend_Model_Config_Source_Reports_Scope'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Shipping_Allmethods',
+    array('Mage_Adminhtml_Model_System_Config_Source_Shipping_Allmethods',
         'Mage_Shipping_Model_Config_Source_Allmethods'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Shipping_Allspecificcountries',
+    array('Mage_Adminhtml_Model_System_Config_Source_Shipping_Allspecificcountries',
         'Mage_Shipping_Model_Config_Source_Allspecificcountries'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Shipping_Flatrate',
+    array('Mage_Adminhtml_Model_System_Config_Source_Shipping_Flatrate',
         'Mage_Shipping_Model_Config_Source_Flatrate'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Shipping_Tablerate',
+    array('Mage_Adminhtml_Model_System_Config_Source_Shipping_Tablerate',
         'Mage_Shipping_Model_Config_Source_Tablerate'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Shipping_Taxclass',
+    array('Mage_Adminhtml_Model_System_Config_Source_Shipping_Taxclass',
         'Mage_Tax_Model_Config_Source_Class_Product'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Storage_Media_Database',
+    array('Mage_Adminhtml_Model_System_Config_Source_Storage_Media_Database',
         'Mage_Backend_Model_Config_Source_Storage_Media_Database'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Storage_Media_Storage',
+    array('Mage_Adminhtml_Model_System_Config_Source_Storage_Media_Storage',
         'Mage_Backend_Model_Config_Source_Storage_Media_Storage'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Tax_Apply_On',
+    array('Mage_Adminhtml_Model_System_Config_Source_Tax_Apply_On',
         'Mage_Tax_Model_Config_Source_Apply_On'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Tax_Basedon',
+    array('Mage_Adminhtml_Model_System_Config_Source_Tax_Basedon',
         'Mage_Tax_Model_Config_Source_Basedon'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Tax_Catalog',
+    array('Mage_Adminhtml_Model_System_Config_Source_Tax_Catalog',
         'Mage_Tax_Model_Config_Source_Catalog'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Watermark_Position',
+    array('Mage_Adminhtml_Model_System_Config_Source_Watermark_Position',
         'Mage_Catalog_Model_Config_Source_Watermark_Position'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Web_Protocol',
+    array('Mage_Adminhtml_Model_System_Config_Source_Web_Protocol',
         'Mage_Backend_Model_Config_Source_Web_Protocol'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Web_Redirect',
+    array('Mage_Adminhtml_Model_System_Config_Source_Web_Redirect',
         'Mage_Backend_Model_Config_Source_Web_Redirect'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Allregion',
+    array('Mage_Adminhtml_Model_System_Config_Source_Allregion',
         'Mage_Directory_Model_Config_Source_Allregion'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Category',
+    array('Mage_Adminhtml_Model_System_Config_Source_Category',
         'Mage_Catalog_Model_Config_Source_Category'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Checktype',
+    array('Mage_Adminhtml_Model_System_Config_Source_Checktype',
         'Mage_Backend_Model_Config_Source_Checktype'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Country',
+    array('Mage_Adminhtml_Model_System_Config_Source_Country',
         'Mage_Directory_Model_Config_Source_Country'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Currency',
+    array('Mage_Adminhtml_Model_System_Config_Source_Currency',
         'Mage_Backend_Model_Config_Source_Currency'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Enabledisable',
+    array('Mage_Adminhtml_Model_System_Config_Source_Enabledisable',
         'Mage_Backend_Model_Config_Source_Enabledisable'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Frequency',
+    array('Mage_Adminhtml_Model_System_Config_Source_Frequency',
         'Mage_Sitemap_Model_Config_Source_Frequency'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Locale',
+    array('Mage_Adminhtml_Model_System_Config_Source_Locale',
         'Mage_Backend_Model_Config_Source_Locale'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Nooptreq',
+    array('Mage_Adminhtml_Model_System_Config_Source_Nooptreq',
         'Mage_Backend_Model_Config_Source_Nooptreq'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Store',
+    array('Mage_Adminhtml_Model_System_Config_Source_Store',
         'Mage_Backend_Model_Config_Source_Store'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Website',
+    array('Mage_Adminhtml_Model_System_Config_Source_Website',
         'Mage_Backend_Model_Config_Source_Website'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Yesno', 'Mage_Backend_Model_Config_Source_Yesno'),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Config_Source_Yesnocustom',
+    array('Mage_Adminhtml_Model_System_Config_Source_Yesno', 'Mage_Backend_Model_Config_Source_Yesno'),
+    array('Mage_Adminhtml_Model_System_Config_Source_Yesnocustom',
         'Mage_Backend_Model_Config_Source_Yesnocustom'
     ),
-    $this->_getClassRule('Mage_Adminhtml_Model_System_Store', 'Mage_Core_Model_System_Store'),
-    $this->_getClassRule('Mage_Adminhtml_Model_Url', 'Mage_Backend_Model_Url'),
-    $this->_getClassRule('Mage_Adminhtml_Rss_CatalogController'),
-    $this->_getClassRule('Mage_Adminhtml_Rss_OrderController'),
-    $this->_getClassRule('Mage_Adminhtml_SystemController', 'Mage_Backend_Adminhtml_SystemController'),
-    $this->_getClassRule('Mage_Adminhtml_System_ConfigController', 'Mage_Backend_Adminhtml_System_ConfigController'),
-    $this->_getClassRule('Mage_Bundle_Product_EditController', 'Mage_Bundle_Adminhtml_Bundle_SelectionController'),
-    $this->_getClassRule('Mage_Bundle_SelectionController', 'Mage_Bundle_Adminhtml_Bundle_SelectionController'),
-    $this->_getClassRule('Mage_Catalog_Model_Convert'),
-    $this->_getClassRule('Mage_Catalog_Model_Convert_Adapter_Catalog'),
-    $this->_getClassRule('Mage_Catalog_Model_Convert_Adapter_Product'),
-    $this->_getClassRule('Mage_Catalog_Model_Convert_Parser_Product'),
-    $this->_getClassRule('Mage_Catalog_Model_Entity_Product_Attribute_Frontend_Image'),
-    $this->_getClassRule('Mage_Catalog_Model_Resource_Product_Attribute_Frontend_Image'),
-    $this->_getClassRule('Mage_Catalog_Model_Resource_Product_Attribute_Frontend_Tierprice'),
-    $this->_getClassRule('Mage_Core_Block_Flush'),
-    $this->_getClassRule('Mage_Core_Block_Template_Facade'),
-    $this->_getClassRule('Mage_Core_Controller_Varien_Router_Admin', 'Mage_Backend_Controller_Router_Default'),
-    $this->_getClassRule('Mage_Core_Model_Convert'),
-    $this->_getClassRule('Mage_Core_Model_Config_System'),
-    $this->_getClassRule('Mage_Core_Model_Design_Source_Apply'),
-    $this->_getClassRule('Mage_Core_Model_Language'),
-    $this->_getClassRule('Mage_Core_Model_Resource_Language'),
-    $this->_getClassRule('Mage_Core_Model_Resource_Language_Collection'),
-    $this->_getClassRule('Mage_Core_Model_Session_Abstract_Varien'),
-    $this->_getClassRule('Mage_Core_Model_Session_Abstract_Zend'),
-    $this->_getClassRule('Mage_Core_Model_Layout_Data', 'Mage_Core_Model_Layout_Update'),
-    $this->_getClassRule('Mage_Customer_Block_Account'),
-    $this->_getClassRule('Mage_Customer_Model_Convert_Adapter_Customer'),
-    $this->_getClassRule('Mage_Customer_Model_Convert_Parser_Customer'),
-    $this->_getClassRule('Mage_Directory_Model_Resource_Currency_Collection'),
-    $this->_getClassRule('Mage_Downloadable_FileController', 'Mage_Downloadable_Adminhtml_Downloadable_FileController'),
-    $this->_getClassRule('Mage_Downloadable_Product_EditController', 'Mage_Adminhtml_Catalog_ProductController'),
-    $this->_getClassRule('Mage_Eav_Model_Convert_Adapter_Entity'),
-    $this->_getClassRule('Mage_Eav_Model_Convert_Adapter_Grid'),
-    $this->_getClassRule('Mage_Eav_Model_Convert_Parser_Abstract'),
-    $this->_getClassRule('Mage_GiftMessage_Block_Message_Form'),
-    $this->_getClassRule('Mage_GiftMessage_Block_Message_Helper'),
-    $this->_getClassRule('Mage_GiftMessage_IndexController'),
-    $this->_getClassRule('Mage_GiftMessage_Model_Entity_Attribute_Backend_Boolean_Config'),
-    $this->_getClassRule('Mage_GiftMessage_Model_Entity_Attribute_Source_Boolean_Config'),
-    $this->_getClassRule('Mage_GoogleOptimizer_IndexController',
+    array('Mage_Adminhtml_Model_System_Store', 'Mage_Core_Model_System_Store'),
+    array('Mage_Adminhtml_Block_System_Store_Grid'),
+    array('Mage_Adminhtml_Model_Url', 'Mage_Backend_Model_Url'),
+    array('Mage_Adminhtml_Rss_CatalogController'),
+    array('Mage_Adminhtml_Rss_OrderController'),
+    array('Mage_Adminhtml_SystemController', 'Mage_Backend_Adminhtml_SystemController'),
+    array('Mage_Adminhtml_System_ConfigController', 'Mage_Backend_Adminhtml_System_ConfigController'),
+    array('Mage_Bundle_Product_EditController', 'Mage_Bundle_Adminhtml_Bundle_SelectionController'),
+    array('Mage_Bundle_SelectionController', 'Mage_Bundle_Adminhtml_Bundle_SelectionController'),
+    array('Mage_Catalog_Model_Convert'),
+    array('Mage_Catalog_Model_Convert_Adapter_Catalog'),
+    array('Mage_Catalog_Model_Convert_Adapter_Product'),
+    array('Mage_Catalog_Model_Convert_Parser_Product'),
+    array('Mage_Catalog_Model_Entity_Product_Attribute_Frontend_Image'),
+    array('Mage_Catalog_Model_Resource_Product_Attribute_Frontend_Image'),
+    array('Mage_Catalog_Model_Resource_Product_Attribute_Frontend_Tierprice'),
+    array('Mage_Core_Block_Flush'),
+    array('Mage_Core_Block_Template_Facade'),
+    array('Mage_Core_Block_Template_Smarty'),
+    array('Mage_Core_Block_Template_Zend'),
+    array('Mage_Core_Controller_Varien_Router_Admin', 'Mage_Backend_Controller_Router_Default'),
+    array('Mage_Core_Model_Convert'),
+    array('Mage_Core_Model_Config_Options', 'Mage_Core_Model_Dir'),
+    array('Mage_Core_Model_Config_System'),
+    array('Mage_Core_Model_Design_Source_Apply'),
+    array('Mage_Core_Model_Language'),
+    array('Mage_Core_Model_Resource_Language'),
+    array('Mage_Core_Model_Resource_Language_Collection'),
+    array('Mage_Core_Model_Session_Abstract_Varien'),
+    array('Mage_Core_Model_Session_Abstract_Zend'),
+    array('Mage_Core_Model_Layout_Data', 'Mage_Core_Model_Layout_Update'),
+    array('Mage_Customer_Block_Account'),
+    array('Mage_Customer_Model_Convert_Adapter_Customer'),
+    array('Mage_Customer_Model_Convert_Parser_Customer'),
+    array('Mage_Directory_Model_Resource_Currency_Collection'),
+    array('Mage_Downloadable_FileController', 'Mage_Downloadable_Adminhtml_Downloadable_FileController'),
+    array('Mage_Downloadable_Product_EditController', 'Mage_Adminhtml_Catalog_ProductController'),
+    array('Mage_Eav_Model_Convert_Adapter_Entity'),
+    array('Mage_Eav_Model_Convert_Adapter_Grid'),
+    array('Mage_Eav_Model_Convert_Parser_Abstract'),
+    array('Mage_GiftMessage_Block_Message_Form'),
+    array('Mage_GiftMessage_Block_Message_Helper'),
+    array('Mage_GiftMessage_IndexController'),
+    array('Mage_GiftMessage_Model_Entity_Attribute_Backend_Boolean_Config'),
+    array('Mage_GiftMessage_Model_Entity_Attribute_Source_Boolean_Config'),
+    array('Mage_GoogleOptimizer_IndexController',
         'Mage_GoogleOptimizer_Adminhtml_Googleoptimizer_IndexController'),
-    $this->_getClassRule('Mage_ImportExport_Model_Import_Adapter_Abstract',
+    array('Mage_ImportExport_Model_Import_Adapter_Abstract',
         'Mage_ImportExport_Model_Import_SourceAbstract'),
-    $this->_getClassRule('Mage_ImportExport_Model_Import_Adapter_Csv', 'Mage_ImportExport_Model_Import_Source_Csv'),
-    $this->_getClassRule('Mage_Ogone_Model_Api_Debug'),
-    $this->_getClassRule('Mage_Ogone_Model_Resource_Api_Debug'),
-    $this->_getClassRule('Mage_Page_Block_Html_Toplinks'),
-    $this->_getClassRule('Mage_Page_Block_Html_Wrapper'),
-    $this->_getClassRule('Mage_Poll_Block_Poll'),
-    $this->_getClassRule('Mage_ProductAlert_Block_Price'),
-    $this->_getClassRule('Mage_ProductAlert_Block_Stock'),
-    $this->_getClassRule('Mage_Reports_Model_Resource_Coupons_Collection'),
-    $this->_getClassRule('Mage_Reports_Model_Resource_Invoiced_Collection'),
-    $this->_getClassRule('Mage_Reports_Model_Resource_Product_Ordered_Collection'),
-    $this->_getClassRule('Mage_Reports_Model_Resource_Product_Viewed_Collection',
+    array('Mage_ImportExport_Model_Import_Adapter_Csv',
+        'Mage_ImportExport_Model_Import_Source_Csv'),
+    array('Mage_Ogone_Model_Api_Debug'),
+    array('Mage_Ogone_Model_Resource_Api_Debug'),
+    array('Mage_Page_Block_Html_Toplinks'),
+    array('Mage_Page_Block_Html_Wrapper'),
+    array('Mage_Poll_Block_Poll'),
+    array('Mage_ProductAlert_Block_Price'),
+    array('Mage_ProductAlert_Block_Stock'),
+    array('Mage_Reports_Model_Resource_Coupons_Collection'),
+    array('Mage_Reports_Model_Resource_Invoiced_Collection'),
+    array('Mage_Reports_Model_Resource_Product_Ordered_Collection'),
+    array('Mage_Reports_Model_Resource_Product_Viewed_Collection',
         'Mage_Reports_Model_Resource_Report_Product_Viewed_Collection'),
-    $this->_getClassRule('Mage_Reports_Model_Resource_Refunded_Collection'),
-    $this->_getClassRule('Mage_Reports_Model_Resource_Shipping_Collection'),
-    $this->_getClassRule('Mage_Rss_Model_Observer'),
-    $this->_getClassRule('Mage_Rss_Model_Session', 'Mage_Backend_Model_Auth and Mage_Backend_Model_Auth_Session'),
-    $this->_getClassRule('Mage_Sales_Block_Order_Details'),
-    $this->_getClassRule('Mage_Sales_Block_Order_Tax'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Address'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Address_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Attribute_Backend_Billing'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Attribute_Backend_Child'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Attribute_Backend_Parent'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Attribute_Backend_Shipping'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Creditmemo'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Creditmemo_Attribute_Backend_Child'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Creditmemo_Attribute_Backend_Parent'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Creditmemo_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Creditmemo_Comment'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Creditmemo_Comment_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Creditmemo_Item'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Creditmemo_Item_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Attribute_Backend_Child'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Attribute_Backend_Item'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Attribute_Backend_Order'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Attribute_Backend_Parent'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Comment'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Comment_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Item'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Invoice_Item_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Item'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Item_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Payment'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Payment_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Attribute_Backend_Child'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Attribute_Backend_Parent'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Comment'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Comment_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Item'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Item_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Track'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Shipment_Track_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Status_History'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Order_Status_History_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Backend'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Backend_Child'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Backend_Parent'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Backend_Region'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Custbalance'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Discount'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Grand'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Shipping'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Subtotal'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Tax'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Item'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Item_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Rate'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Address_Rate_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Item'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Item_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Payment'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Quote_Payment_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Sale_Collection'),
-    $this->_getClassRule('Mage_Sales_Model_Entity_Setup'),
-    $this->_getClassRule('Mage_Shipping_ShippingController'),
-    $this->_getClassRule('Mage_Tag_Block_Customer_Edit'),
-    $this->_getClassRule('Mage_User_Block_Role_Grid'),
-    $this->_getClassRule('Mage_User_Block_User_Grid'),
-    $this->_getClassRule('Mage_User_Model_Roles'),
-    $this->_getClassRule('Mage_User_Model_Resource_Roles'),
-    $this->_getClassRule('Mage_User_Model_Resource_Roles_Collection'),
-    $this->_getClassRule('Mage_User_Model_Resource_Roles_User_Collection'),
-    $this->_getClassRule('Mage_Wishlist_Model_Resource_Product_Collection'),
-    $this->_getClassRule('Varien_Convert_Action'),
-    $this->_getClassRule('Varien_Convert_Action_Abstract'),
-    $this->_getClassRule('Varien_Convert_Action_Interface'),
-    $this->_getClassRule('Varien_Convert_Adapter_Abstract'),
-    $this->_getClassRule('Varien_Convert_Adapter_Db_Table'),
-    $this->_getClassRule('Varien_Convert_Adapter_Http'),
-    $this->_getClassRule('Varien_Convert_Adapter_Http_Curl'),
-    $this->_getClassRule('Varien_Convert_Adapter_Interface'),
-    $this->_getClassRule('Varien_Convert_Adapter_Io'),
-    $this->_getClassRule('Varien_Convert_Adapter_Soap'),
-    $this->_getClassRule('Varien_Convert_Adapter_Std'),
-    $this->_getClassRule('Varien_Convert_Adapter_Zend_Cache'),
-    $this->_getClassRule('Varien_Convert_Adapter_Zend_Db'),
-    $this->_getClassRule('Varien_Convert_Container_Collection'),
-    $this->_getClassRule('Varien_Convert_Container_Generic'),
-    $this->_getClassRule('Varien_Convert_Container_Interface'),
-    $this->_getClassRule('Varien_Convert_Mapper_Abstract'),
-    $this->_getClassRule('Varien_Convert_Parser_Abstract'),
-    $this->_getClassRule('Varien_Convert_Parser_Csv'),
-    $this->_getClassRule('Varien_Convert_Parser_Interface'),
-    $this->_getClassRule('Varien_Convert_Parser_Serialize'),
-    $this->_getClassRule('Varien_Convert_Parser_Xml_Excel'),
-    $this->_getClassRule('Varien_Convert_Profile'),
-    $this->_getClassRule('Varien_Convert_Profile_Abstract'),
-    $this->_getClassRule('Varien_Convert_Profile_Collection'),
-    $this->_getClassRule('Varien_Convert_Validator_Abstract'),
-    $this->_getClassRule('Varien_Convert_Validator_Column'),
-    $this->_getClassRule('Varien_Convert_Validator_Dryrun'),
-    $this->_getClassRule('Varien_Convert_Validator_Interface'),
-    $this->_getClassRule('Varien_File_Uploader_Image'),
-    $this->_getClassRule('Varien_Profiler', 'Magento_Profiler'),
+    array('Mage_Reports_Model_Resource_Refunded_Collection'),
+    array('Mage_Reports_Model_Resource_Shipping_Collection'),
+    array('Mage_Rss_Model_Observer'),
+    array('Mage_Rss_Model_Session', 'Mage_Backend_Model_Auth and Mage_Backend_Model_Auth_Session'),
+    array('Mage_Sales_Block_Order_Details'),
+    array('Mage_Sales_Block_Order_Tax'),
+    array('Mage_Sales_Model_Entity_Order'),
+    array('Mage_Sales_Model_Entity_Order_Address'),
+    array('Mage_Sales_Model_Entity_Order_Address_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Attribute_Backend_Billing'),
+    array('Mage_Sales_Model_Entity_Order_Attribute_Backend_Child'),
+    array('Mage_Sales_Model_Entity_Order_Attribute_Backend_Parent'),
+    array('Mage_Sales_Model_Entity_Order_Attribute_Backend_Shipping'),
+    array('Mage_Sales_Model_Entity_Order_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Creditmemo'),
+    array('Mage_Sales_Model_Entity_Order_Creditmemo_Attribute_Backend_Child'),
+    array('Mage_Sales_Model_Entity_Order_Creditmemo_Attribute_Backend_Parent'),
+    array('Mage_Sales_Model_Entity_Order_Creditmemo_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Creditmemo_Comment'),
+    array('Mage_Sales_Model_Entity_Order_Creditmemo_Comment_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Creditmemo_Item'),
+    array('Mage_Sales_Model_Entity_Order_Creditmemo_Item_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Invoice'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Attribute_Backend_Child'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Attribute_Backend_Item'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Attribute_Backend_Order'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Attribute_Backend_Parent'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Comment'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Comment_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Item'),
+    array('Mage_Sales_Model_Entity_Order_Invoice_Item_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Item'),
+    array('Mage_Sales_Model_Entity_Order_Item_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Payment'),
+    array('Mage_Sales_Model_Entity_Order_Payment_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Shipment'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Attribute_Backend_Child'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Attribute_Backend_Parent'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Comment'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Comment_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Item'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Item_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Track'),
+    array('Mage_Sales_Model_Entity_Order_Shipment_Track_Collection'),
+    array('Mage_Sales_Model_Entity_Order_Status_History'),
+    array('Mage_Sales_Model_Entity_Order_Status_History_Collection'),
+    array('Mage_Sales_Model_Entity_Quote'),
+    array('Mage_Sales_Model_Entity_Quote_Address'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Backend'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Backend_Child'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Backend_Parent'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Backend_Region'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Custbalance'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Discount'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Grand'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Shipping'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Subtotal'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Attribute_Frontend_Tax'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Collection'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Item'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Item_Collection'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Rate'),
+    array('Mage_Sales_Model_Entity_Quote_Address_Rate_Collection'),
+    array('Mage_Sales_Model_Entity_Quote_Collection'),
+    array('Mage_Sales_Model_Entity_Quote_Item'),
+    array('Mage_Sales_Model_Entity_Quote_Item_Collection'),
+    array('Mage_Sales_Model_Entity_Quote_Payment'),
+    array('Mage_Sales_Model_Entity_Quote_Payment_Collection'),
+    array('Mage_Sales_Model_Entity_Sale_Collection'),
+    array('Mage_Sales_Model_Entity_Setup'),
+    array('Mage_Shipping_ShippingController'),
+    array('Mage_Tag_Block_Customer_Edit'),
+    array('Mage_User_Block_Role_Grid'),
+    array('Mage_User_Block_User_Grid'),
+    array('Mage_User_Model_Roles'),
+    array('Mage_User_Model_Resource_Roles'),
+    array('Mage_User_Model_Resource_Roles_Collection'),
+    array('Mage_User_Model_Resource_Roles_User_Collection'),
+    array('Mage_Wishlist_Model_Resource_Product_Collection'),
+    array('Varien_Convert_Action'),
+    array('Varien_Convert_Action_Abstract'),
+    array('Varien_Convert_Action_Interface'),
+    array('Varien_Convert_Adapter_Abstract'),
+    array('Varien_Convert_Adapter_Db_Table'),
+    array('Varien_Convert_Adapter_Http'),
+    array('Varien_Convert_Adapter_Http_Curl'),
+    array('Varien_Convert_Adapter_Interface'),
+    array('Varien_Convert_Adapter_Io'),
+    array('Varien_Convert_Adapter_Soap'),
+    array('Varien_Convert_Adapter_Std'),
+    array('Varien_Convert_Adapter_Zend_Cache'),
+    array('Varien_Convert_Adapter_Zend_Db'),
+    array('Varien_Convert_Container_Collection'),
+    array('Varien_Convert_Container_Generic'),
+    array('Varien_Convert_Container_Interface'),
+    array('Varien_Convert_Mapper_Abstract'),
+    array('Varien_Convert_Parser_Abstract'),
+    array('Varien_Convert_Parser_Csv'),
+    array('Varien_Convert_Parser_Interface'),
+    array('Varien_Convert_Parser_Serialize'),
+    array('Varien_Convert_Parser_Xml_Excel'),
+    array('Varien_Convert_Profile'),
+    array('Varien_Convert_Profile_Abstract'),
+    array('Varien_Convert_Profile_Collection'),
+    array('Varien_Convert_Validator_Abstract'),
+    array('Varien_Convert_Validator_Column'),
+    array('Varien_Convert_Validator_Dryrun'),
+    array('Varien_Convert_Validator_Interface'),
+    array('Varien_File_Uploader_Image'),
+    array('Varien_Profiler', 'Magento_Profiler'),
 );
diff --git a/dev/tests/static/testsuite/Legacy/_files/obsolete_constants.php b/dev/tests/static/testsuite/Legacy/_files/obsolete_constants.php
index 1d241ab1d25..be48adab35a 100644
--- a/dev/tests/static/testsuite/Legacy/_files/obsolete_constants.php
+++ b/dev/tests/static/testsuite/Legacy/_files/obsolete_constants.php
@@ -1,5 +1,9 @@
 <?php
 /**
+ * Obsolete constants
+ *
+ * Format: array(<constant_name>[, <class_scope> = ''[, <replacement>]])
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -18,50 +22,48 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    tests
- * @package     static
- * @subpackage  Legacy
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 return array(
-    $this->_getRule('GALLERY_IMAGE_TABLE', 'Mage_Catalog_Model_Resource_Product_Attribute_Backend_Media'),
-    $this->_getRule('DEFAULT_VALUE_TABLE_PREFIX'),
-    $this->_getRule('CATEGORY_APPLY_CATEGORY_AND_PRODUCT_RECURSIVE'),
-    $this->_getRule('CATEGORY_APPLY_CATEGORY_ONLY'),
-    $this->_getRule('CATEGORY_APPLY_CATEGORY_AND_PRODUCT_ONLY'),
-    $this->_getRule('CATEGORY_APPLY_CATEGORY_RECURSIVE'),
-    $this->_getRule('BACKORDERS_BELOW'),
-    $this->_getRule('BACKORDERS_YES'),
-    $this->_getRule('XML_PATH_DEFAULT_COUNTRY', 'Mage_Core_Model_Locale'),
-    $this->_getRule('XML_PATH_SENDING_SET_RETURN_PATH', 'Mage_Newsletter_Model_Subscriber'),
-    $this->_getRule('CHECKSUM_KEY_NAME'),
-    $this->_getRule('XML_PATH_COUNTRY_DEFAULT', 'Mage_Paypal_Model_System_Config_Backend_MerchantCountry'),
-    $this->_getRule('ENTITY_PRODUCT', 'Mage_Review_Model_Review'),
-    $this->_getRule('CHECKOUT_METHOD_REGISTER'),
-    $this->_getRule('CHECKOUT_METHOD_GUEST'),
-    $this->_getRule('CONFIG_XML_PATH_SHOW_IN_CATALOG'),
-    $this->_getRule('CONFIG_XML_PATH_DEFAULT_PRODUCT_TAX_GROUP'),
-    $this->_getRule('CONFIG_XML_PATH_DISPLAY_TAX_COLUMN'),
-    $this->_getRule('CONFIG_XML_PATH_DISPLAY_FULL_SUMMARY'),
-    $this->_getRule('CONFIG_XML_PATH_DISPLAY_ZERO_TAX'),
-    $this->_getRule('EXCEPTION_CODE_IS_GROUPED_PRODUCT'),
-    $this->_getRule('Mage_Rss_Block_Catalog_NotifyStock::CACHE_TAG'),
-    $this->_getRule('Mage_Rss_Block_Catalog_Review::CACHE_TAG'),
-    $this->_getRule('Mage_Rss_Block_Order_New::CACHE_TAG'),
-    $this->_getRule('REGISTRY_FORM_PARAMS_KEY', null, 'direct value'),
-    $this->_getRule('TYPE_TINYINT', null, 'Varien_Db_Ddl_Table::TYPE_SMALLINT'),
-    $this->_getRule('TYPE_CHAR', null, 'Varien_Db_Ddl_Table::TYPE_TEXT'),
-    $this->_getRule('TYPE_VARCHAR', null, 'Varien_Db_Ddl_Table::TYPE_TEXT'),
-    $this->_getRule('TYPE_LONGVARCHAR', null, 'Varien_Db_Ddl_Table::TYPE_TEXT'),
-    $this->_getRule('TYPE_CLOB', null, 'Varien_Db_Ddl_Table::TYPE_TEXT'),
-    $this->_getRule('TYPE_DOUBLE', null, 'Varien_Db_Ddl_Table::TYPE_FLOAT'),
-    $this->_getRule('TYPE_REAL', null, 'Varien_Db_Ddl_Table::TYPE_FLOAT'),
-    $this->_getRule('TYPE_TIME', null, 'Varien_Db_Ddl_Table::TYPE_TIMESTAMP'),
-    $this->_getRule('TYPE_BINARY', null, 'Varien_Db_Ddl_Table::TYPE_BLOB'),
-    $this->_getRule('TYPE_LONGVARBINARY', null, 'Varien_Db_Ddl_Table::TYPE_BLOB'),
-    $this->_getRule('HASH_ALGO'),
-    $this->_getRule('SEESION_MAX_COOKIE_LIFETIME'),
-    $this->_getRule('URL_TYPE_SKIN'),
-    $this->_getRule('DEFAULT_THEME_NAME', 'Mage_Core_Model_Design_Package'),
+    array('GALLERY_IMAGE_TABLE', 'Mage_Catalog_Model_Resource_Product_Attribute_Backend_Media'),
+    array('DEFAULT_VALUE_TABLE_PREFIX'),
+    array('CATEGORY_APPLY_CATEGORY_AND_PRODUCT_RECURSIVE'),
+    array('CATEGORY_APPLY_CATEGORY_ONLY'),
+    array('CATEGORY_APPLY_CATEGORY_AND_PRODUCT_ONLY'),
+    array('CATEGORY_APPLY_CATEGORY_RECURSIVE'),
+    array('BACKORDERS_BELOW'),
+    array('BACKORDERS_YES'),
+    array('XML_PATH_DEFAULT_COUNTRY', 'Mage_Core_Model_Locale'),
+    array('XML_PATH_SENDING_SET_RETURN_PATH', 'Mage_Newsletter_Model_Subscriber'),
+    array('CHECKSUM_KEY_NAME'),
+    array('XML_PATH_COUNTRY_DEFAULT', 'Mage_Paypal_Model_System_Config_Backend_MerchantCountry'),
+    array('ENTITY_PRODUCT', 'Mage_Review_Model_Review'),
+    array('CHECKOUT_METHOD_REGISTER'),
+    array('CHECKOUT_METHOD_GUEST'),
+    array('CONFIG_XML_PATH_SHOW_IN_CATALOG'),
+    array('CONFIG_XML_PATH_DEFAULT_PRODUCT_TAX_GROUP'),
+    array('CONFIG_XML_PATH_DISPLAY_TAX_COLUMN'),
+    array('CONFIG_XML_PATH_DISPLAY_FULL_SUMMARY'),
+    array('CONFIG_XML_PATH_DISPLAY_ZERO_TAX'),
+    array('EXCEPTION_CODE_IS_GROUPED_PRODUCT'),
+    array('Mage_Rss_Block_Catalog_NotifyStock::CACHE_TAG'),
+    array('Mage_Rss_Block_Catalog_Review::CACHE_TAG'),
+    array('Mage_Rss_Block_Order_New::CACHE_TAG'),
+    array('REGISTRY_FORM_PARAMS_KEY', null, 'direct value'),
+    array('TYPE_TINYINT', null, 'Varien_Db_Ddl_Table::TYPE_SMALLINT'),
+    array('TYPE_CHAR', null, 'Varien_Db_Ddl_Table::TYPE_TEXT'),
+    array('TYPE_VARCHAR', null, 'Varien_Db_Ddl_Table::TYPE_TEXT'),
+    array('TYPE_LONGVARCHAR', null, 'Varien_Db_Ddl_Table::TYPE_TEXT'),
+    array('TYPE_CLOB', null, 'Varien_Db_Ddl_Table::TYPE_TEXT'),
+    array('TYPE_DOUBLE', null, 'Varien_Db_Ddl_Table::TYPE_FLOAT'),
+    array('TYPE_REAL', null, 'Varien_Db_Ddl_Table::TYPE_FLOAT'),
+    array('TYPE_TIME', null, 'Varien_Db_Ddl_Table::TYPE_TIMESTAMP'),
+    array('TYPE_BINARY', null, 'Varien_Db_Ddl_Table::TYPE_BLOB'),
+    array('TYPE_LONGVARBINARY', null, 'Varien_Db_Ddl_Table::TYPE_BLOB'),
+    array('HASH_ALGO'),
+    array('SEESION_MAX_COOKIE_LIFETIME'),
+    array('URL_TYPE_SKIN'),
+    array('INSTALLER_HOST_RESPONSE', 'Mage_Install_Model_Installer'),
+    array('DEFAULT_THEME_NAME', 'Mage_Core_Model_Design_Package'),
 );
diff --git a/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php
index 82e82106bcf..7112523adc1 100644
--- a/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Legacy/_files/obsolete_methods.php
@@ -1,5 +1,9 @@
 <?php
 /**
+ * Obsolete methods
+ *
+ * Format: array(<method_name = ''>[, <class_scope> = ''[, <replacement>]])
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -18,413 +22,417 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    tests
- * @package     static
- * @subpackage  Legacy
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
-/** @var $this Legacy_ObsoleteCodeTest */
 return array(
-    $this->_getRule('__get', 'Varien_Object'),
-    $this->_getRule('__set', 'Varien_Object'),
-    $this->_getRule('_addMinimalPrice', 'Mage_Catalog_Model_Resource_Product_Collection'),
-    $this->_getRule('_addTaxPercents', 'Mage_Catalog_Model_Resource_Product_Collection'),
-    $this->_getRule('_afterSaveCommit', 'Mage_Core_Model_Abstract'),
-    $this->_getRule('_afterSetConfig', 'Mage_Eav_Model_Entity_Abstract'),
-    $this->_getRule('_aggregateByOrderCreatedAt', 'Mage_SalesRule_Model_Resource_Report_Rule'),
-    $this->_getRule('_amountByCookies', 'Mage_Sendfriend_Model_Sendfriend'),
-    $this->_getRule('_amountByIp', 'Mage_Sendfriend_Model_Sendfriend'),
-    $this->_getRule('_applyCustomDesignSettings'),
-    $this->_getRule('_applyDesign', 'Mage_Catalog_Model_Design'),
-    $this->_getRule('_applyDesignRecursively', 'Mage_Catalog_Model_Design'),
-    $this->_getRule('_avoidDoubleTransactionProcessing'),
-    $this->_getRule('_beforeChildToHtml'),
-    $this->_getRule('_calculatePrice', 'Mage_Sales_Model_Quote_Item_Abstract'),
-    $this->_getRule('_canShowField', 'Mage_Backend_Block_System_Config_Form'),
-    $this->_getRule('_canUseLocalModules'),
-    $this->_getRule('_checkUrlSettings', 'Mage_Adminhtml_Controller_Action'),
-    $this->_getRule('_collectOrigData', 'Mage_Catalog_Model_Resource_Abstract'),
-    $this->_getRule('_decodeInput', 'Mage_Adminhtml_Catalog_ProductController'),
-    $this->_getRule('_emailOrderConfirmation', 'Mage_Checkout_Model_Type_Abstract'),
-    $this->_getRule('_escapeValue', 'Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Abstract'),
-    $this->_getRule('_getAddressTaxRequest', 'Mage_Tax_Model_Sales_Total_Quote_Shipping'),
-    $this->_getRule('_getAggregationPerStoreView'),
-    $this->_getRule('_getAttributeFilterBlockName', 'Mage_Catalog_Block_Layer_View'),
-    $this->_getRule('_getAttributeFilterBlockName', 'Mage_CatalogSearch_Block_Layer'),
-    $this->_getRule('_getAttributeFilterBlockName'),
-    $this->_getRule('_getAvailable', 'Mage_GiftMessage_Model_Observer'),
-    $this->_getRule('_getCacheId', 'Mage_Core_Model_App'),
-    $this->_getRule('_getCacheKey', 'Mage_Catalog_Model_Layer_Filter_Price'),
-    $this->_getRule('_getCacheTags', 'Mage_Core_Model_App'),
-    $this->_getRule('_getChildHtml'),
-    $this->_getRule('_getCollapseState', 'Mage_Backend_Block_System_Config_Form_Fieldset', '_isCollapseState'),
-    $this->_getRule('_getCollectionNames', 'Mage_Adminhtml_Report_SalesController'),
-    $this->_getRule('_getConnenctionType', 'Mage_Install_Model_Installer_Db'),
-    $this->_getRule('_getDateFromToHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
-    $this->_getRule('_getExistingBasePopularity'),
-    $this->_getRule('_getFieldTableAlias', 'Mage_Newsletter_Model_Resource_Subscriber_Collection'),
-    $this->_getRule('_getForeignKeyName', 'Varien_Db_Adapter_Pdo_Mysql'),
-    $this->_getRule('_getGiftmessageSaveModel', 'Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid'),
-    $this->_getRule('_getGlobalAggregation'),
-    $this->_getRule('_getGroupByDateFormat', 'Mage_Log_Model_Resource_Visitor_Collection'),
-    $this->_getRule('_getInputHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
-    $this->_getRule('_getLabelForStore', 'Mage_Catalog_Model_Resource_Eav_Attribute'),
-    $this->_getRule('_getMultiSelectHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
-    $this->_getRule('_getNumberFromToHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
-    $this->_getRule('_getPriceFilter', 'Mage_Catalog_Block_Layer_View'),
-    $this->_getRule('_getProductQtyForCheck', 'Mage_CatalogInventory_Model_Observer'),
-    $this->_getRule('_getRangeByType', 'Mage_Log_Model_Resource_Visitor_Collection'),
-    $this->_getRule('_getRecentProductsCollection'),
-    $this->_getRule('_getSelectHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
-    $this->_getRule('_getSetData', 'Mage_Adminhtml_Block_Catalog_Product_Attribute_Set_Main'),
-    $this->_getRule('_getSHAInSet', null, 'Mage_Ogone_Model_Api::getHash'),
-    $this->_getRule('_getStoreTaxRequest', 'Mage_Tax_Model_Sales_Total_Quote_Shipping'),
-    $this->_getRule('_importAddress', 'Mage_Paypal_Model_Api_Nvp'),
-    $this->_getRule('_inheritDesign', 'Mage_Catalog_Model_Design'),
-    $this->_getRule('_initOrder', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('_initShipment', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('_inludeControllerClass', null, '_includeControllerClass'),
-    $this->_getRule('_isApplyDesign', 'Mage_Catalog_Model_Design'),
-    $this->_getRule('_isApplyFor', 'Mage_Catalog_Model_Design'),
-    $this->_getRule('_isPositiveDecimalNumber', 'Mage_Shipping_Model_Resource_Carrier_Tablerate'),
-    $this->_getRule('_loadOldRates', 'Mage_Tax_Model_Resource_Setup'),
-    $this->_getRule('_needSubtractShippingTax'),
-    $this->_getRule('_needSubtractTax'),
-    $this->_getRule('_needToAddDummy'),
-    $this->_getRule('_needToAddDummyForShipment'),
-    $this->_getRule('_parseDescription', 'Mage_Sales_Model_Order_Pdf_Items_Abstract'),
-    $this->_getRule('_parseXmlTrackingResponse', 'Mage_Usa_Model_Shipping_Carrier_Fedex'),
-    $this->_getRule('_prepareCondition', 'Mage_CatalogSearch_Model_Advanced'),
-    $this->_getRule('_prepareConfigurableProductData', 'Mage_ImportExport_Model_Export_Entity_Product'),
-    $this->_getRule('_prepareConfigurableProductPrice', 'Mage_ImportExport_Model_Export_Entity_Product'),
-    $this->_getRule('_prepareOptionsForCart', 'Mage_Catalog_Model_Product_Type_Abstract'),
-    $this->_getRule('_preparePackageTheme', 'Mage_Widget_Model_Widget_Instance'),
-    $this->_getRule('_processItem', 'Mage_Weee_Model_Total_Quote_Weee'),
-    $this->_getRule('_processShippingAmount'),
-    $this->_getRule('_processValidateCustomer', 'Mage_Checkout_Model_Type_Onepage'),
-    $this->_getRule('_putCustomerIntoQuote', 'Mage_Adminhtml_Model_Sales_Order_Create'),
-    $this->_getRule('_quoteRow', 'Mage_Backup_Model_Resource_Db'),
-    $this->_getRule('_recollectItem', 'Mage_Tax_Model_Sales_Total_Quote_Subtotal'),
-    $this->_getRule('_resetItemPriceInclTax'),
-    $this->_getRule('_saveCustomerAfterOrder', 'Mage_Adminhtml_Model_Sales_Order_Create'),
-    $this->_getRule('_saveCustomers', 'Mage_Adminhtml_Model_Sales_Order_Create'),
-    $this->_getRule('_sendUploadResponse', 'Mage_Adminhtml_CustomerController'),
-    $this->_getRule('_sendUploadResponse', 'Mage_Adminhtml_Newsletter_SubscriberController'),
-    $this->_getRule('_setAttribteValue'),
-    $this->_getRule('_sort', 'Mage_Backend_Model_Config_Structure_Converter'),
-    $this->_getRule('_usePriceIncludeTax'),
-    $this->_getRule('addBackupedFilter'),
-    $this->_getRule('addConfigField', 'Mage_Core_Model_Resource_Setup'),
-    $this->_getRule('addConstraint', 'Varien_Db_Adapter_Pdo_Mysql'),
-    $this->_getRule('addCustomersToAlertQueueAction'),
-    $this->_getRule('addCustomerToSegments'),
-    $this->_getRule('addGroupByTag', 'Mage_Tag_Model_Resource_Reports_Collection'),
-    $this->_getRule('addKey', 'Varien_Db_Adapter_Pdo_Mysql'),
-    $this->_getRule('addSaleableFilterToCollection'),
-    $this->_getRule('addSearchQfFilter'),
-    $this->_getRule('addStoresFilter', 'Mage_Poll_Model_Resource_Poll_Collection'),
-    $this->_getRule('addSummary', 'Mage_Tag_Model_Resource_Tag'),
-    $this->_getRule('addSummary', 'Mage_Tag_Model_Tag'),
-    $this->_getRule('addTemplateData', 'Mage_Newsletter_Model_Queue'),
-    $this->_getRule('addToAlersAction'),
-    $this->_getRule('addToChildGroup'),
-    $this->_getRule('addVisibleFilterToCollection', 'Mage_Catalog_Model_Product_Status'),
-    $this->_getRule('addVisibleInCatalogFilterToCollection', null,
+    array('__get', 'Varien_Object'),
+    array('__set', 'Varien_Object'),
+    array('_addMinimalPrice', 'Mage_Catalog_Model_Resource_Product_Collection'),
+    array('_addTaxPercents', 'Mage_Catalog_Model_Resource_Product_Collection'),
+    array('_afterSaveCommit', 'Mage_Core_Model_Abstract'),
+    array('_afterSetConfig', 'Mage_Eav_Model_Entity_Abstract'),
+    array('_aggregateByOrderCreatedAt', 'Mage_SalesRule_Model_Resource_Report_Rule'),
+    array('_amountByCookies', 'Mage_Sendfriend_Model_Sendfriend'),
+    array('_amountByIp', 'Mage_Sendfriend_Model_Sendfriend'),
+    array('_applyCustomDesignSettings'),
+    array('_applyDesign', 'Mage_Catalog_Model_Design'),
+    array('_applyDesignRecursively', 'Mage_Catalog_Model_Design'),
+    array('_avoidDoubleTransactionProcessing'),
+    array('_beforeChildToHtml'),
+    array('_calculatePrice', 'Mage_Sales_Model_Quote_Item_Abstract'),
+    array('_canShowField', 'Mage_Backend_Block_System_Config_Form'),
+    array('_canUseLocalModules'),
+    array('_checkUrlSettings', 'Mage_Adminhtml_Controller_Action'),
+    array('_collectOrigData', 'Mage_Catalog_Model_Resource_Abstract'),
+    array('_decodeInput', 'Mage_Adminhtml_Catalog_ProductController'),
+    array('_emailOrderConfirmation', 'Mage_Checkout_Model_Type_Abstract'),
+    array('_escapeValue', 'Mage_Adminhtml_Block_Widget_Grid_Column_Filter_Abstract'),
+    array('_getAddressTaxRequest', 'Mage_Tax_Model_Sales_Total_Quote_Shipping'),
+    array('_getAggregationPerStoreView'),
+    array('_getAttributeFilterBlockName', 'Mage_Catalog_Block_Layer_View'),
+    array('_getAttributeFilterBlockName', 'Mage_CatalogSearch_Block_Layer'),
+    array('_getAttributeFilterBlockName'),
+    array('_getAvailable', 'Mage_GiftMessage_Model_Observer'),
+    array('_getCacheId', 'Mage_Core_Model_App'),
+    array('_getCacheKey', 'Mage_Catalog_Model_Layer_Filter_Price'),
+    array('_getCacheTags', 'Mage_Core_Model_App'),
+    array('_getChildHtml'),
+    array('_getCollapseState', 'Mage_Backend_Block_System_Config_Form_Fieldset', '_isCollapseState'),
+    array('_getCollectionNames', 'Mage_Adminhtml_Report_SalesController'),
+    array('_getConnenctionType', 'Mage_Install_Model_Installer_Db'),
+    array('_getDateFromToHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
+    array('_getExistingBasePopularity'),
+    array('_getFieldTableAlias', 'Mage_Newsletter_Model_Resource_Subscriber_Collection'),
+    array('_getForeignKeyName', 'Varien_Db_Adapter_Pdo_Mysql'),
+    array('_getGiftmessageSaveModel', 'Mage_Adminhtml_Block_Sales_Order_Create_Search_Grid'),
+    array('_getGlobalAggregation'),
+    array('_getGroupByDateFormat', 'Mage_Log_Model_Resource_Visitor_Collection'),
+    array('_getInputHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
+    array('_getLabelForStore', 'Mage_Catalog_Model_Resource_Eav_Attribute'),
+    array('_getMultiSelectHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
+    array('_getNumberFromToHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
+    array('_getPriceFilter', 'Mage_Catalog_Block_Layer_View'),
+    array('_getProductQtyForCheck', 'Mage_CatalogInventory_Model_Observer'),
+    array('_getRangeByType', 'Mage_Log_Model_Resource_Visitor_Collection'),
+    array('_getRecentProductsCollection'),
+    array('_getSelectHtml', 'Mage_ImportExport_Block_Adminhtml_Export_Filter'),
+    array('_getSetData', 'Mage_Adminhtml_Block_Catalog_Product_Attribute_Set_Main'),
+    array('_getSHAInSet', null, 'Mage_Ogone_Model_Api::getHash'),
+    array('_getStoreTaxRequest', 'Mage_Tax_Model_Sales_Total_Quote_Shipping'),
+    array('_importAddress', 'Mage_Paypal_Model_Api_Nvp'),
+    array('_inheritDesign', 'Mage_Catalog_Model_Design'),
+    array('_initOrder', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('_initShipment', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('_inludeControllerClass', null, '_includeControllerClass'),
+    array('_isApplyDesign', 'Mage_Catalog_Model_Design'),
+    array('_isApplyFor', 'Mage_Catalog_Model_Design'),
+    array('_isPositiveDecimalNumber', 'Mage_Shipping_Model_Resource_Carrier_Tablerate'),
+    array('_loadOldRates', 'Mage_Tax_Model_Resource_Setup'),
+    array('_needSubtractShippingTax'),
+    array('_needSubtractTax'),
+    array('_needToAddDummy'),
+    array('_needToAddDummyForShipment'),
+    array('_parseDescription', 'Mage_Sales_Model_Order_Pdf_Items_Abstract'),
+    array('_parseXmlTrackingResponse', 'Mage_Usa_Model_Shipping_Carrier_Fedex'),
+    array('_prepareCondition', 'Mage_CatalogSearch_Model_Advanced'),
+    array('_prepareConfigurableProductData', 'Mage_ImportExport_Model_Export_Entity_Product'),
+    array('_prepareConfigurableProductPrice', 'Mage_ImportExport_Model_Export_Entity_Product'),
+    array('_prepareOptionsForCart', 'Mage_Catalog_Model_Product_Type_Abstract'),
+    array('_preparePackageTheme', 'Mage_Widget_Model_Widget_Instance'),
+    array('_processItem', 'Mage_Weee_Model_Total_Quote_Weee'),
+    array('_processShippingAmount'),
+    array('_processValidateCustomer', 'Mage_Checkout_Model_Type_Onepage'),
+    array('_putCustomerIntoQuote', 'Mage_Adminhtml_Model_Sales_Order_Create'),
+    array('_quoteRow', 'Mage_Backup_Model_Resource_Db'),
+    array('_recollectItem', 'Mage_Tax_Model_Sales_Total_Quote_Subtotal'),
+    array('_resetItemPriceInclTax'),
+    array('_saveCustomerAfterOrder', 'Mage_Adminhtml_Model_Sales_Order_Create'),
+    array('_saveCustomers', 'Mage_Adminhtml_Model_Sales_Order_Create'),
+    array('_sendUploadResponse', 'Mage_Adminhtml_CustomerController'),
+    array('_sendUploadResponse', 'Mage_Adminhtml_Newsletter_SubscriberController'),
+    array('_setAttribteValue'),
+    array('_sort', 'Mage_Backend_Model_Config_Structure_Converter'),
+    array('_updateMediaPathUseRewrites', 'Mage_Core_Model_Store', '_getMediaScriptUrl'),
+    array('_usePriceIncludeTax'),
+    array('addBackupedFilter'),
+    array('addConfigField', 'Mage_Core_Model_Resource_Setup'),
+    array('addConstraint', 'Varien_Db_Adapter_Pdo_Mysql'),
+    array('addCustomersToAlertQueueAction'),
+    array('addCustomerToSegments'),
+    array('addGroupByTag', 'Mage_Tag_Model_Resource_Reports_Collection'),
+    array('addKey', 'Varien_Db_Adapter_Pdo_Mysql'),
+    array('addSaleableFilterToCollection'),
+    array('addSearchQfFilter'),
+    array('addStoresFilter', 'Mage_Poll_Model_Resource_Poll_Collection'),
+    array('addSummary', 'Mage_Tag_Model_Resource_Tag'),
+    array('addSummary', 'Mage_Tag_Model_Tag'),
+    array('addTemplateData', 'Mage_Newsletter_Model_Queue'),
+    array('addToAlersAction'),
+    array('addToChildGroup'),
+    array('addVisibleFilterToCollection', 'Mage_Catalog_Model_Product_Status'),
+    array('addVisibleInCatalogFilterToCollection', null,
         '$collection->setVisibility(Mage_Catalog_Model_Product_Visibility->getVisibleInCatalogIds());'),
-    $this->_getRule('addVisibleInSearchFilterToCollection', null,
+    array('addVisibleInSearchFilterToCollection', null,
         '$collection->setVisibility(Mage_Catalog_Model_Product_Visibility->getVisibleInSearchIds());'),
-    $this->_getRule('addVisibleInSiteFilterToCollection', null,
+    array('addVisibleInSiteFilterToCollection', null,
         '$collection->setVisibility(Mage_Catalog_Model_Product_Visibility->getVisibleInSiteIds());'),
-    $this->_getRule('addWishlistLink', 'Mage_Wishlist_Block_Links'),
-    $this->_getRule('addWishListSortOrder', 'Mage_Wishlist_Model_Resource_Item_Collection'),
-    $this->_getRule('aggregate', 'Mage_Tag_Model_Resource_Tag'),
-    $this->_getRule('aggregate', 'Mage_Tag_Model_Tag'),
-    $this->_getRule('applyDesign', 'Mage_Catalog_Model_Design'),
-    $this->_getRule('authAdmin'),
-    $this->_getRule('authFailed', null, 'Mage_Core_Helper_Http::failHttpAuthentication()'),
-    $this->_getRule('authFrontend'),
-    $this->_getRule('authValidate', null, 'Mage_Core_Helper_Http::getHttpAuthCredentials()'),
-    $this->_getRule('bundlesAction', 'Mage_Adminhtml_Catalog_ProductController'),
-    $this->_getRule('calcTaxAmount', 'Mage_Sales_Model_Quote_Item_Abstract'),
-    $this->_getRule('canPrint', 'Mage_Checkout_Block_Onepage_Success'),
-    $this->_getRule('catalogCategoryChangeProducts', 'Mage_Catalog_Model_Product_Flat_Observer'),
-    $this->_getRule('catalogEventProductCollectionAfterLoad', 'Mage_GiftMessage_Model_Observer'),
-    $this->_getRule('catalogProductLoadAfter', 'Mage_Bundle_Model_Observer'),
-    $this->_getRule('chechAllowedExtension'),
-    $this->_getRule('checkConfigurableProducts', 'Mage_Eav_Model_Resource_Entity_Attribute_Collection'),
-    $this->_getRule('checkDatabase', 'Mage_Install_Model_Installer_Db'),
-    $this->_getRule('checkDateTime', 'Mage_Core_Model_Date'),
-    $this->_getRule('cleanDbRow', 'Mage_Core_Model_Resource'),
-    $this->_getRule('cloneIndexTable', 'Mage_Index_Model_Resource_Abstract'),
-    $this->_getRule('convertOldTaxData', 'Mage_Tax_Model_Resource_Setup'),
-    $this->_getRule('convertOldTreeToNew', 'Mage_Catalog_Model_Resource_Setup'),
-    $this->_getRule('countChildren', 'Mage_Core_Block_Abstract'),
-    $this->_getRule('crear'),
-    $this->_getRule('createOrderItem', 'Mage_CatalogInventory_Model_Observer'),
-    $this->_getRule('debugRequest', 'Mage_Paypal_Model_Api_Standard'),
-    $this->_getRule('deleteProductPrices', 'Mage_Catalog_Model_Resource_Product_Attribute_Backend_Tierprice'),
-    $this->_getRule('display', 'Varien_Image_Adapter_Abstract', 'getImage()'),
-    $this->_getRule('displayFullSummary', 'Mage_Tax_Model_Config'),
-    $this->_getRule('displayTaxColumn', 'Mage_Tax_Model_Config'),
-    $this->_getRule('displayZeroTax', 'Mage_Tax_Model_Config'),
-    $this->_getRule('drawItem', 'Mage_Catalog_Block_Navigation'),
-    $this->_getRule('dropKey', 'Varien_Db_Adapter_Pdo_Mysql'),
-    $this->_getRule('editAction', 'Mage_Tag_CustomerController'),
-    $this->_getRule('escapeJs', 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config'),
-    $this->_getRule('exportOrderedCsvAction'),
-    $this->_getRule('exportOrderedExcelAction'),
-    $this->_getRule('fetchItemsCount', 'Mage_Wishlist_Model_Resource_Wishlist'),
-    $this->_getRule('fetchRuleRatesForCustomerTaxClass'),
-    $this->_getRule('forsedSave'),
-    $this->_getRule('generateBlocks', null, 'generateElements()'),
-    $this->_getRule('getAccount', 'Mage_GoogleAnalytics_Block_Ga'),
-    $this->_getRule('getAclAssert', 'Mage_Admin_Model_Config'),
-    $this->_getRule('getAclPrivilegeSet', 'Mage_Admin_Model_Config'),
-    $this->_getRule('getAclResourceList', 'Mage_Admin_Model_Config'),
-    $this->_getRule('getAclResourceTree', 'Mage_Admin_Model_Config'),
-    $this->_getRule('getAddNewButtonHtml', 'Mage_Adminhtml_Block_Catalog_Product'),
-    $this->_getRule('getAddToCartItemUrl', 'Mage_Wishlist_Block_Customer_Sidebar'),
-    $this->_getRule('getAddToCartUrlBase64', null, '_getAddToCartUrl'),
-    $this->_getRule('getAllEntityIds', 'Mage_Rss_Model_Resource_Order'),
-    $this->_getRule('getAllEntityTypeCommentIds', 'Mage_Rss_Model_Resource_Order'),
-    $this->_getRule('getAllOrderEntityIds', 'Mage_Rss_Model_Resource_Order'),
-    $this->_getRule('getAllOrderEntityTypeIds', 'Mage_Rss_Model_Resource_Order'),
-    $this->_getRule('getAnonSuffix'),
-    $this->_getRule('getAttributesJson', 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config', 'getAttributes'),
-    $this->_getRule('getBaseTaxAmount', 'Mage_Sales_Model_Quote_Item_Abstract'),
-    $this->_getRule('getCheckoutMehod', 'Mage_Checkout_Model_Type_Onepage'),
-    $this->_getRule('getChild', null, 'Mage_Core_Block_Abstract::getChildBlock()', 'app'),
-    $this->_getRule('getChildGroup', null, 'Mage_Core_Block_Abstract::getGroupChildNames()'),
-    $this->_getRule('getConfig', 'Mage_Eav_Model_Entity_Attribute_Abstract'),
-    $this->_getRule('getCustomerData', 'Mage_Adminhtml_Block_Sales_Order_Create_Form_Account'),
-    $this->_getRule('getDataForSave', 'Mage_Wishlist_Model_Item'),
-    $this->_getRule('getDebug', 'Mage_Ogone_Model_Api'),
-    $this->_getRule('getDebug', 'Mage_Paypal_Model_Api_Abstract'),
-    $this->_getRule('getDirectOutput', 'Mage_Core_Model_Layout'),
-    $this->_getRule('getEntityIdsToIncrementIds', 'Mage_Rss_Model_Resource_Order'),
-    $this->_getRule('getEntityTypeIdsToTypes', 'Mage_Rss_Model_Resource_Order'),
-    $this->_getRule('getFacets'),
-    $this->_getRule('getFallbackTheme'),
-    $this->_getRule('getFormated', null, 'getFormated(true) -> format(\'html\'), getFormated() -> format(\'text\')'),
-    $this->_getRule('getFormObject', 'Mage_Adminhtml_Block_Widget_Form'),
-    $this->_getRule('getGiftmessageHtml', 'Mage_Adminhtml_Block_Sales_Order_View_Tab_Info'),
-    $this->_getRule('getHtmlFormat', 'Mage_Customer_Model_Address_Abstract'),
-    $this->_getRule('getIsActiveAanalytics', null, 'getOnsubmitJs'),
-    $this->_getRule('getIsAjaxRequest', 'Mage_Core_Model_Translate_Inline'),
-    $this->_getRule('getIsEngineAvailable'),
-    $this->_getRule('getIsGlobal', 'Mage_Eav_Model_Entity_Attribute_Abstract'),
-    $this->_getRule('getIsInStock', 'Mage_Checkout_Block_Cart_Item_Renderer'),
-    $this->_getRule('getItemRender', 'Mage_Checkout_Block_Cart_Abstract'),
-    $this->_getRule('getJoinFlag', 'Mage_Tag_Model_Resource_Customer_Collection'),
-    $this->_getRule('getJoinFlag', 'Mage_Tag_Model_Resource_Product_Collection'),
-    $this->_getRule('getJoinFlag', 'Mage_Tag_Model_Resource_Tag_Collection'),
-    $this->_getRule('getKeyList', 'Varien_Db_Adapter_Pdo_Mysql'),
-    $this->_getRule('getLanguages', 'Mage_Install_Block_Begin'),
-    $this->_getRule('getLayoutFilename', null, 'getFilename'),
-    $this->_getRule('getLifeTime', 'Mage_Core_Model_Resource_Session'),
-    $this->_getRule('getLocaleBaseDir', 'Mage_Core_Model_Design_Package'),
-    $this->_getRule('getMail', 'Mage_Newsletter_Model_Template'),
-    $this->_getRule('getMaxQueryLenght'),
-    $this->_getRule('getMenuItemLabel', 'Mage_Admin_Model_Config'),
-    $this->_getRule('getMergedCssUrl'),
-    $this->_getRule('getMergedJsUrl'),
-    $this->_getRule('getMinQueryLenght'),
-    $this->_getRule('getNeedUsePriceExcludeTax', null, 'Mage_Tax_Model_Config::priceIncludesTax()'),
-    $this->_getRule('getOneBalanceTotal'),
-    $this->_getRule('getOrderHtml', 'Mage_GoogleAnalytics_Block_Ga'),
-    $this->_getRule('getOrderId', 'Mage_Checkout_Block_Onepage_Success'),
-    $this->_getRule('getOrderId', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('getOriginalHeigh', null, 'getOriginalHeight'),
-    $this->_getRule('getParentProductIds', 'Mage_Catalog_Model_Resource_Product'),
-    $this->_getRule('getPriceFormatted', 'Mage_Adminhtml_Block_Customer_Edit_Tab_View_Sales'),
-    $this->_getRule('getPrices', 'Mage_Bundle_Model_Product_Price'),
-    $this->_getRule('getPricesDependingOnTax', 'Mage_Bundle_Model_Product_Price'),
-    $this->_getRule('getPrintUrl', 'Mage_Checkout_Block_Onepage_Success'),
-    $this->_getRule('getPrintUrl', 'Mage_Sales_Block_Order_Info'),
-    $this->_getRule('getProductCollection', 'Mage_Wishlist_Helper_Data'),
-    $this->_getRule('getProductCollection', 'Mage_Wishlist_Model_Wishlist'),
-    $this->_getRule('getProductsNotInStoreIds'),
-    $this->_getRule('getProfile', 'Varien_Convert_Container_Abstract'),
-    $this->_getRule('getQuoteItem', 'Mage_Catalog_Model_Product_Option_Type_Default'),
-    $this->_getRule('getQuoteItemOption', 'Mage_Catalog_Model_Product_Option_Type_Default'),
-    $this->_getRule('getQuoteOrdersHtml', 'Mage_GoogleAnalytics_Block_Ga'),
-    $this->_getRule('getRemoveItemUrl', 'Mage_Wishlist_Block_Customer_Sidebar'),
-    $this->_getRule('getReorderUrl', 'Mage_Sales_Block_Order_Info'),
-    $this->_getRule('getRowId', 'Mage_Adminhtml_Block_Sales_Order_Create_Customer_Grid'),
-    $this->_getRule('getRowId', 'Mage_Adminhtml_Block_Widget_Grid'),
-    $this->_getRule('getSaveTemplateFlag', 'Mage_Newsletter_Model_Queue'),
-    $this->_getRule('getSelectionFinalPrice', 'Mage_Bundle_Model_Product_Price'),
-    $this->_getRule('getSecure', 'Mage_Core_Model_Url', 'isSecure'),
-    $this->_getRule('getSecure', 'Mage_Backend_Model_Url', 'isSecure'),
-    $this->_getRule('getShipId', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('getSortedChildren', null, 'getChildNames'),
-    $this->_getRule('getSortedChildBlocks', null, 'getChildNames() + $this->getLayout()->getBlock($name)'),
-    $this->_getRule('getStatrupPageUrl'),
-    $this->_getRule('getStoreButtonsHtml', 'Mage_Backend_Block_System_Config_Tabs'),
-    $this->_getRule('getStoreCurrency', 'Mage_Sales_Model_Order'),
-    $this->_getRule('getStoreSelectOptions', 'Mage_Backend_Block_System_Config_Tabs'),
-    $this->_getRule('getSuggestedZeroDate'),
-    $this->_getRule('getSuggestionsByQuery'),
-    $this->_getRule('getSysTmpDir'),
-    $this->_getRule('getTaxAmount', 'Mage_Sales_Model_Quote_Item_Abstract'),
-    $this->_getRule('getTaxRatesByProductClass', null, '_getAllRatesByProductClass'),
-    $this->_getRule('getTemplateFilename', null, 'getFilename'),
-    $this->_getRule('getTotalModels', 'Mage_Sales_Model_Quote_Address'),
-    $this->_getRule('getTrackId', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('getTrackingInfoByOrder', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('getTrackingInfoByShip', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('getTrackingInfoByTrackId', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('getTrackingPopUpUrlByOrderId', null, 'getTrackingPopupUrlBySalesModel'),
-    $this->_getRule('getTrackingPopUpUrlByShipId', null, 'getTrackingPopupUrlBySalesModel'),
-    $this->_getRule('getTrackingPopUpUrlByTrackId', null, 'getTrackingPopupUrlBySalesModel'),
-    $this->_getRule('getUseCacheFilename', 'Mage_Core_Model_App'),
-    $this->_getRule('getValidator', 'Mage_SalesRule_Model_Observer'),
-    $this->_getRule('getValidatorData', 'Mage_Core_Model_Session_Abstract', 'use _getSessionEnvironment method'),
-    $this->_getRule('getValueTable'),
-    $this->_getRule('getViewOrderUrl', 'Mage_Checkout_Block_Onepage_Success'),
-    $this->_getRule('getWidgetSupportedBlocks', 'Mage_Widget_Model_Widget_Instance'),
-    $this->_getRule('getWidgetSupportedTemplatesByBlock', 'Mage_Widget_Model_Widget_Instance'),
-    $this->_getRule('hasItems', 'Mage_Wishlist_Helper_Data'),
-    $this->_getRule('htmlEscape', null, 'escapeHtml'),
-    $this->_getRule('imageAction', 'Mage_Catalog_ProductController'),
-    $this->_getRule('importFromTextArray'),
-    $this->_getRule('initLabels', 'Mage_Catalog_Model_Resource_Eav_Attribute'),
-    $this->_getRule('insertProductPrice', 'Mage_Catalog_Model_Resource_Product_Attribute_Backend_Tierprice'),
-    $this->_getRule('isAllowedGuestCheckout', 'Mage_Sales_Model_Quote'),
-    $this->_getRule('isAutomaticCleaningAvailable', 'Varien_Cache_Backend_Eaccelerator'),
-    $this->_getRule('isCheckoutAvailable', 'Mage_Checkout_Model_Type_Multishipping'),
-    $this->_getRule('isFulAmountCovered'),
-    $this->_getRule('isLeyeredNavigationAllowed'),
-    $this->_getRule('isReadablePopupObject'),
-    $this->_getRule('isTemplateAllowedForApplication'),
-    $this->_getRule('loadLabel', 'Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute'),
-    $this->_getRule('loadParentProductIds', 'Mage_Catalog_Model_Product'),
-    $this->_getRule('loadPrices', 'Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute'),
-    $this->_getRule('loadProductPrices', 'Mage_Catalog_Model_Resource_Product_Attribute_Backend_Tierprice'),
-    $this->_getRule('lockOrderInventoryData', 'Mage_CatalogInventory_Model_Observer'),
-    $this->_getRule('logEncryptionKeySave'),
-    $this->_getRule('logInvitationSave'),
-    $this->_getRule('mergeFiles', 'Mage_Core_Helper_Data'),
-    $this->_getRule('order_success_page_view', 'Mage_GoogleAnalytics_Model_Observer'),
-    $this->_getRule('orderedAction', 'Mage_Adminhtml_Report_ProductController'),
-    $this->_getRule('parseDateTime', 'Mage_Core_Model_Date'),
-    $this->_getRule('postDispatchMyAccountSave'),
-    $this->_getRule('postDispatchSystemImportExportRun'),
-    $this->_getRule('prepareCacheId', 'Mage_Core_Model_App'),
-    $this->_getRule('prepareGoogleOptimizerScripts'),
-    $this->_getRule('preprocess', 'Mage_Newsletter_Model_Template'),
-    $this->_getRule('processBeacon'),
-    $this->_getRule('processBeforeVoid', 'Mage_Payment_Model_Method_Abstract'),
-    $this->_getRule('processSubst', 'Mage_Core_Model_Store'),
-    $this->_getRule('productEventAggregate'),
-    $this->_getRule('push', 'Mage_Catalog_Model_Product_Image'),
-    $this->_getRule('rebuildCategoryLevels', 'Mage_Catalog_Model_Resource_Setup'),
-    $this->_getRule('regenerateSessionId', 'Mage_Core_Model_Session_Abstract'),
-    $this->_getRule('refundOrderItem', 'Mage_CatalogInventory_Model_Observer'),
-    $this->_getRule('removeCustomerFromSegments'),
-    $this->_getRule('revalidateCookie', 'Mage_Core_Model_Session_Abstract_Varien'),
-    $this->_getRule('sales_order_afterPlace'),
-    $this->_getRule('sales_quote_address_discount_item'),
-    $this->_getRule('salesOrderPaymentPlaceEnd'),
-    $this->_getRule('saveRow__OLD'),
-    $this->_getRule('saveAction', 'Mage_Tag_CustomerController'),
-    $this->_getRule('saveSegmentCustomersFromSelect'),
-    $this->_getRule('send', 'Mage_Newsletter_Model_Template'),
-    $this->_getRule('sendNewPasswordEmail'),
-    $this->_getRule('setAnonSuffix'),
-    $this->_getRule('setAttributeSetExcludeFilter', 'Mage_Eav_Model_Resource_Entity_Attribute_Collection'),
-    $this->_getRule('setBlockAlias'),
-    $this->_getRule('setCustomerId', 'Mage_Customer_Model_Resource_Address'),
-    $this->_getRule('setIsAjaxRequest', 'Mage_Core_Model_Translate_Inline'),
-    $this->_getRule('setJoinFlag', 'Mage_Tag_Model_Resource_Customer_Collection'),
-    $this->_getRule('setJoinFlag', 'Mage_Tag_Model_Resource_Product_Collection'),
-    $this->_getRule('setJoinFlag', 'Mage_Tag_Model_Resource_Tag_Collection'),
-    $this->_getRule('setOrderId', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('setNeedUsePriceExcludeTax', null, 'Mage_Tax_Model_Config::setPriceIncludesTax()'),
-    $this->_getRule('setWatermarkHeigth', null, 'setWatermarkHeight'),
-    $this->_getRule('getWatermarkHeigth', null, 'getWatermarkHeight'),
-    $this->_getRule('setParentBlock'),
-    $this->_getRule('setProfile', 'Varien_Convert_Container_Abstract'),
-    $this->_getRule('setSaveTemplateFlag', 'Mage_Newsletter_Model_Queue'),
-    $this->_getRule('setShipId', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('setTaxGroupFilter'),
-    $this->_getRule('setTrackId', 'Mage_Shipping_Block_Tracking_Popup'),
-    $this->_getRule('shaCrypt', null, 'Mage_Ogone_Model_Api::getHash'),
-    $this->_getRule('shaCryptValidation', null, 'Mage_Ogone_Model_Api::getHash'),
-    $this->_getRule('shouldCustomerHaveOneBalance'),
-    $this->_getRule('shouldShowOneBalance'),
-    $this->_getRule('sortChildren'),
-    $this->_getRule('toOptionArray', 'Mage_Cms_Model_Resource_Page_Collection'),
-    $this->_getRule('toOptionArray', 'Mage_Sendfriend_Model_Sendfriend'),
-    $this->_getRule('truncate', 'Varien_Db_Adapter_Pdo_Mysql'),
-    $this->_getRule('unsetBlock'),
-    $this->_getRule('unsetJoinFlag', 'Mage_Tag_Model_Resource_Customer_Collection'),
-    $this->_getRule('unsetJoinFlag', 'Mage_Tag_Model_Resource_Product_Collection'),
-    $this->_getRule('unsetJoinFlag', 'Mage_Tag_Model_Resource_Tag_Collection'),
-    $this->_getRule('useValidateRemoteAddr', 'Mage_Core_Model_Session_Abstract'),
-    $this->_getRule('useValidateHttpVia', 'Mage_Core_Model_Session_Abstract'),
-    $this->_getRule('useValidateHttpXForwardedFor', 'Mage_Core_Model_Session_Abstract'),
-    $this->_getRule('useValidateHttpUserAgent', 'Mage_Core_Model_Session_Abstract'),
-    $this->_getRule('updateCofigurableProductOptions', 'Mage_Weee_Model_Observer', 'updateConfigurableProductOptions'),
-    $this->_getRule('updateTable', 'Mage_Core_Model_Resource_Setup'),
-    $this->_getRule('urlEscape', null, 'escapeUrl'),
-    $this->_getRule('validateDataArray', 'Varien_Convert_Container_Abstract'),
-    $this->_getRule('validateFile', 'Mage_Core_Model_Design_Package'),
-    $this->_getRule('validateOrder', 'Mage_Checkout_Model_Type_Onepage'),
-    $this->_getRule('prepareAttributesForSave', 'Mage_ImportExport_Model_Import_Entity_Product'),
-    $this->_getRule('fetchUpdatesByHandle', 'Mage_Core_Model_Resource_Layout',
+    array('addWishlistLink', 'Mage_Wishlist_Block_Links'),
+    array('addWishListSortOrder', 'Mage_Wishlist_Model_Resource_Item_Collection'),
+    array('aggregate', 'Mage_Tag_Model_Resource_Tag'),
+    array('aggregate', 'Mage_Tag_Model_Tag'),
+    array('applyDesign', 'Mage_Catalog_Model_Design'),
+    array('authAdmin'),
+    array('authFailed', null, 'Mage_Core_Helper_Http::failHttpAuthentication()'),
+    array('authFrontend'),
+    array('authValidate', null, 'Mage_Core_Helper_Http::getHttpAuthCredentials()'),
+    array('bundlesAction', 'Mage_Adminhtml_Catalog_ProductController'),
+    array('calcTaxAmount', 'Mage_Sales_Model_Quote_Item_Abstract'),
+    array('canPrint', 'Mage_Checkout_Block_Onepage_Success'),
+    array('catalogCategoryChangeProducts', 'Mage_Catalog_Model_Product_Flat_Observer'),
+    array('catalogEventProductCollectionAfterLoad', 'Mage_GiftMessage_Model_Observer'),
+    array('catalogProductLoadAfter', 'Mage_Bundle_Model_Observer'),
+    array('chechAllowedExtension'),
+    array('checkConfigurableProducts', 'Mage_Eav_Model_Resource_Entity_Attribute_Collection'),
+    array('checkDatabase', 'Mage_Install_Model_Installer_Db'),
+    array('checkDateTime', 'Mage_Core_Model_Date'),
+    array('cleanDbRow', 'Mage_Core_Model_Resource'),
+    array('cleanVarFolder', null, 'Varien_Io_File::rmdirRecursive()'),
+    array('cleanVarSubFolders', null, 'glob() on Mage::getBaseDir(Mage_Core_Model_App_Dir::VAR_DIR)'),
+    array('cloneIndexTable', 'Mage_Index_Model_Resource_Abstract'),
+    array('convertOldTaxData', 'Mage_Tax_Model_Resource_Setup'),
+    array('convertOldTreeToNew', 'Mage_Catalog_Model_Resource_Setup'),
+    array('countChildren', 'Mage_Core_Block_Abstract'),
+    array('crear'),
+    array('createDirIfNotExists', null, 'mkdir()'),
+    array('createOrderItem', 'Mage_CatalogInventory_Model_Observer'),
+    array('debugRequest', 'Mage_Paypal_Model_Api_Standard'),
+    array('deleteProductPrices', 'Mage_Catalog_Model_Resource_Product_Attribute_Backend_Tierprice'),
+    array('display', 'Varien_Image_Adapter_Abstract', 'getImage()'),
+    array('displayFullSummary', 'Mage_Tax_Model_Config'),
+    array('displayTaxColumn', 'Mage_Tax_Model_Config'),
+    array('displayZeroTax', 'Mage_Tax_Model_Config'),
+    array('drawItem', 'Mage_Catalog_Block_Navigation'),
+    array('dropKey', 'Varien_Db_Adapter_Pdo_Mysql'),
+    array('editAction', 'Mage_Tag_CustomerController'),
+    array('escapeJs', 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config'),
+    array('exportOrderedCsvAction'),
+    array('exportOrderedExcelAction'),
+    array('fetchItemsCount', 'Mage_Wishlist_Model_Resource_Wishlist'),
+    array('fetchRuleRatesForCustomerTaxClass'),
+    array('forsedSave'),
+    array('generateBlocks', null, 'generateElements()'),
+    array('getAccount', 'Mage_GoogleAnalytics_Block_Ga'),
+    array('getAclAssert', 'Mage_Admin_Model_Config'),
+    array('getAclPrivilegeSet', 'Mage_Admin_Model_Config'),
+    array('getAclResourceList', 'Mage_Admin_Model_Config'),
+    array('getAclResourceTree', 'Mage_Admin_Model_Config'),
+    array('getAddNewButtonHtml', 'Mage_Adminhtml_Block_Catalog_Product'),
+    array('getAddToCartItemUrl', 'Mage_Wishlist_Block_Customer_Sidebar'),
+    array('getAddToCartUrlBase64', null, '_getAddToCartUrl'),
+    array('getAllEntityIds', 'Mage_Rss_Model_Resource_Order'),
+    array('getAllEntityTypeCommentIds', 'Mage_Rss_Model_Resource_Order'),
+    array('getAllOrderEntityIds', 'Mage_Rss_Model_Resource_Order'),
+    array('getAllOrderEntityTypeIds', 'Mage_Rss_Model_Resource_Order'),
+    array('getAnonSuffix'),
+    array('getAttributesJson', 'Mage_Adminhtml_Block_Catalog_Product_Edit_Tab_Super_Config', 'getAttributes'),
+    array('getBaseTaxAmount', 'Mage_Sales_Model_Quote_Item_Abstract'),
+    array('getCheckoutMehod', 'Mage_Checkout_Model_Type_Onepage'),
+    array('getChildGroup', null, 'Mage_Core_Block_Abstract::getGroupChildNames()'),
+    array('getConfig', 'Mage_Eav_Model_Entity_Attribute_Abstract'),
+    array('getCustomerData', 'Mage_Adminhtml_Block_Sales_Order_Create_Form_Account'),
+    array('getDataForSave', 'Mage_Wishlist_Model_Item'),
+    array('getDebug', 'Mage_Ogone_Model_Api'),
+    array('getDebug', 'Mage_Paypal_Model_Api_Abstract'),
+    array('getDefaultBasePath', 'Mage_Core_Model_Store'),
+    array('getDirectOutput', 'Mage_Core_Model_Layout'),
+    array('getDistroServerVars', 'Mage_Core_Model_Config', 'getDistroBaseUrl'),
+    array('getEntityIdsToIncrementIds', 'Mage_Rss_Model_Resource_Order'),
+    array('getEntityTypeIdsToTypes', 'Mage_Rss_Model_Resource_Order'),
+    array('getFacets'),
+    array('getFallbackTheme'),
+    array('getFormated', null, 'getFormated(true) -> format(\'html\'), getFormated() -> format(\'text\')'),
+    array('getFormObject', 'Mage_Adminhtml_Block_Widget_Form'),
+    array('getGiftmessageHtml', 'Mage_Adminhtml_Block_Sales_Order_View_Tab_Info'),
+    array('getHtmlFormat', 'Mage_Customer_Model_Address_Abstract'),
+    array('getIsActiveAanalytics', null, 'getOnsubmitJs'),
+    array('getIsAjaxRequest', 'Mage_Core_Model_Translate_Inline'),
+    array('getIsEngineAvailable'),
+    array('getIsGlobal', 'Mage_Eav_Model_Entity_Attribute_Abstract'),
+    array('getIsInStock', 'Mage_Checkout_Block_Cart_Item_Renderer'),
+    array('getItemRender', 'Mage_Checkout_Block_Cart_Abstract'),
+    array('getJoinFlag', 'Mage_Tag_Model_Resource_Customer_Collection'),
+    array('getJoinFlag', 'Mage_Tag_Model_Resource_Product_Collection'),
+    array('getJoinFlag', 'Mage_Tag_Model_Resource_Tag_Collection'),
+    array('getKeyList', 'Varien_Db_Adapter_Pdo_Mysql'),
+    array('getLanguages', 'Mage_Install_Block_Begin'),
+    array('getLayoutFilename', null, 'getFilename'),
+    array('getLifeTime', 'Mage_Core_Model_Resource_Session'),
+    array('getLocaleBaseDir', 'Mage_Core_Model_Design_Package'),
+    array('getMail', 'Mage_Newsletter_Model_Template'),
+    array('getMaxQueryLenght'),
+    array('getMenuItemLabel', 'Mage_Admin_Model_Config'),
+    array('getMergedCssUrl'),
+    array('getMergedJsUrl'),
+    array('getMinQueryLenght'),
+    array('getNeedUsePriceExcludeTax', null, 'Mage_Tax_Model_Config::priceIncludesTax()'),
+    array('getOneBalanceTotal'),
+    array('getOption', 'Mage_Captcha_Helper_Data', 'Mage_Core_Model_Dir::getDir()'),
+    array('getOptions', 'Mage_Core_Model_Config'),
+    array('getOrderHtml', 'Mage_GoogleAnalytics_Block_Ga'),
+    array('getOrderId', 'Mage_Checkout_Block_Onepage_Success'),
+    array('getOrderId', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('getOriginalHeigh', null, 'getOriginalHeight'),
+    array('getParentProductIds', 'Mage_Catalog_Model_Resource_Product'),
+    array('getPriceFormatted', 'Mage_Adminhtml_Block_Customer_Edit_Tab_View_Sales'),
+    array('getPrices', 'Mage_Bundle_Model_Product_Price'),
+    array('getPricesDependingOnTax', 'Mage_Bundle_Model_Product_Price'),
+    array('getPrintUrl', 'Mage_Checkout_Block_Onepage_Success'),
+    array('getPrintUrl', 'Mage_Sales_Block_Order_Info'),
+    array('getProductCollection', 'Mage_Wishlist_Helper_Data'),
+    array('getProductCollection', 'Mage_Wishlist_Model_Wishlist'),
+    array('getProductsNotInStoreIds'),
+    array('getProfile', 'Varien_Convert_Container_Abstract'),
+    array('getQuoteItem', 'Mage_Catalog_Model_Product_Option_Type_Default'),
+    array('getQuoteItemOption', 'Mage_Catalog_Model_Product_Option_Type_Default'),
+    array('getQuoteOrdersHtml', 'Mage_GoogleAnalytics_Block_Ga'),
+    array('getRemoveItemUrl', 'Mage_Wishlist_Block_Customer_Sidebar'),
+    array('getReorderUrl', 'Mage_Sales_Block_Order_Info'),
+    array('getRowId', 'Mage_Adminhtml_Block_Sales_Order_Create_Customer_Grid'),
+    array('getRowId', 'Mage_Adminhtml_Block_Widget_Grid'),
+    array('getSaveTemplateFlag', 'Mage_Newsletter_Model_Queue'),
+    array('getSelectionFinalPrice', 'Mage_Bundle_Model_Product_Price'),
+    array('getSecure', 'Mage_Core_Model_Url', 'isSecure'),
+    array('getSecure', 'Mage_Backend_Model_Url', 'isSecure'),
+    array('getShipId', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('getSortedChildren', null, 'getChildNames'),
+    array('getSortedChildBlocks', null, 'getChildNames() + $this->getLayout()->getBlock($name)'),
+    array('getStatrupPageUrl'),
+    array('getStoreButtonsHtml', 'Mage_Backend_Block_System_Config_Tabs'),
+    array('getStoreCurrency', 'Mage_Sales_Model_Order'),
+    array('getStoreSelectOptions', 'Mage_Backend_Block_System_Config_Tabs'),
+    array('getSuggestedZeroDate'),
+    array('getSuggestionsByQuery'),
+    array('getSysTmpDir'),
+    array('getTaxAmount', 'Mage_Sales_Model_Quote_Item_Abstract'),
+    array('getTaxRatesByProductClass', null, '_getAllRatesByProductClass'),
+    array('getTemplateFilename', null, 'getFilename'),
+    array('getTempVarDir', 'Mage_Core_Model_Config', 'Mage_Core_Model_Dir::getDir()'),
+    array('getTotalModels', 'Mage_Sales_Model_Quote_Address'),
+    array('getTrackId', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('getTrackingInfoByOrder', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('getTrackingInfoByShip', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('getTrackingInfoByTrackId', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('getTrackingPopUpUrlByOrderId', null, 'getTrackingPopupUrlBySalesModel'),
+    array('getTrackingPopUpUrlByShipId', null, 'getTrackingPopupUrlBySalesModel'),
+    array('getTrackingPopUpUrlByTrackId', null, 'getTrackingPopupUrlBySalesModel'),
+    array('getUseCacheFilename', 'Mage_Core_Model_App'),
+    array('getValidator', 'Mage_SalesRule_Model_Observer'),
+    array('getValidatorData', 'Mage_Core_Model_Session_Abstract', 'use _getSessionEnvironment method'),
+    array('getValueTable'),
+    array('getVarDir', 'Mage_Core_Model_Config', 'Mage_Core_Model_Dir::getDir()'),
+    array('getViewOrderUrl', 'Mage_Checkout_Block_Onepage_Success'),
+    array('getWidgetSupportedBlocks', 'Mage_Widget_Model_Widget_Instance'),
+    array('getWidgetSupportedTemplatesByBlock', 'Mage_Widget_Model_Widget_Instance'),
+    array('hasItems', 'Mage_Wishlist_Helper_Data'),
+    array('htmlEscape', null, 'escapeHtml'),
+    array('imageAction', 'Mage_Catalog_ProductController'),
+    array('importFromTextArray'),
+    array('initLabels', 'Mage_Catalog_Model_Resource_Eav_Attribute'),
+    array('insertProductPrice', 'Mage_Catalog_Model_Resource_Product_Attribute_Backend_Tierprice'),
+    array('isAllowedGuestCheckout', 'Mage_Sales_Model_Quote'),
+    array('isAutomaticCleaningAvailable', 'Varien_Cache_Backend_Eaccelerator'),
+    array('isCheckoutAvailable', 'Mage_Checkout_Model_Type_Multishipping'),
+    array('isFulAmountCovered'),
+    array('isLeyeredNavigationAllowed'),
+    array('isReadablePopupObject'),
+    array('isTemplateAllowedForApplication'),
+    array('loadLabel', 'Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute'),
+    array('loadParentProductIds', 'Mage_Catalog_Model_Product'),
+    array('loadPrices', 'Mage_Catalog_Model_Resource_Product_Type_Configurable_Attribute'),
+    array('loadProductPrices', 'Mage_Catalog_Model_Resource_Product_Attribute_Backend_Tierprice'),
+    array('lockOrderInventoryData', 'Mage_CatalogInventory_Model_Observer'),
+    array('logEncryptionKeySave'),
+    array('logInvitationSave'),
+    array('mergeFiles', 'Mage_Core_Helper_Data'),
+    array('order_success_page_view', 'Mage_GoogleAnalytics_Model_Observer'),
+    array('orderedAction', 'Mage_Adminhtml_Report_ProductController'),
+    array('parseDateTime', 'Mage_Core_Model_Date'),
+    array('postDispatchMyAccountSave'),
+    array('postDispatchSystemImportExportRun'),
+    array('prepareCacheId', 'Mage_Core_Model_App'),
+    array('prepareGoogleOptimizerScripts'),
+    array('preprocess', 'Mage_Newsletter_Model_Template'),
+    array('processBeacon'),
+    array('processBeforeVoid', 'Mage_Payment_Model_Method_Abstract'),
+    array('processSubst', 'Mage_Core_Model_Store'),
+    array('productEventAggregate'),
+    array('push', 'Mage_Catalog_Model_Product_Image'),
+    array('rebuildCategoryLevels', 'Mage_Catalog_Model_Resource_Setup'),
+    array('regenerateSessionId', 'Mage_Core_Model_Session_Abstract'),
+    array('refundOrderItem', 'Mage_CatalogInventory_Model_Observer'),
+    array('renderView', null, 'Mage_Core_Block_Template::_toHtml()'),
+    array('removeCustomerFromSegments'),
+    array('revalidateCookie', 'Mage_Core_Model_Session_Abstract_Varien'),
+    array('sales_order_afterPlace'),
+    array('sales_quote_address_discount_item'),
+    array('salesOrderPaymentPlaceEnd'),
+    array('saveRow__OLD'),
+    array('saveAction', 'Mage_Tag_CustomerController'),
+    array('saveSegmentCustomersFromSelect'),
+    array('send', 'Mage_Newsletter_Model_Template'),
+    array('sendNewPasswordEmail'),
+    array('setAnonSuffix'),
+    array('setAttributeSetExcludeFilter', 'Mage_Eav_Model_Resource_Entity_Attribute_Collection'),
+    array('setBlockAlias'),
+    array('setCustomerId', 'Mage_Customer_Model_Resource_Address'),
+    array('setIsAjaxRequest', 'Mage_Core_Model_Translate_Inline'),
+    array('setJoinFlag', 'Mage_Tag_Model_Resource_Customer_Collection'),
+    array('setJoinFlag', 'Mage_Tag_Model_Resource_Product_Collection'),
+    array('setJoinFlag', 'Mage_Tag_Model_Resource_Tag_Collection'),
+    array('setOption', 'Mage_Captcha_Helper_Data'),
+    array('setOrderId', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('setNeedUsePriceExcludeTax', null, 'Mage_Tax_Model_Config::setPriceIncludesTax()'),
+    array('setScriptPath', 'Mage_Core_Block_Template'),
+    array('setVarSubFolders'),
+    array('setWatermarkHeigth', null, 'setWatermarkHeight'),
+    array('getWatermarkHeigth', null, 'getWatermarkHeight'),
+    array('setOptions', 'Mage_Core_Model_Config'),
+    array('setParentBlock'),
+    array('setProfile', 'Varien_Convert_Container_Abstract'),
+    array('setSaveTemplateFlag', 'Mage_Newsletter_Model_Queue'),
+    array('setScriptPath'),
+    array('setShipId', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('setTaxGroupFilter'),
+    array('setTrackId', 'Mage_Shipping_Block_Tracking_Popup'),
+    array('shaCrypt', null, 'Mage_Ogone_Model_Api::getHash'),
+    array('shaCryptValidation', null, 'Mage_Ogone_Model_Api::getHash'),
+    array('shouldCustomerHaveOneBalance'),
+    array('shouldShowOneBalance'),
+    array('substDistroServerVars', 'Mage_Core_Model_Config'),
+    array('sortChildren'),
+    array('toOptionArray', 'Mage_Cms_Model_Resource_Page_Collection'),
+    array('toOptionArray', 'Mage_Sendfriend_Model_Sendfriend'),
+    array('truncate', 'Varien_Db_Adapter_Pdo_Mysql'),
+    array('unsetBlock'),
+    array('unsetJoinFlag', 'Mage_Tag_Model_Resource_Customer_Collection'),
+    array('unsetJoinFlag', 'Mage_Tag_Model_Resource_Product_Collection'),
+    array('unsetJoinFlag', 'Mage_Tag_Model_Resource_Tag_Collection'),
+    array('useValidateRemoteAddr', 'Mage_Core_Model_Session_Abstract'),
+    array('useValidateHttpVia', 'Mage_Core_Model_Session_Abstract'),
+    array('useValidateHttpXForwardedFor', 'Mage_Core_Model_Session_Abstract'),
+    array('useValidateHttpUserAgent', 'Mage_Core_Model_Session_Abstract'),
+    array('updateCofigurableProductOptions', 'Mage_Weee_Model_Observer', 'updateConfigurableProductOptions'),
+    array('updateTable', 'Mage_Core_Model_Resource_Setup'),
+    array('urlEscape', null, 'escapeUrl'),
+    array('validateDataArray', 'Varien_Convert_Container_Abstract'),
+    array('validateFile', 'Mage_Core_Model_Design_Package'),
+    array('validateOrder', 'Mage_Checkout_Model_Type_Onepage'),
+    array('prepareAttributesForSave', 'Mage_ImportExport_Model_Import_Entity_Product'),
+    array('fetchUpdatesByHandle', 'Mage_Core_Model_Resource_Layout',
         'Mage_Core_Model_Resource_Layout_Update'),
-    $this->_getRule('getElementClass', 'Mage_Core_Model_Layout_Update'),
-    $this->_getRule('addUpdate', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('asArray', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('asString', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('addHandle', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('removeHandle', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getHandles', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('addPageHandles', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getPageHandleParents', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('pageHandleExists', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getPageHandles', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getPageHandlesHierarchy', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getPageHandleLabel', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getPageHandleType', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('load', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('asSimplexml', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getFileLayoutUpdatesXml', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getContainers', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
-    $this->_getRule('getPostMaxSize', 'Mage_Adminhtml_Block_Media_Uploader',
-        'Magento_File_Size::getPostMaxSize()'),
-    $this->_getRule('getUploadMaxSize', 'Mage_Adminhtml_Block_Media_Uploader',
-        'Magento_File_Size::getUploadMaxSize()'),
-    $this->_getRule('getDataMaxSize'),
-    $this->_getRule('getDataMaxSizeInBytes', 'Mage_Adminhtml_Block_Media_Uploader',
-        'Magento_File_Size::getMaxFileSize()'),
-    $this->_getRule('_getBytesIniValue', 'Mage_Catalog_Model_Product_Option_Type_File'),
-    $this->_getRule('_getUploadMaxFilesize', 'Mage_Catalog_Model_Product_Option_Type_File'),
-    $this->_getRule('_bytesToMbytes', 'Mage_Catalog_Model_Product_Option_Type_File'),
-    $this->_getRule('getMaxUploadSize', 'Mage_ImportExport_Helper_Data', 'getMaxUploadSizeMessage'),
-    $this->_getRule('prepareRedirect', 'Mage_Core_Controller_Varien_Exception'),
-    $this->_getRule('getPostMaxSize', 'Mage_Adminhtml_Block_Media_Uploader',
-        'Magento_File_Size::getPostMaxSize()'),
-    $this->_getRule('getUploadMaxSize', 'Mage_Adminhtml_Block_Media_Uploader',
-        'Magento_File_Size::getUploadMaxSize()'),
-    $this->_getRule('getDataMaxSize'),
-    $this->_getRule('getDataMaxSizeInBytes', 'Mage_Adminhtml_Block_Media_Uploader',
-        'Magento_File_Size::getMaxFileSize()'),
-    $this->_getRule('_getBytesIniValue', 'Mage_Catalog_Model_Product_Option_Type_File'),
-    $this->_getRule('_getUploadMaxFilesize', 'Mage_Catalog_Model_Product_Option_Type_File'),
-    $this->_getRule('_bytesToMbytes', 'Mage_Catalog_Model_Product_Option_Type_File'),
-    $this->_getRule('getMaxUploadSize', 'Mage_ImportExport_Helper_Data', 'getMaxUploadSizeMessage'),
-    $this->_getRule('getOptions', 'Mage_Core_Model_Design_Source_Design',
+    array('getElementClass', 'Mage_Core_Model_Layout_Update'),
+    array('addUpdate', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('asArray', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('asString', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('addHandle', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('removeHandle', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getHandles', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('addPageHandles', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getPageHandleParents', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('pageHandleExists', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getPageHandles', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getPageHandlesHierarchy', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getPageHandleLabel', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getPageHandleType', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('load', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('asSimplexml', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getFileLayoutUpdatesXml', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getContainers', 'Mage_Core_Model_Layout_Update', 'Mage_Core_Model_Layout_Merge'),
+    array('getDataMaxSize'),
+    array('getDataMaxSizeInBytes', 'Mage_Adminhtml_Block_Media_Uploader', 'Magento_File_Size::getMaxFileSize()'),
+    array('getPostMaxSize', 'Mage_Adminhtml_Block_Media_Uploader', 'Magento_File_Size::getPostMaxSize()'),
+    array('getUploadMaxSize', 'Mage_Adminhtml_Block_Media_Uploader', 'Magento_File_Size::getUploadMaxSize()'),
+    array('_getBytesIniValue', 'Mage_Catalog_Model_Product_Option_Type_File'),
+    array('_getUploadMaxFilesize', 'Mage_Catalog_Model_Product_Option_Type_File'),
+    array('_bytesToMbytes', 'Mage_Catalog_Model_Product_Option_Type_File'),
+    array('getMaxUploadSize', 'Mage_ImportExport_Helper_Data', 'getMaxUploadSizeMessage'),
+    array('prepareRedirect', 'Mage_Core_Controller_Varien_Exception'),
+    array('getOptions', 'Mage_Core_Model_Design_Source_Design',
         'Mage_Core_Model_Theme::getThemeCollectionOptionArray'),
-    $this->_getRule('getThemeOptions', 'Mage_Core_Model_Design_Source_Design',
+    array('getThemeOptions', 'Mage_Core_Model_Design_Source_Design',
         'Mage_Core_Model_Theme::getThemeCollectionOptionArray'),
-    $this->_getRule('isThemeCompatible', 'Mage_Core_Model_Design_Package', 'Mage_Core_Model_Theme::isThemeCompatible'),
-    $this->_getRule('setPackageTheme', 'Mage_Widget_Model_Widget_Instance', 'setThemeId'),
-    $this->_getRule('getPackageTheme', 'Mage_Widget_Model_Widget_Instance', 'getThemeId'),
-    $this->_getRule('getPackage', 'Mage_Widget_Model_Widget_Instance'),
-    $this->_getRule('getTheme', 'Mage_Widget_Model_Widget_Instance'),
-    $this->_getRule('_parsePackageTheme', 'Mage_Widget_Model_Widget_Instance'),
+    array('isThemeCompatible', 'Mage_Core_Model_Design_Package', 'Mage_Core_Model_Theme::isThemeCompatible'),
+    array('setPackageTheme', 'Mage_Widget_Model_Widget_Instance', 'setThemeId'),
+    array('getPackageTheme', 'Mage_Widget_Model_Widget_Instance', 'getThemeId'),
+    array('getPackage', 'Mage_Widget_Model_Widget_Instance'),
+    array('getTheme', 'Mage_Widget_Model_Widget_Instance'),
+    array('_parsePackageTheme', 'Mage_Widget_Model_Widget_Instance'),
+    array('isVerbose', 'Magento_Shell'),
+    array('setVerbose', 'Magento_Shell'),
+    array('output', 'Magento_Shell'),
+    array('getHeaderText', 'Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search'),
+    array('getButtonsHtml', 'Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search'),
+    array('getHeaderCssClass', 'Mage_Bundle_Block_Adminhtml_Catalog_Product_Edit_Tab_Bundle_Option_Search'),
+    array('superGroupGridOnlyAction', 'Mage_Adminhtml_Catalog_ProductController'),
 );
diff --git a/dev/tests/static/testsuite/Legacy/_files/obsolete_properties.php b/dev/tests/static/testsuite/Legacy/_files/obsolete_properties.php
index fae1c41ad0d..d914ac1a508 100644
--- a/dev/tests/static/testsuite/Legacy/_files/obsolete_properties.php
+++ b/dev/tests/static/testsuite/Legacy/_files/obsolete_properties.php
@@ -1,5 +1,9 @@
 <?php
 /**
+ * Obsolete class attributes
+ *
+ * Format: array(<attribute_name>[, <class_scope> = ''[, <replacement>]])
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -18,54 +22,60 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @category    tests
- * @package     static
- * @subpackage  Legacy
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 return array(
-    $this->_getRule('_anonSuffix'),
-    $this->_getRule('_isAnonymous'),
-    $this->_getRule('decoratedIsFirst', null, 'getDecoratedIsFirst'),
-    $this->_getRule('decoratedIsEven', null, 'getDecoratedIsEven'),
-    $this->_getRule('decoratedIsOdd', null, 'getDecoratedIsOdd'),
-    $this->_getRule('decoratedIsLast', null, 'getDecoratedIsLast'),
-    $this->_getRule('_alias', 'Mage_Core_Block_Abstract'),
-    $this->_getRule('_children', 'Mage_Core_Block_Abstract'),
-    $this->_getRule('_childrenHtmlCache', 'Mage_Core_Block_Abstract'),
-    $this->_getRule('_childGroups', 'Mage_Core_Block_Abstract'),
-    $this->_getRule('_canUseLocalModules'),
-    $this->_getRule('_currencyNameTable'),
-    $this->_getRule('_combineHistory'),
-    $this->_getRule('_searchTextFields'),
-    $this->_getRule('_skipFieldsByModel'),
-    $this->_getRule('_parent', 'Mage_Core_Block_Abstract'),
-    $this->_getRule('_parentBlock', 'Mage_Core_Block_Abstract'),
-    $this->_getRule('_setAttributes', 'Mage_Catalog_Model_Product_Type_Abstract'),
-    $this->_getRule('_storeFilter', 'Mage_Catalog_Model_Product_Type_Abstract'),
-    $this->_getRule('_addMinimalPrice', 'Mage_Catalog_Model_Resource_Product_Collection'),
-    $this->_getRule('_checkedProductsQty', 'Mage_CatalogInventory_Model_Observer'),
-    $this->_getRule('_baseDirCache', 'Mage_Core_Model_Config'),
-    $this->_getRule('_customEtcDir', 'Mage_Core_Model_Config'),
-    $this->_getRule('static', 'Mage_Core_Model_Email_Template_Filter'),
-    $this->_getRule('_loadDefault', 'Mage_Core_Model_Resource_Store_Collection'),
-    $this->_getRule('_loadDefault', 'Mage_Core_Model_Resource_Store_Group_Collection'),
-    $this->_getRule('_loadDefault', 'Mage_Core_Model_Resource_Website_Collection'),
-    $this->_getRule('_addresses', 'Mage_Customer_Model_Customer'),
-    $this->_getRule('_currency', 'Mage_GoogleCheckout_Model_Api_Xml_Checkout'),
-    $this->_getRule('_saveTemplateFlag', 'Mage_Newsletter_Model_Queue'),
-    $this->_getRule('_ratingOptionTable', 'Mage_Rating_Model_Resource_Rating_Option_Collection'),
-    $this->_getRule('_entityTypeIdsToTypes'),
-    $this->_getRule('_entityIdsToIncrementIds'),
-    $this->_getRule('_isFirstTimeProcessRun', 'Mage_SalesRule_Model_Validator'),
-    $this->_getRule('_shipTable', 'Mage_Shipping_Model_Resource_Carrier_Tablerate_Collection'),
-    $this->_getRule('_designProductSettingsApplied'),
-    $this->_getRule('_order', 'Mage_Checkout_Block_Onepage_Success'),
-    $this->_getRule('_track_id'),
-    $this->_getRule('_order_id'),
-    $this->_getRule('_ship_id'),
-    $this->_getRule('_sortedChildren'),
-    $this->_getRule('_sortInstructions'),
-    $this->_getRule('_config', 'Mage_Core_Model_Design_Package'),
+    array('_alias', 'Mage_Core_Block_Abstract'),
+    array('_anonSuffix'),
+    array('_isAnonymous'),
+    array('_children', 'Mage_Core_Block_Abstract'),
+    array('_childrenHtmlCache', 'Mage_Core_Block_Abstract'),
+    array('_childGroups', 'Mage_Core_Block_Abstract'),
+    array('_canUseLocalModules'),
+    array('_config', 'Mage_Core_Model_Design_Package'),
+    array('_config', 'Mage_Core_Model_Logger', '_dirs'),
+    array('_configuration', 'Mage_Index_Model_Lock_Storage', '_dirs'),
+    array('_combineHistory'),
+    array('_currencyNameTable'),
+    array('decoratedIsFirst', null, 'getDecoratedIsFirst'),
+    array('decoratedIsEven', null, 'getDecoratedIsEven'),
+    array('decoratedIsOdd', null, 'getDecoratedIsOdd'),
+    array('decoratedIsLast', null, 'getDecoratedIsLast'),
+    array('_distroServerVars'),
+    array('_searchTextFields'),
+    array('_skipFieldsByModel'),
+    array('_parent', 'Mage_Core_Block_Abstract'),
+    array('_parentBlock', 'Mage_Core_Block_Abstract'),
+    array('_setAttributes', 'Mage_Catalog_Model_Product_Type_Abstract'),
+    array('_storeFilter', 'Mage_Catalog_Model_Product_Type_Abstract'),
+    array('_addMinimalPrice', 'Mage_Catalog_Model_Resource_Product_Collection'),
+    array('_checkedProductsQty', 'Mage_CatalogInventory_Model_Observer'),
+    array('_baseDirCache', 'Mage_Core_Model_Config'),
+    array('_customEtcDir', 'Mage_Core_Model_Config'),
+    array('static', 'Mage_Core_Model_Email_Template_Filter'),
+    array('_loadDefault', 'Mage_Core_Model_Resource_Store_Collection'),
+    array('_loadDefault', 'Mage_Core_Model_Resource_Store_Group_Collection'),
+    array('_loadDefault', 'Mage_Core_Model_Resource_Website_Collection'),
+    array('_addresses', 'Mage_Customer_Model_Customer'),
+    array('_currency', 'Mage_GoogleCheckout_Model_Api_Xml_Checkout'),
+    array('_saveTemplateFlag', 'Mage_Newsletter_Model_Queue'),
+    array('_ratingOptionTable', 'Mage_Rating_Model_Resource_Rating_Option_Collection'),
+    array('_entityTypeIdsToTypes'),
+    array('_entityIdsToIncrementIds'),
+    array('_isFirstTimeProcessRun', 'Mage_SalesRule_Model_Validator'),
+    array('_shipTable', 'Mage_Shipping_Model_Resource_Carrier_Tablerate_Collection'),
+    array('_designProductSettingsApplied'),
+    array('_option', 'Mage_Captcha_Helper_Data', '_dirs'),
+    array('_options', 'Mage_Core_Model_Config', 'Mage_Core_Model_Dir'),
+    array('_optionsMapping', null, 'Mage::getBaseDir($nodeKey)'),
+    array('_order', 'Mage_Checkout_Block_Onepage_Success'),
+    array('_order_id'),
+    array('_ship_id'),
+    array('_sortedChildren'),
+    array('_sortInstructions'),
+    array('_substServerVars'),
+    array('_track_id'),
+    array('_varSubFolders', null, 'Mage_Core_Model_Dir'),
+    array('_viewDir', 'Mage_Core_Block_Template', '_dirs'),
 );
diff --git a/dev/tests/static/testsuite/Legacy/_files/words_core.xml b/dev/tests/static/testsuite/Legacy/_files/words_core.xml
index 1042f311ed2..22e6bd4d100 100644
--- a/dev/tests/static/testsuite/Legacy/_files/words_core.xml
+++ b/dev/tests/static/testsuite/Legacy/_files/words_core.xml
@@ -40,6 +40,9 @@
         <word>system/convert/profiles</word>
         <word>Mage_Adminhtml::gui</word>
         <word>Mage_Adminhtml::profiles</word>
+        <word>secure_base_url}}js/</word>
+        <word>secure_base_url}}skin/</word>
+        <word>secure_base_url}}media/</word>
     </words>
     <whitelist>
         <item>
diff --git a/dev/tests/static/testsuite/Php/Exemplar/CodeStyleTest.php b/dev/tests/static/testsuite/Php/Exemplar/CodeStyleTest.php
index d868f37e8e7..32b11a7aa5b 100644
--- a/dev/tests/static/testsuite/Php/Exemplar/CodeStyleTest.php
+++ b/dev/tests/static/testsuite/Php/Exemplar/CodeStyleTest.php
@@ -35,7 +35,7 @@
 class Php_Exemplar_CodeStyleTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * @var Inspection_CodeSniffer_Command
+     * @var CodingStandard_Tool_CodeSniffer
      */
     protected static $_cmd = null;
 
diff --git a/dev/tests/static/testsuite/Php/LiveCodeTest.php b/dev/tests/static/testsuite/Php/LiveCodeTest.php
index 5176569fb7f..02b867447c3 100644
--- a/dev/tests/static/testsuite/Php/LiveCodeTest.php
+++ b/dev/tests/static/testsuite/Php/LiveCodeTest.php
@@ -100,7 +100,7 @@ class Php_LiveCodeTest extends PHPUnit_Framework_TestCase
         }
 
         $this->assertTrue($copyPasteDetector->run(array(), $blackList),
-            "PHP Code Mess has found error(s): See detailed report in $reportFile"
+            "PHP Copy/Paste Detector has found error(s): See detailed report in $reportFile"
         );
     }
 
diff --git a/dev/tests/static/testsuite/Php/_files/blacklist/common.txt b/dev/tests/static/testsuite/Php/_files/blacklist/common.txt
index 0002d2b805f..fd9c398bc5a 100644
--- a/dev/tests/static/testsuite/Php/_files/blacklist/common.txt
+++ b/dev/tests/static/testsuite/Php/_files/blacklist/common.txt
@@ -6,22 +6,13 @@ app/code/core/Mage/Backend/Model/Config.php
 app/code/core/Mage/Backend/Model/Config/Structure/Converter.php
 app/code/core/Mage/Backend/Model/Menu/Config.php
 app/code/core/Mage/Backend/Block/Widget/Grid
+app/code/core/Mage/Backend/view
 app/code/core/Mage/DesignEditor/view
 app/code/core/Mage/Webapi/view
-app/code/core/Mage/Core/data/core_setup/data-upgrade-1.6.0.4-1.6.0.5.php
-app/code/core/Mage/Theme/Helper/Data.php
-app/code/core/Mage/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php
 app/code/core/Mage/User/view
-lib/Magento/Config/Dom.php
-lib/Magento/Config/Theme.php
-lib/Magento/Data
-lib/Magento/Shell.php
-lib/Magento/Validator.php
 dev/tests/integration/testsuite/integrity/modular/TemplateFilesTest.php
 dev/tests/integration/testsuite/integrity/theme/TemplateFilesTest.php
 dev/tests/integration/testsuite/Mage/Backend/Block/System/Config/FormStub.php
-dev/tests/integration/testsuite/Mage/Core/Block/_files
 dev/tests/integration/tmp
 dev/tests/static/testsuite/Php/Exemplar/_files/phpcs/input
 dev/tests/static/testsuite/Php/Exemplar/_files/phpmd/input
-app/code/core/Mage/Backend/view
\ No newline at end of file
diff --git a/dev/tests/static/testsuite/Php/_files/whitelist/common.txt b/dev/tests/static/testsuite/Php/_files/whitelist/common.txt
index 124d474a7c2..339d7620651 100644
--- a/dev/tests/static/testsuite/Php/_files/whitelist/common.txt
+++ b/dev/tests/static/testsuite/Php/_files/whitelist/common.txt
@@ -19,34 +19,40 @@ app/code/core/Mage/Adminhtml/controllers/Report/ProductController.php
 app/code/core/Mage/Adminhtml/controllers/UrlrewriteController.php
 app/code/core/Mage/Backend
 app/code/core/Mage/Catalog/Block/Product/Configurable
+app/code/core/Mage/Catalog/Block/Product/Grouped
 app/code/core/Mage/Catalog/Model/Resource/Product/Collection
 app/code/core/Mage/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
-app/code/core/Mage/Core/Block/Abstract.php
-app/code/core/Mage/Core/data
-app/code/core/Mage/Core/Model/Config.php
 app/code/core/Mage/Centinel/Model/State/Jcb.php
+app/code/core/Mage/Cms/Controller/Router.php
+app/code/core/Mage/Core/Block/Abstract.php
 app/code/core/Mage/Core/Controller/Varien/ActionAbstract.php
 app/code/core/Mage/Core/Controller/Varien/Action/Factory.php
 app/code/core/Mage/Core/Controller/Varien/Router/Factory.php
+app/code/core/Mage/Core/Controller/Varien/Action/Forward.php
+app/code/core/Mage/Core/Controller/Varien/DispatchableInterface.php
+app/code/core/Mage/Core/Controller/Varien/Router/Abstract.php
+app/code/core/Mage/Core/data
+app/code/core/Mage/Core/Model/Config.php
 app/code/core/Mage/Core/Model/Config/Module.php
 app/code/core/Mage/Core/Model/Design.php
+app/code/core/Mage/Core/Model/Design/Fallback
+app/code/core/Mage/Core/Model/Design/Fallback.php
+app/code/core/Mage/Core/Model/Design/FallbackInterface.php
 app/code/core/Mage/Core/Model/Design/Source/Design.php
-app/code/core/Mage/Core/Model/ShellAbstract.php
+app/code/core/Mage/Core/Model/Dir.php
 app/code/core/Mage/Core/Model/Layout.php
 app/code/core/Mage/Core/Model/Layout/Factory.php
 app/code/core/Mage/Core/Model/Layout/Update.php
-app/code/core/Mage/Core/Model/Design/Fallback
-app/code/core/Mage/Core/Model/Design/Fallback.php
-app/code/core/Mage/Core/Model/Design/FallbackInterface.php
+app/code/core/Mage/Core/Model/Layout/Argument
 app/code/core/Mage/Core/Model/Resource/Setup/Migration.php
 app/code/core/Mage/Core/Model/Resource/Theme/Collection.php
 app/code/core/Mage/Core/Model/Resource/Theme.php
+app/code/core/Mage/Core/Model/ShellAbstract.php
 app/code/core/Mage/Core/Model/Theme/Validator.php
 app/code/core/Mage/Core/Model/Theme.php
 app/code/core/Mage/Core/sql/core_setup/upgrade-1.6.0.3-1.6.0.4.php
 app/code/core/Mage/Directory/Model/Currency/DefaultLocator.php
 app/code/core/Mage/DesignEditor
-app/code/core/Mage/Core/Model/Layout/Argument
 app/code/core/Mage/ImportExport/Model/Import/Entity/CustomerComposite.php
 app/code/core/Mage/ImportExport/Model/Import/Entity/Product/Option.php
 app/code/core/Mage/ImportExport/Model/Resource/Customer/Storage.php
@@ -56,6 +62,7 @@ app/code/core/Mage/Index/Model/Shell.php
 app/code/core/Mage/Log/Model/Resource/Helper
 app/code/core/Mage/Log/Model/Resource/Shell.php
 app/code/core/Mage/Log/Model/Shell.php
+app/code/core/Mage/Page/Helper/Robots.php
 app/code/core/Mage/Reports/Block/Adminhtml/Customer
 app/code/core/Mage/Reports/Block/Adminhtml/Product
 app/code/core/Mage/Reports/Model/Resource/Accounts
@@ -65,13 +72,6 @@ app/code/core/Mage/Tag/Block/Adminhtml/Customer/Edit/Tab/Tag.php
 app/code/core/Mage/Tag/Block/Catalog/Product/Rss/Link.php
 app/code/core/Mage/Theme
 app/code/core/Mage/User
-app/code/core/Mage/Core/Controller/Varien/Action/Forward.php
-app/code/core/Mage/Core/Controller/Varien/DispatchableInterface.php
-app/code/core/Mage/Core/Controller/Varien/Router/Abstract.php
-app/code/core/Mage/Cms/Controller/Router.php
-app/code/core/Mage/DesignEditor/Controller/Varien/Router/Standard.php
-app/code/core/Mage/DesignEditor/Helper/Data.php
-app/code/core/Mage/Page/Helper/Robots.php
 app/code/core/Mage/Webapi
 dev/shell
 dev/tests/integration
diff --git a/dev/tests/unit/framework/Magento/Test/Helper/ObjectManager.php b/dev/tests/unit/framework/Magento/Test/Helper/ObjectManager.php
index c6f027fc61c..74b11836bc6 100644
--- a/dev/tests/unit/framework/Magento/Test/Helper/ObjectManager.php
+++ b/dev/tests/unit/framework/Magento/Test/Helper/ObjectManager.php
@@ -60,6 +60,8 @@ class Magento_Test_Helper_ObjectManager
             'storeConfig'        => 'Mage_Core_Model_Store_Config',
             'frontController'    => 'Mage_Core_Controller_Varien_Front',
             'helperFactory'      => 'Mage_Core_Model_Factory_Helper',
+            'dirs'               => 'Mage_Core_Model_Dir',
+            'logger'             => 'Mage_Core_Model_Logger',
             'filesystem'         => 'Magento_Filesystem',
         ),
         self::MODEL_ENTITY => array(
diff --git a/dev/tests/unit/testsuite/Mage/Captcha/Helper/DataTest.php b/dev/tests/unit/testsuite/Mage/Captcha/Helper/DataTest.php
index 2342464b754..bce1e24d08f 100644
--- a/dev/tests/unit/testsuite/Mage/Captcha/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Mage/Captcha/Helper/DataTest.php
@@ -28,8 +28,39 @@
 class Mage_Captcha_Helper_DataTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * Sets up the fixture, for example, opens a network connection.
-     * This method is called before a test is executed.
+     * Fixture for testing getFonts()
+     */
+    const FONT_FIXTURE = '<fonts><font_code><label>Label</label><path>path/to/fixture.ttf</path></font_code></fonts>';
+
+    /**
+     * Temp dir to act as media dir for the test
+     *
+     * @var string
+     */
+    protected $_mediaDir;
+
+    protected function setUp()
+    {
+        $this->_mediaDir = TESTS_TEMP_DIR . DIRECTORY_SEPARATOR . 'media';
+        if (!is_dir($this->_mediaDir)) {
+            mkdir($this->_mediaDir, 0777);
+        }
+    }
+
+    protected function tearDown()
+    {
+        if (is_dir($this->_mediaDir)) {
+            $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
+            $filesystem->delete($this->_mediaDir);
+        }
+    }
+
+    /**
+     * Return helper to be tested
+     *
+     * @param Mage_Core_Model_Store $store
+     * @param Mage_Core_Model_Config $config
+     * @return Mage_Captcha_Helper_Data
      */
     protected function _getHelper($store, $config)
     {
@@ -42,13 +73,19 @@ class Mage_Captcha_Helper_DataTest extends PHPUnit_Framework_TestCase
         $app->expects($this->any())
             ->method('getStore')
             ->will($this->returnValue($store));
+
         $adapterMock = $this->getMockBuilder('Magento_Filesystem_Adapter_Local')
             ->getMock();
         $adapterMock->expects($this->any())
             ->method('isDirectory')
             ->will($this->returnValue(true));
-        $filesystem = new Magento_Filesystem($adapterMock);
-        return new Mage_Captcha_Helper_Data($app, $config, $filesystem);
+        $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
+
+        $customPaths = array(
+            Mage_Core_Model_Dir::MEDIA => $this->_mediaDir
+        );
+        $dirs = new Mage_Core_Model_Dir(TESTS_TEMP_DIR, array(), $customPaths);
+        return new Mage_Captcha_Helper_Data($dirs, $app, $config, $filesystem);
     }
 
     /**
@@ -66,11 +103,12 @@ class Mage_Captcha_Helper_DataTest extends PHPUnit_Framework_TestCase
             ->with('customer/captcha/type')
             ->will($this->returnValue('zend'));
 
+        $objectManager = $this->getMock('Magento_ObjectManager_Zend', array(), array(), '', false);
         $config = $this->_getConfigStub();
         $config->expects($this->once())
             ->method('getModelInstance')
             ->with('Mage_Captcha_Model_Zend')
-            ->will($this->returnValue(new Mage_Captcha_Model_Zend(array('formId' => 'user_create'))));
+            ->will($this->returnValue(new Mage_Captcha_Model_Zend($objectManager, array('formId' => 'user_create'))));
 
         $helper = $this->_getHelper($store, $config);
         $this->assertInstanceOf('Mage_Captcha_Model_Zend', $helper->getCaptcha('user_create'));
@@ -94,28 +132,16 @@ class Mage_Captcha_Helper_DataTest extends PHPUnit_Framework_TestCase
         $object->getConfigNode('enable');
     }
 
-    /**
-     * @covers Mage_Captcha_Helper_Data::getFonts
-     */
     public function testGetFonts()
     {
-        $option = $this->_getOptionStub();
-        $option->expects($this->any())
-            ->method('getDir')
-            ->will($this->returnValue(TESTS_TEMP_DIR));
-        $config = $this->_getConfigStub();
-        $config->expects($this->any())
-            ->method('getOptions')
-            ->will($this->returnValue($option));
-
-        $object = $this->_getHelper($this->_getStoreStub(), $config);
+        $object = $this->_getHelper($this->_getStoreStub(), $this->_getConfigStub());
         $fonts = $object->getFonts();
-
-        $this->assertEquals($fonts['linlibertine']['label'], 'LinLibertine');
-        $this->assertEquals(
-            $fonts['linlibertine']['path'],
-            TESTS_TEMP_DIR . DIRECTORY_SEPARATOR . 'lib/LinLibertineFont/LinLibertine_Bd-2.8.1.ttf'
-        );
+        $this->assertArrayHasKey('font_code', $fonts); // fixture
+        $this->assertArrayHasKey('label', $fonts['font_code']);
+        $this->assertArrayHasKey('path', $fonts['font_code']);
+        $this->assertEquals('Label', $fonts['font_code']['label']);
+        $this->assertStringStartsWith(TESTS_TEMP_DIR, $fonts['font_code']['path']);
+        $this->assertStringEndsWith('path/to/fixture.ttf', $fonts['font_code']['path']);
     }
 
     /**
@@ -124,22 +150,13 @@ class Mage_Captcha_Helper_DataTest extends PHPUnit_Framework_TestCase
      */
     public function testGetImgDir()
     {
-        $captchaTmpDir = TESTS_TEMP_DIR . DIRECTORY_SEPARATOR . 'captcha';
-        $option = $this->_getOptionStub();
-        $option->expects($this->once())
-            ->method('getDir')
-            ->will($this->returnValue($captchaTmpDir));
-        $config = $this->_getConfigStub();
-        $config->expects($this->any())
-            ->method('getOptions')
-            ->will($this->returnValue($option));
-
-        $object = $this->_getHelper($this->_getStoreStub(), $config);
-        $this->assertEquals(
-            $object->getImgDir(),
-            Magento_Filesystem::getPathFromArray(array($captchaTmpDir, 'captcha', 'base'))
-            . Magento_Filesystem::DIRECTORY_SEPARATOR
-        );
+        $object = $this->_getHelper($this->_getStoreStub(), $this->_getConfigStub());
+        $this->assertFileNotExists(TESTS_TEMP_DIR . '/captcha');
+        $result = $object->getImgDir();
+        $result = str_replace('/', DIRECTORY_SEPARATOR, $result);
+        $this->assertFileExists($result);
+        $this->assertStringStartsWith(TESTS_TEMP_DIR, $result);
+        $this->assertStringEndsWith('captcha' . DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR, $result);
     }
 
     /**
@@ -161,33 +178,16 @@ class Mage_Captcha_Helper_DataTest extends PHPUnit_Framework_TestCase
     {
         $config = $this->getMock(
             'Mage_Core_Model_Config',
-            array('getNode', 'getModelInstance', 'getOptions'),
+            array('getNode', 'getModelInstance'),
             array(), '', false
         );
 
         $config->expects($this->any())
             ->method('getNode')
-            ->will($this->returnValue(
-                new SimpleXMLElement('<fonts><linlibertine><label>LinLibertine</label>'
-                    . '<path>lib/LinLibertineFont/LinLibertine_Bd-2.8.1.ttf</path></linlibertine></fonts>')));
+            ->will($this->returnValue(new SimpleXMLElement(self::FONT_FIXTURE)));
         return $config;
     }
 
-    /**
-     * Create option stub
-     *
-     * @return Mage_Core_Model_Config_Options
-     */
-    protected function _getOptionStub()
-    {
-        $option = $this->getMock(
-            'Mage_Core_Model_Config_Options',
-            array('getDir'),
-            array(), '', false
-        );
-        return $option;
-    }
-
     /**
      * Create Website Stub
      *
diff --git a/dev/tests/unit/testsuite/Mage/Captcha/Model/ZendTest.php b/dev/tests/unit/testsuite/Mage/Captcha/Model/ZendTest.php
index 009d906738b..7bf7e81c9de 100644
--- a/dev/tests/unit/testsuite/Mage/Captcha/Model/ZendTest.php
+++ b/dev/tests/unit/testsuite/Mage/Captcha/Model/ZendTest.php
@@ -67,16 +67,27 @@ class Mage_Captcha_Model_ZendTest extends PHPUnit_Framework_TestCase
      */
     protected $_object;
 
+    /**
+     * @var Magento_ObjectManager_Zend
+     */
+    protected $_objectManager;
+
     /**
      * Sets up the fixture, for example, opens a network connection.
      * This method is called before a test is executed.
      */
     protected function setUp()
     {
+        $this->_objectManager = $this->getMock('Magento_ObjectManager_Zend', array('get'), array(), '', false);
+        $this->_objectManager->expects($this->any())
+            ->method('get')
+            ->with('Mage_Captcha_Helper_Data')
+            ->will($this->returnValue($this->_getHelperStub()));
+
         $this->_object = new Mage_Captcha_Model_Zend(
+            $this->_objectManager,
             array(
                 'formId' => 'user_create',
-                'helper' => $this->_getHelperStub(),
                 'session' => $this->_getSessionStub()
             )
         );
@@ -169,9 +180,9 @@ class Mage_Captcha_Model_ZendTest extends PHPUnit_Framework_TestCase
         $resourceModel = $this->_getResourceModelStub();
 
         $captcha = new Mage_Captcha_Model_Zend(
+            $this->_objectManager,
             array(
                 'formId' => 'user_create',
-                'helper' => $this->_getHelperStub(),
                 'session' => $this->_getSessionStub(),
                 'resourceModel' => $resourceModel,
             )
diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
index fef92dcda2d..1b926a9463b 100644
--- a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
+++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Attribute/Backend/MediaTest.php
@@ -39,8 +39,12 @@ class Mage_Catalog_Model_Product_Attribute_Backend_MediaTest extends PHPUnit_Fra
             ->method('getMainTable')
             ->will($this->returnValue('table'));
 
+        $mediaConfig = $this->getMock('Mage_Catalog_Model_Product_Media_Config', array(), array(), '', false);
+        $dirs = $this->getMock('Mage_Core_Model_Dir', array(), array(), '', false);
         $filesystem = $this->getMockBuilder('Magento_Filesystem')->disableOriginalConstructor()->getMock();
         $this->_model = new Mage_Catalog_Model_Product_Attribute_Backend_Media(
+            $mediaConfig,
+            $dirs,
             $filesystem,
             array('resourceModel' => $resource)
         );
diff --git a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php
index 6bbe7a3a2c5..32c82982cb9 100644
--- a/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php
+++ b/dev/tests/unit/testsuite/Mage/Catalog/Model/Product/Type/ConfigurableTest.php
@@ -38,8 +38,8 @@ class Mage_Catalog_Model_Product_Type_ConfigurableTest extends PHPUnit_Framework
         $this->_model = new Mage_Catalog_Model_Product_Type_Configurable($filesystem);
     }
 
-    public function testHasWeightFalse()
+    public function testHasWeightTrue()
     {
-        $this->assertFalse($this->_model->hasWeight(), 'This product has weight, but it should not');
+        $this->assertTrue($this->_model->hasWeight(), 'This product has not weight, but it should');
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Core/Block/AbstractTest.php b/dev/tests/unit/testsuite/Mage/Core/Block/AbstractTest.php
index 015ca69670b..dd938996bf0 100644
--- a/dev/tests/unit/testsuite/Mage/Core/Block/AbstractTest.php
+++ b/dev/tests/unit/testsuite/Mage/Core/Block/AbstractTest.php
@@ -31,13 +31,12 @@ class Mage_Core_Block_AbstractTest extends PHPUnit_Framework_TestCase
      * @param string $expectedResult
      * @param string $nameInLayout
      * @param array $methodArguments
-     * @dataProvider dataGetUiId
+     * @dataProvider getUiIdDataProvider
      */
     public function testGetUiId($expectedResult, $nameInLayout, $methodArguments)
     {
-        /** @var $block Mage_Core_Block_Abstract */
-        $block = $this->getMockForAbstractClass('Mage_Core_Block_Abstract',
-            array(), '', false);
+        /** @var $block Mage_Core_Block_Abstract|PHPUnit_Framework_MockObject_MockObject */
+        $block = $this->getMockForAbstractClass('Mage_Core_Block_Abstract', array(), '', false);
         $block->setNameInLayout($nameInLayout);
 
         $this->assertEquals(
@@ -46,7 +45,10 @@ class Mage_Core_Block_AbstractTest extends PHPUnit_Framework_TestCase
         );
     }
 
-    public static function dataGetUiId()
+    /**
+     * @return array
+     */
+    public function getUiIdDataProvider()
     {
         return array(
             array(' data-ui-id="" ', null, array()),
@@ -67,4 +69,32 @@ class Mage_Core_Block_AbstractTest extends PHPUnit_Framework_TestCase
             ),
         );
     }
+
+    public function testGetVar()
+    {
+        $filesystemMock = $this->getMock('Magento_Filesystem', array(), array(), '', false);
+        $design = $this->getMock('Mage_Core_Model_Design_Package', array('getViewConfig'), array($filesystemMock));
+        /** @var $block Mage_Core_Block_Abstract|PHPUnit_Framework_MockObject_MockObject */
+        $block = $this->getMockForAbstractClass('Mage_Core_Block_Abstract', array(
+            $this->getMock('Mage_Core_Controller_Request_Http'),
+            $this->getMock('Mage_Core_Model_Layout', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Event_Manager'),
+            $this->getMock('Mage_Core_Model_Url'),
+            $this->getMock('Mage_Core_Model_Translate', array(), array($design)),
+            $this->getMock('Mage_Core_Model_Cache', array(), array(), '', false),
+            $design,
+            $this->getMock('Mage_Core_Model_Session'),
+            $this->getMock('Mage_Core_Model_Store_Config'),
+            $this->getMock('Mage_Core_Controller_Varien_Front', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Factory_Helper'),
+        ), uniqid('Mage_Core_Block_Abstract_'));
+        $config = $this->getMock('Magento_Config_View', array('getVarValue'), array(), '', false);
+        $design->expects($this->exactly(2))->method('getViewConfig')->will($this->returnValue($config));
+        $module = uniqid();
+        $config->expects($this->at(0))->method('getVarValue')->with('Mage_Core', 'v1')->will($this->returnValue('one'));
+        $config->expects($this->at(1))->method('getVarValue')->with($module, 'v2')->will($this->returnValue('two'));
+
+        $this->assertEquals('one', $block->getVar('v1'));
+        $this->assertEquals('two', $block->getVar('v2', $module));
+    }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Core/Block/TemplateTest.php b/dev/tests/unit/testsuite/Mage/Core/Block/TemplateTest.php
new file mode 100644
index 00000000000..c247e195aa1
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Core/Block/TemplateTest.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.
+ *
+ * @category    Magento
+ * @package     Mage_Core
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Core_Block_TemplateTest extends PHPUnit_Framework_TestCase
+{
+    public function testGetTemplateFile()
+    {
+        $design = $this->getMock('Mage_Core_Model_Design_Package', array('getFilename'), array(), '', false);
+        $template = 'fixture';
+        $area = 'areaFixture';
+        $block = new Mage_Core_Block_Template(
+            $this->getMock('Mage_Core_Controller_Request_Http'),
+            $this->getMock('Mage_Core_Model_Layout', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Event_Manager'),
+            $this->getMock('Mage_Core_Model_Url'),
+            $this->getMock('Mage_Core_Model_Translate', array(), array($design)),
+            $this->getMock('Mage_Core_Model_Cache', array(), array(), '', false),
+            $design,
+            $this->getMock('Mage_Core_Model_Session'),
+            $this->getMock('Mage_Core_Model_Store_Config'),
+            $this->getMock('Mage_Core_Controller_Varien_Front', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Factory_Helper'),
+            $this->getMock('Mage_Core_Model_Dir', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Logger', array(), array(), '', false),
+            $this->getMock('Magento_Filesystem', array(), array(), '', false),
+            array('template' => $template, 'area' => $area)
+        );
+
+        $params = array('module' => 'Mage_Core', 'area' => $area);
+        $design->expects($this->once())->method('getFilename')->with($template, $params);
+        $block->getTemplateFile();
+    }
+
+    /**
+     * @param string $filename
+     * @param string $expectedOutput
+     * @dataProvider fetchViewDataProvider
+     */
+    public function testFetchView($filename, $expectedOutput)
+    {
+        $layout = $this->getMock('Mage_Core_Model_Layout', array('isDirectOutput'), array(), '', false);
+        $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
+        $design = $this->getMock('Mage_Core_Model_Design_Package', array(), array($filesystem));
+        $block = $this->getMock('Mage_Core_Block_Template', array('getShowTemplateHints'), array(
+            $this->getMock('Mage_Core_Controller_Request_Http'),
+            $layout,
+            $this->getMock('Mage_Core_Model_Event_Manager'),
+            $this->getMock('Mage_Core_Model_Url'),
+            $this->getMock('Mage_Core_Model_Translate', array(), array($design)),
+            $this->getMock('Mage_Core_Model_Cache', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Design_Package', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Session'),
+            $this->getMock('Mage_Core_Model_Store_Config'),
+            $this->getMock('Mage_Core_Controller_Varien_Front', array(), array(), '', false),
+            $this->getMock('Mage_Core_Model_Factory_Helper'),
+            new Mage_Core_Model_Dir(
+                __DIR__ . '/_files',
+                array(Mage_Core_Model_Dir::APP => ''),
+                array(Mage_Core_Model_Dir::APP => __DIR__)
+            ),
+            $this->getMock('Mage_Core_Model_Logger', array('log'), array(), '', false),
+            $filesystem
+        ));
+        $layout->expects($this->once())->method('isDirectOutput')->will($this->returnValue(false));
+
+        $this->assertSame($block, $block->assign(array('varOne' => 'value1', 'varTwo' => 'value2')));
+        $this->assertEquals($expectedOutput, $block->fetchView(__DIR__ . "/_files/{$filename}"));
+    }
+
+    /**
+     * @return array
+     */
+    public function fetchViewDataProvider()
+    {
+        return array(
+            array('template_test_assign.phtml', 'value1, value2'),
+            array('invalid_file', ''),
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Mage/Core/Block/_files/template_test_assign.phtml b/dev/tests/unit/testsuite/Mage/Core/Block/_files/template_test_assign.phtml
similarity index 96%
rename from dev/tests/integration/testsuite/Mage/Core/Block/_files/template_test_assign.phtml
rename to dev/tests/unit/testsuite/Mage/Core/Block/_files/template_test_assign.phtml
index c64f82e2a48..456da5eede2 100644
--- a/dev/tests/integration/testsuite/Mage/Core/Block/_files/template_test_assign.phtml
+++ b/dev/tests/unit/testsuite/Mage/Core/Block/_files/template_test_assign.phtml
@@ -25,4 +25,5 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 ?>
-<?php echo $varOne . ', ' . $varTwo ?>
+<?php
+echo $varOne . ', ' . $varTwo;
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/App/OptionsTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/App/OptionsTest.php
deleted file mode 100644
index 5a04e56fa3c..00000000000
--- a/dev/tests/unit/testsuite/Mage/Core/Model/App/OptionsTest.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.
- *
- * @category    Magento
- * @package     Mage_Core
- * @subpackage  unit_tests
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-class Mage_Core_Model_App_OptionsTest extends PHPUnit_Framework_TestCase
-{
-    public function testGetRunCode()
-    {
-        $model = new Mage_Core_Model_App_Options(array());
-        $this->assertEmpty($model->getRunCode());
-
-        $model = new Mage_Core_Model_App_Options(array(Mage_Core_Model_App_Options::OPTION_APP_RUN_CODE => 'test'));
-        $this->assertEquals('test', $model->getRunCode());
-    }
-
-    public function testGetRunType()
-    {
-        $model = new Mage_Core_Model_App_Options(array());
-        $this->assertEquals(Mage_Core_Model_App_Options::APP_RUN_TYPE_STORE, $model->getRunType());
-
-        $runType = Mage_Core_Model_App_Options::APP_RUN_TYPE_WEBSITE;
-        $model = new Mage_Core_Model_App_Options(array(Mage_Core_Model_App_Options::OPTION_APP_RUN_TYPE => $runType));
-        $this->assertEquals($runType, $model->getRunType());
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     * @expectedExceptionMessage run type "invalid" is not recognized, supported values: "store", "group", "website"
-     */
-    public function testGetRunTypeException()
-    {
-        new Mage_Core_Model_App_Options(array(Mage_Core_Model_App_Options::OPTION_APP_RUN_TYPE => 'invalid'));
-    }
-
-    public function testGetRunOptions()
-    {
-        $model = new Mage_Core_Model_App_Options(array('ignored_option' => 'ignored value'));
-        $this->assertEmpty($model->getRunOptions());
-
-        $extraLocalConfigFile = 'test/local.xml';
-        $inputOptions = array(Mage_Core_Model_App_Options::OPTION_LOCAL_CONFIG_EXTRA_FILE => $extraLocalConfigFile);
-        $expectedRunOptions = array(Mage_Core_Model_Config::OPTION_LOCAL_CONFIG_EXTRA_FILE => $extraLocalConfigFile);
-        $model = new Mage_Core_Model_App_Options($inputOptions);
-        $this->assertEquals($expectedRunOptions, $model->getRunOptions());
-    }
-}
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/AppTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/AppTest.php
index 02eeca38643..6119e5324ad 100644
--- a/dev/tests/unit/testsuite/Mage/Core/Model/AppTest.php
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/AppTest.php
@@ -30,13 +30,8 @@
  */
 class Mage_Core_Model_AppTest extends PHPUnit_Framework_TestCase
 {
-    /*
-     * Test layout class instance
-     */
-    const LAYOUT_INSTANCE = 'TestLayoutInstance';
-
     /**
-     * @var Mage_Core_Model_App
+     * @var Mage_Core_Model_App|PHPUnit_Framework_MockObject_MockObject
      */
     protected $_model;
 
@@ -45,20 +40,64 @@ class Mage_Core_Model_AppTest extends PHPUnit_Framework_TestCase
      */
     protected $_objectManager;
 
-    public function setUp()
+    protected function setUp()
     {
         $frontController = $this->getMock('Mage_Core_Controller_Varien_Front', array(), array(), '', false);
-        $this->_objectManager = $this->getMock('Magento_ObjectManager_Zend', array('get'), array(), '', false);
-        $this->_model = new Mage_Core_Model_App($frontController, $this->_objectManager);
+
+        $this->_objectManager = new Magento_ObjectManager_Zend();
+        $dirs = new Mage_Core_Model_Dir(__DIR__, array(), array(Mage_Core_Model_Dir::CONFIG => __DIR__));
+        $this->_objectManager->addSharedInstance($dirs, 'Mage_Core_Model_Dir');
+
+        $this->_model = $this->getMock(
+            'Mage_Core_Model_App',
+            array('_initEnvironment', '_initFilesystem', '_initLogger', '_initCache'),
+            array($frontController, $this->_objectManager)
+        );
+        $this->_objectManager->addSharedInstance($this->_model, 'Mage_Core_Model_App');
+    }
+
+    protected function tearDown()
+    {
+        $this->_model = null;
+        $this->_objectManager = null;
+    }
+
+    public function testIsInstalledFalse()
+    {
+        $this->_model->baseInit(array(
+            Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA
+                => sprintf(Mage_Core_Model_Config::CONFIG_TEMPLATE_INSTALL_DATE, 'invalid')
+        ));
+        $this->assertFalse($this->_model->isInstalled());
+    }
+
+    public function testIsInstalledTrue()
+    {
+        $this->_model->baseInit(array(
+            Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA
+                => sprintf(Mage_Core_Model_Config::CONFIG_TEMPLATE_INSTALL_DATE, 'Fri, 28 Dec 2012 11:29:51 -0800')
+        ));
+        $this->assertTrue($this->_model->isInstalled());
+    }
+
+    /**
+     * @expectedException Magento_Exception
+     * @expectedExceptionMessage Application is not installed yet, please complete the installation first.
+     */
+    public function testRequireInstalledInstance()
+    {
+        $this->_model->baseInit(array(
+            Mage_Core_Model_Config::INIT_OPTION_EXTRA_DATA
+                => sprintf(Mage_Core_Model_Config::CONFIG_TEMPLATE_INSTALL_DATE, 'invalid')
+        ));
+        $this->_model->requireInstalledInstance();
     }
 
     public function testGetLayout()
     {
-        $this->_objectManager->expects($this->once())
-            ->method('get')
-            ->with('Mage_Core_Model_Layout')
-            ->will($this->returnValue(self::LAYOUT_INSTANCE));
+        $layout = $this->getMock('Mage_Core_Model_Layout', array(), array(), '', false);
+        $this->_objectManager->addSharedInstance($layout, 'Mage_Core_Model_Layout');
 
-        $this->assertEquals(self::LAYOUT_INSTANCE, $this->_model->getLayout());
+        $this->assertEquals($layout, $this->_model->getLayout());
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/CacheTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/CacheTest.php
index 4f0bc940d7c..60b4a3afb3c 100644
--- a/dev/tests/unit/testsuite/Mage/Core/Model/CacheTest.php
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/CacheTest.php
@@ -27,15 +27,25 @@
 
 class Mage_Core_Model_CacheTest extends PHPUnit_Framework_TestCase
 {
+    /**
+     * @var Mage_Core_Model_Dir
+     */
+    protected static $_dirs;
+
     /**
      * @var Mage_Core_Model_Cache
      */
     protected $_model;
 
     /**
-     * @var Mage_Core_Model_Config
+     * @var Mage_Core_Model_App|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_app;
+
+    /**
+     * @var Magento_ObjectManager_Zend|PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_config;
+    protected $_objectManager;
 
     /**
      * @var Mage_Core_Helper_Abstract
@@ -52,64 +62,109 @@ class Mage_Core_Model_CacheTest extends PHPUnit_Framework_TestCase
      */
     protected $_requestProcessor;
 
-    public function setUp()
+    public static function setUpBeforeClass()
+    {
+        self::$_dirs = new Mage_Core_Model_Dir(TESTS_TEMP_DIR);
+        mkdir(self::$_dirs->getDir(Mage_Core_Model_Dir::CACHE), 0777, true);
+    }
+
+    public static function tearDownAfterClass()
+    {
+        self::$_dirs = null;
+    }
+
+    protected function setUp()
     {
-        $objectManagerMock = $this->getMock('Magento_ObjectManager_Zend', array('create', 'get'), array(), '', false);
-        $objectManagerMock->expects($this->any())
+        $this->_prepareApp('global_ban_use_cache', false);
+        $this->_objectManager = $this->getMock(
+            'Magento_ObjectManager_Zend', array('create', 'get'), array(), '', false
+        );
+        $this->_objectManager->expects($this->any())
             ->method('create')
             ->will($this->returnCallback(array($this, 'getInstance')));
+        $this->_objectManager->expects($this->any())
+            ->method('get')
+            ->will($this->returnCallback(array($this, 'getObject')));
 
-        $this->_config = new Mage_Core_Model_Config($objectManagerMock, <<<XML
-            <config>
-                <global>
-                    <cache>
-                        <types>
-                            <single_tag>
-                                <label>Tag One</label>
-                                <description>This is Tag One</description>
-                                <tags>tag_one</tags>
-                            </single_tag>
-                            <multiple_tags>
-                                <label>Tags One and Two</label>
-                                <description>These are Tags One and Two</description>
-                                <tags>tag_one,tag_two</tags>
-                            </multiple_tags>
-                        </types>
-                    </cache>
-                </global>
-            </config>
-XML
-        );
         $this->_helper = $this->getMock('Mage_Core_Helper_Data', array('__'));
         $this->_helper
             ->expects($this->any())
             ->method('__')
             ->will($this->returnArgument(0))
         ;
-        $this->_config->setOptions(array(
-            'cache_dir' => __DIR__,
-            'etc_dir' => __DIR__,
-        ));
         $this->_cacheFrontend = $this->getMock(
             'Zend_Cache_Core', array('load', 'test', 'save', 'remove', 'clean', '_getHelper')
         );
         $this->_requestProcessor = $this->getMock('stdClass', array('extractContent'));
-        $this->_model = new Mage_Core_Model_Cache(array(
-            'config'   => $this->_config,
-            'helper'   => $this->_helper,
-            'frontend' => $this->_cacheFrontend,
-            'backend'  => 'BlackHole',
-            'request_processors' => array($this->_requestProcessor),
+        $this->_model = new Mage_Core_Model_Cache(
+            $this->_objectManager,
+            array(
+                'helper'   => $this->_helper,
+                'frontend' => $this->_cacheFrontend,
+                'backend'  => 'BlackHole',
+                'request_processors' => array($this->_requestProcessor),
         ));
     }
 
-    public function tearDown()
+    protected function tearDown()
     {
-        $this->_config = null;
+        $this->_objectManager = null;
         $this->_cacheFrontend = null;
         $this->_model = null;
     }
 
+    /**
+     * Create application mock
+     *
+     * @param string $initParam
+     * @param mixed $initValue
+     */
+    protected function _prepareApp($initParam, $initValue)
+    {
+        $this->_app = $this->getMock('Mage_Core_Model_App', array('getInitParam'), array(), '', false);
+        $this->_app->expects($this->any())
+            ->method('getInitParam')
+            ->with($initParam)
+            ->will($this->returnValue($initValue));
+    }
+
+    /**
+     * Callback for getter of the object manager
+     *
+     * @param string $className
+     * @return object|null|PHPUnit_Framework_MockObject_MockObject
+     */
+    public function getObject($className)
+    {
+        switch ($className) {
+            case 'Mage_Core_Model_Config':
+                return new Mage_Core_Model_Config($this->_objectManager, <<<XML
+                    <config>
+                        <global>
+                            <cache>
+                                <types>
+                                    <single_tag>
+                                        <label>Tag One</label>
+                                        <description>This is Tag One</description>
+                                        <tags>tag_one</tags>
+                                    </single_tag>
+                                    <multiple_tags>
+                                        <label>Tags One and Two</label>
+                                        <description>These are Tags One and Two</description>
+                                        <tags>tag_one,tag_two</tags>
+                                    </multiple_tags>
+                                </types>
+                            </cache>
+                        </global>
+                    </config>
+XML
+                );
+            case 'Mage_Core_Model_App': return $this->_app;
+            case 'Mage_Core_Model_Dir': return self::$_dirs;
+            default: return null;
+        }
+    }
+
     /**
      * Force to load desired cache type options
      *
@@ -132,8 +187,8 @@ XML
      */
     public function testConstructor(array $options, $expectedBackendClass)
     {
-        $options += array('config' => $this->_config, 'helper' => $this->_helper);
-        $model = new Mage_Core_Model_Cache($options);
+        $options += array('helper' => $this->_helper);
+        $model = new Mage_Core_Model_Cache($this->_objectManager, $options);
 
         $backend = $model->getFrontend()->getBackend();
         $this->assertInstanceOf($expectedBackendClass, $backend);
@@ -209,8 +264,7 @@ XML
 
     public function testSaveDisallowed()
     {
-        $model = new Mage_Core_Model_Cache(array(
-            'config'   => $this->_config,
+        $model = new Mage_Core_Model_Cache($this->_objectManager, array(
             'helper'   => $this->_helper,
             'frontend' => $this->_cacheFrontend,
             'backend'  => 'BlackHole',
@@ -312,6 +366,15 @@ XML
         return $this->_model;
     }
 
+    public function testCanUseBanCache()
+    {
+        $this->_prepareApp('global_ban_use_cache', true);
+        $this->_emulateCacheTypeOptions();
+        $this->assertEquals(array('config' => false), $this->_model->canUse(''));
+        $this->assertFalse($this->_model->canUse('config'));
+        return $this->_model;
+    }
+
     /**
      * @depends testCanUse
      * @param Mage_Core_Model_Cache $model
@@ -436,8 +499,7 @@ XML
     public function testProcessRequestFalse()
     {
         $response = new Zend_Controller_Response_Http();
-        $this->_model = new Mage_Core_Model_Cache(array(
-            'config'   => $this->_config,
+        $this->_model = new Mage_Core_Model_Cache($this->_objectManager, array(
             'helper'   => $this->_helper,
             'frontend' => $this->_cacheFrontend,
             'backend'  => 'BlackHole',
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/Config/OptionsTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/Config/OptionsTest.php
deleted file mode 100644
index 62b07ed2f83..00000000000
--- a/dev/tests/unit/testsuite/Mage/Core/Model/Config/OptionsTest.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.
- *
- * @category    Magento
- * @package     Mage_Core
- * @subpackage  unit_tests
- * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-class Mage_Core_Model_Config_OptionsTest extends PHPUnit_Framework_TestCase
-{
-    /**
-     * @var Mage_Core_Model_Config_Options
-     */
-    protected $_model;
-
-    /**
-     * @var array
-     */
-    protected $_sourceData;
-
-    /**
-     * @var array
-     */
-    protected $_varDir;
-
-    protected function setUp()
-    {
-        $ioModel = $this->getMock('Varien_Io_File', array('checkAndCreateFolder'));
-        $this->_sourceData = array(
-            'app_dir' => __DIR__ . DIRECTORY_SEPARATOR . 'app',
-            'io' => $ioModel,
-        );
-        $this->_varDir = __DIR__ . DIRECTORY_SEPARATOR . 'var';
-    }
-
-    public function testGetVarDir()
-    {
-        $this->_sourceData['io']->expects($this->once())
-            ->method('checkAndCreateFolder')
-            ->with($this->equalTo($this->_varDir))
-            ->will($this->returnValue(true));
-
-        $this->_model = new Mage_Core_Model_Config_Options($this->_sourceData);
-        $result = $this->_model->getVarDir();
-        $this->assertEquals($this->_varDir, $result);
-    }
-
-    /**
-     * @expectedException Mage_Core_Exception
-     */
-    public function testGetVarDirWithException()
-    {
-        $this->_sourceData['io']->expects($this->at(0))
-            ->method('checkAndCreateFolder')
-            ->with($this->equalTo($this->_varDir))
-            ->will($this->throwException(new Exception));
-        $this->_model = new Mage_Core_Model_Config_Options($this->_sourceData);
-    }
-
-    public function testCreateDirIfNotExists()
-    {
-        $checkDir = __DIR__ . DIRECTORY_SEPARATOR . 'test';
-        $this->_sourceData['io']->expects($this->at(0))
-            ->method('checkAndCreateFolder')
-            ->with($this->equalTo($this->_varDir))
-            ->will($this->returnValue(true));
-
-        $this->_sourceData['io']->expects($this->at(1))
-            ->method('checkAndCreateFolder')
-            ->with($this->equalTo($checkDir))
-            ->will($this->returnValue(true));
-
-        $this->_model = new Mage_Core_Model_Config_Options($this->_sourceData);
-
-        $result = $this->_model->createDirIfNotExists($checkDir);
-        $this->assertEquals(true, $result);
-    }
-
-    public function testCreateDirIfNotExistsNegativeResult()
-    {
-        $checkDir = __DIR__ . DIRECTORY_SEPARATOR . 'dirNotExists';
-        $this->_sourceData['io']->expects($this->at(0))
-            ->method('checkAndCreateFolder')
-            ->with($this->equalTo($this->_varDir))
-            ->will($this->returnValue(true));
-
-        $this->_sourceData['io']->expects($this->at(1))
-            ->method('checkAndCreateFolder')
-            ->will($this->throwException(new Exception));
-
-        $this->_model = new Mage_Core_Model_Config_Options($this->_sourceData);
-        $result = $this->_model->createDirIfNotExists($checkDir);
-        $this->assertEquals(false, $result);
-    }
-}
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/ConfigTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/ConfigTest.php
index 00b88f53a27..cd899c38aaf 100644
--- a/dev/tests/unit/testsuite/Mage/Core/Model/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/ConfigTest.php
@@ -34,23 +34,27 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
 
     /**
      * @param mixed $data
-     * @param array $map
      * @dataProvider constructorDataProvider
      */
-    public function testConstructor($data, $map)
+    public function testConstructor($data)
     {
         //TODO: We should not use mocks in integration tests
         /** @var Magento_ObjectManager_Zend|PHPUnit_Framework_MockObject_MockObject $objectManagerMock */
         $objectManagerMock = $this->getMock('Magento_ObjectManager_Zend', array('create', 'get'), array(), '', false);
         $objectManagerMock->expects($this->any())
             ->method('create')
-            ->will($this->returnValueMap(array(
-                $map,
-                array('Mage_Core_Model_Config_Base', array(), true,  new Mage_Core_Model_Config_Base())
-            )));
+            ->will($this->returnValueMap(
+                array(
+                    array(
+                        'Mage_Core_Model_Config_Base',
+                        array(),
+                        true,
+                        new Mage_Core_Model_Config_Base()
+                    )
+                )
+            ));
 
         $this->_model = new Mage_Core_Model_Config($objectManagerMock, $data);
-        $this->assertInstanceOf('Mage_Core_Model_Config_Options', $this->_model->getOptions());
     }
 
     /**
@@ -61,18 +65,14 @@ class Mage_Core_Model_ConfigTest extends PHPUnit_Framework_TestCase
         $simpleXml = new Varien_Simplexml_Element('<body></body>');
         return array(
             array(
-                'data' => null,
-                'map' => array('Mage_Core_Model_Config_Options', array('data' => array(null)), true,
-                    new Mage_Core_Model_Config_Options())
+                'data' => null
             ),
             array(
-                'data' => array(),
-                'map' => array('Mage_Core_Model_Config_Options', array('data' => array()), true,
-                    new Mage_Core_Model_Config_Options())
+                'data' => array()
             ),
-            array('data' => $simpleXml,
-                'map' => array('Mage_Core_Model_Config_Options', array('data' => array($simpleXml)), true,
-                    new Mage_Core_Model_Config_Options())),
+            array(
+                'data' => $simpleXml
+            )
         );
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/Design/Fallback/CachingProxyTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/Design/Fallback/CachingProxyTest.php
index ee88abafba3..2ca8873f2bd 100644
--- a/dev/tests/unit/testsuite/Mage/Core/Model/Design/Fallback/CachingProxyTest.php
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/Design/Fallback/CachingProxyTest.php
@@ -32,14 +32,7 @@ class Mage_Core_Model_Design_Fallback_CachingProxyTest extends PHPUnit_Framework
      *
      * @var string
      */
-    protected static $_tmpDir;
-
-    /**
-     * Base dir as passed to the model
-     *
-     * @var string
-     */
-    protected $_baseDir;
+    protected $_tmpDir;
 
     /**
      * Mock of the model to be tested. Operates the mocked fallback object.
@@ -55,170 +48,103 @@ class Mage_Core_Model_Design_Fallback_CachingProxyTest extends PHPUnit_Framework
      */
     protected $_fallback;
 
-    /**
-     * Mocked theme object
-     *
-     * @var Mage_Core_Model_Theme
-     */
-    protected $_theme;
-
-    public static function setUpBeforeClass()
-    {
-        self::$_tmpDir = TESTS_TEMP_DIR . DIRECTORY_SEPARATOR . 'fallback';
-        mkdir(self::$_tmpDir);
-    }
-
     public function setUp()
     {
-        // TODO This test should be either refactored to use mock filesystem or moved to integration
-        $this->_baseDir = DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR . 'dir';
-
-        $this->_theme = $this->getMock('Mage_Core_Model_Theme', array(), array(), '', false);
-
-        $params = array(
-            'area'       => 'frontend',
-            'themeModel' => $this->_theme,
-            'locale'     => 'en_US',
-            'appConfig'  => false,
-            'canSaveMap' => false,
-            'mapDir'     => self::$_tmpDir,
-            'baseDir'    => $this->_baseDir
-        );
-
+        $this->_tmpDir = TESTS_TEMP_DIR . DIRECTORY_SEPARATOR . 'fallback';
+        mkdir($this->_tmpDir);
         $this->_fallback = $this->getMock(
             'Mage_Core_Model_Design_Fallback',
-            array('getFile', 'getLocaleFile', 'getViewFile'),
-            array($this->_createFilesystem(), $params)
+            array('getFile', 'getLocaleFile', 'getViewFile', 'getArea', 'getPackage', 'getTheme', 'getLocale'),
+            array(),
+            '',
+            false
+        );
+        $this->_fallback->expects($this->any())->method('getArea')->will($this->returnValue('a'));
+        $this->_fallback->expects($this->any())->method('getPackage')->will($this->returnValue('p'));
+        $this->_fallback->expects($this->any())->method('getTheme')->will($this->returnValue('t'));
+        $this->_fallback->expects($this->any())->method('getLocale')->will($this->returnValue('l'));
+        $this->_model = new Mage_Core_Model_Design_Fallback_CachingProxy(
+            $this->_fallback, $this->_createFilesystem(), $this->_tmpDir, __DIR__, true
         );
-
-        $this->_model = $this->getMockBuilder('Mage_Core_Model_Design_Fallback_CachingProxy')
-            ->setMethods(array('_getFallback'))
-            ->setConstructorArgs(array($this->_createFilesystem(), $params))
-            ->getMock();
-        $this->_model->expects($this->any())
-            ->method('_getFallback')
-            ->will($this->returnValue($this->_fallback));
     }
 
-    /**
-     * Calls are repeated twice to verify, that fallback is used only once, and next time a proper value is returned
-     * via cached map.
-     */
-    public function testGetFile()
+    protected function tearDown()
     {
-        $module = 'Some_Module';
-        $expected = $this->_baseDir . DIRECTORY_SEPARATOR . 'path' . DIRECTORY_SEPARATOR . 'theme_file.ext';
-        $expected = str_replace('/', DIRECTORY_SEPARATOR, $expected);
-        $this->_fallback->expects($this->once())
-            ->method('getFile')
-            ->with('file.ext', $module)
-            ->will($this->returnValue($expected));
-
-        $actual = $this->_model->getFile('file.ext', $module);
-        $this->assertEquals($expected, $actual);
-        $actual = $this->_model->getFile('file.ext', $module);
-        $this->assertEquals($expected, $actual);
+        Varien_Io_File::rmdirRecursive($this->_tmpDir);
     }
 
     /**
-     * Calls are repeated twice to verify, that fallback is used only once, and next time a proper value is returned
-     * via cached map.
+     * @expectedException InvalidArgumentException
      */
-    public function testGetLocaleFile()
+    public function testConstructInvalidDir()
     {
-        $expected = $this->_baseDir . DIRECTORY_SEPARATOR . 'path' . DIRECTORY_SEPARATOR . 'locale_file.ext';
-        $this->_fallback->expects($this->once())
-            ->method('getLocaleFile')
-            ->with('file.ext')
-            ->will($this->returnValue($expected));
-
-        $actual = $this->_model->getLocaleFile('file.ext');
-        $this->assertEquals($expected, $actual);
-        $actual = $this->_model->getLocaleFile('file.ext');
-        $this->assertEquals($expected, $actual);
+        new Mage_Core_Model_Design_Fallback_CachingProxy($this->_fallback, $this->_createFilesystem(), $this->_tmpDir,
+            __DIR__ . '/invalid_dir');
     }
 
-    /**
-     * Calls are repeated twice to verify, that fallback is used only once, and next time a proper value is returned
-     * via cached map.
-     */
-    public function testGetViewFile()
+    public function testDestruct()
     {
-        $module = 'Some_Module';
-        $expected = $this->_baseDir . DIRECTORY_SEPARATOR . 'path' . DIRECTORY_SEPARATOR . 'view_file.ext';
         $this->_fallback->expects($this->once())
-            ->method('getViewFile')
-            ->with('file.ext', $module)
-            ->will($this->returnValue($expected));
-
-        $actual = $this->_model->getViewFile('file.ext', $module);
-        $this->assertEquals($expected, $actual);
-        $actual = $this->_model->getViewFile('file.ext', $module);
-        $this->assertEquals($expected, $actual);
+            ->method('getFile')
+            ->will($this->returnValue(__DIR__ . DIRECTORY_SEPARATOR . 'test.txt'));
+        $suffix = uniqid();
+        $model = new Mage_Core_Model_Design_Fallback_CachingProxy(
+            $this->_fallback,
+            $this->_createFilesystem(),
+            $this->_tmpDir . DIRECTORY_SEPARATOR . $suffix,
+            __DIR__,
+            true
+        );
+        $expectedFile = $this->_tmpDir . DIRECTORY_SEPARATOR . $suffix . DIRECTORY_SEPARATOR . 'a_t_l.ser';
+        $model->getFile('does not matter');
+        $this->assertFileNotExists($expectedFile);
+        unset($model);
+        $this->assertFileExists($expectedFile);
+        $contents = unserialize(file_get_contents($expectedFile));
+        $this->assertContains('test.txt', $contents);
     }
 
     /**
-     * Test that proxy caches published skin path, and further calls do not use fallback model
+     * @covers Mage_Core_Model_Design_Fallback_CachingProxy::getFile
+     * @covers Mage_Core_Model_Design_Fallback_CachingProxy::getLocaleFile
+     * @covers Mage_Core_Model_Design_Fallback_CachingProxy::getViewFile
      */
-    public function testNotifySkinFilePublished()
+    public function testProxyMethods()
     {
-        $module = 'Some_Module';
-        $file = $this->_baseDir . DIRECTORY_SEPARATOR . 'path' . DIRECTORY_SEPARATOR . 'file.ext';
-
+        $fileArg = 'file.txt';
+        $moduleArg = 'module';
+        $path = __DIR__ . DIRECTORY_SEPARATOR;
         $this->_fallback->expects($this->once())
-            ->method('getViewFile')
-            ->with($file, $module)
-            ->will($this->returnValue(null));
-
-        // Empty at first
-        $this->assertNull($this->_model->getViewFile($file, $module));
-
-        // Store something
-        $publicFilePath = $this->_baseDir . DIRECTORY_SEPARATOR . 'public' . DIRECTORY_SEPARATOR . 'file.ext';
-        $result = $this->_model->notifyViewFilePublished($publicFilePath, $file, $module);
-        $this->assertSame($this->_model, $result);
-
-        // Stored successfully
-        $storedFilePath = $this->_model->getViewFile($file, $module);
-        $this->assertEquals($publicFilePath, $storedFilePath);
+            ->method('getFile')->with($fileArg, $moduleArg)->will($this->returnValue("{$path}one"));
+        $this->_fallback->expects($this->once())
+            ->method('getLocaleFile')->with($fileArg)->will($this->returnValue("{$path}two"));
+        $this->_fallback->expects($this->once())
+            ->method('getViewFile')->with($fileArg, $moduleArg)->will($this->returnValue("{$path}three"));
+
+        // Call each method twice to ensure the proxied method is called once
+        $this->assertEquals("{$path}one", $this->_model->getFile($fileArg, $moduleArg));
+        $this->assertEquals("{$path}one", $this->_model->getFile($fileArg, $moduleArg));
+        $this->assertEquals("{$path}two", $this->_model->getLocaleFile($fileArg));
+        $this->assertEquals("{$path}two", $this->_model->getLocaleFile($fileArg));
+        $this->assertEquals("{$path}three", $this->_model->getViewFile($fileArg, $moduleArg));
+        $this->assertEquals("{$path}three", $this->_model->getViewFile($fileArg, $moduleArg));
     }
 
     /**
-     * Tests that proxy saves data between instantiations
+     * Test that proxy caches published skin path, and further calls do not use fallback model
      */
-    public function testSaving()
+    public function testNotifyViewFilePublished()
     {
-        $module = 'Some_Module';
-        $file = 'internal/path/to/view_file.ext';
-        $expectedPublicFile = 'public/path/to/view_file.ext';
-
-        $params = array(
-            'area'       => 'frontend',
-            'themeModel' => $this->_theme,
-            'locale'     => 'en_US',
-            'canSaveMap' => true,
-            'mapDir'     => self::$_tmpDir,
-            'baseDir'    => ''
+        $moduleArg = '...';
+        $fixture = __DIR__ . DIRECTORY_SEPARATOR . uniqid();
+        $anotherFixture = __DIR__ . DIRECTORY_SEPARATOR . uniqid();
+
+        $this->_fallback->expects($this->once())->method('getViewFile')->will($this->returnValue($fixture));
+        $this->assertEquals($fixture, $this->_model->getViewFile('file.txt', $moduleArg));
+        $this->assertSame(
+            $this->_model, $this->_model->notifyViewFilePublished($anotherFixture, 'file.txt', $moduleArg)
         );
-        $model = new Mage_Core_Model_Design_Fallback_CachingProxy($this->_createFilesystem(), $params);
-        $model->notifyViewFilePublished($expectedPublicFile, $file, $module);
-
-        $globPath = self::$_tmpDir . DIRECTORY_SEPARATOR . '*.*';
-        $this->assertEmpty(glob($globPath));
-        unset($model);
-        $this->assertNotEmpty(glob($globPath));
-
-        /** @var $model Mage_Core_Model_Design_Fallback_CachingProxy */
-        $model = $this->getMock(
-            'Mage_Core_Model_Design_Fallback_CachingProxy',
-            array('_getFallback'),
-            array($this->_createFilesystem(), $params)
-        );
-        $model->expects($this->never())
-            ->method('_getFallback');
-
-        $actualPublicFile = $model->getViewFile($file, $module);
-        $this->assertEquals($expectedPublicFile, $actualPublicFile);
+        $this->assertEquals($anotherFixture, $this->_model->getViewFile('file.txt', $moduleArg));
     }
 
     protected function _createFilesystem()
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/DirTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/DirTest.php
new file mode 100644
index 00000000000..8e90493146b
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/DirTest.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+class Mage_Core_Model_DirTest extends PHPUnit_Framework_TestCase
+{
+    public function testGetWritableDirCodes()
+    {
+        $codes = Mage_Core_Model_Dir::getWritableDirCodes();
+        $this->assertInternalType('array', $codes);
+        $this->assertNotEmpty($codes);
+        $dir = new Mage_Core_Model_Dir(__DIR__);
+        foreach ($codes as $code) {
+            $this->assertNotEmpty($dir->getDir($code));
+        }
+    }
+
+    /**
+     * @param string $code
+     * @param string $value
+     * @expectedException InvalidArgumentException
+     * @dataProvider invalidUriDataProvider
+     */
+    public function testInvalidUri($code, $value)
+    {
+        new Mage_Core_Model_Dir(__DIR__, array($code => $value));
+    }
+
+    /**
+     * @return array
+     */
+    public function invalidUriDataProvider()
+    {
+        return array(
+            array(Mage_Core_Model_Dir::MEDIA, '/'),
+            array(Mage_Core_Model_Dir::MEDIA, '//'),
+            array(Mage_Core_Model_Dir::MEDIA, '/value'),
+            array(Mage_Core_Model_Dir::MEDIA, 'value/'),
+            array(Mage_Core_Model_Dir::MEDIA, '/value/'),
+            array(Mage_Core_Model_Dir::MEDIA, 'one\\two'),
+            array(Mage_Core_Model_Dir::MEDIA, '../dir'),
+            array(Mage_Core_Model_Dir::MEDIA, './dir'),
+            array(Mage_Core_Model_Dir::MEDIA, 'one/../two'),
+        );
+    }
+
+    public function testGetUri()
+    {
+        $dir = new Mage_Core_Model_Dir(__DIR__, array(
+            Mage_Core_Model_Dir::PUB   => '',
+            Mage_Core_Model_Dir::MEDIA => 'test',
+            'custom' => 'test2'
+        ));
+
+        // arbitrary custom value
+        $this->assertEquals('test2', $dir->getUri('custom'));
+
+        // setting empty value correctly adjusts its children
+        $this->assertEquals('', $dir->getUri(Mage_Core_Model_Dir::PUB));
+        $this->assertEquals('lib', $dir->getUri(Mage_Core_Model_Dir::PUB_LIB));
+
+        // at the same time if another child has custom value, it must not be affected by its parent
+        $this->assertEquals('test', $dir->getUri(Mage_Core_Model_Dir::MEDIA));
+        $this->assertEquals('test/upload', $dir->getUri(Mage_Core_Model_Dir::UPLOAD));
+
+        // dirs should not be affected (there is no getter for all directories, so use whatever getter is available)
+        $default = new Mage_Core_Model_Dir(__DIR__);
+        foreach (Mage_Core_Model_Dir::getWritableDirCodes() as $code) {
+            $this->assertEquals($default->getDir($code), $dir->getDir($code));
+        }
+    }
+
+    public function testGetDir()
+    {
+        $newRoot = __DIR__ . DIRECTORY_SEPARATOR . 'root';
+        $newMedia = __DIR__ . DIRECTORY_SEPARATOR . 'media';
+        $dir = new Mage_Core_Model_Dir(__DIR__, array(), array(
+            Mage_Core_Model_Dir::ROOT => $newRoot,
+            Mage_Core_Model_Dir::MEDIA => $newMedia,
+            'custom' => 'test2'
+        ));
+
+        // arbitrary custom value
+        $this->assertEquals('test2', $dir->getDir('custom'));
+
+        // new root has affected all its non-customized children
+        $this->assertStringStartsWith($newRoot, $dir->getDir(Mage_Core_Model_Dir::APP));
+        $this->assertStringStartsWith($newRoot, $dir->getDir(Mage_Core_Model_Dir::MODULES));
+
+        // but it didn't affect the customized dirs
+        $this->assertEquals($newMedia, $dir->getDir(Mage_Core_Model_Dir::MEDIA));
+        $this->assertStringStartsWith($newMedia, $dir->getDir(Mage_Core_Model_Dir::UPLOAD));
+
+        // uris should not be affected
+        $default = new Mage_Core_Model_Dir(__DIR__);
+        foreach (array(
+            Mage_Core_Model_Dir::PUB,
+            Mage_Core_Model_Dir::PUB_LIB,
+            Mage_Core_Model_Dir::MEDIA,
+            Mage_Core_Model_Dir::UPLOAD) as $code
+        ) {
+            $this->assertEquals($default->getUri($code), $dir->getUri($code));
+        }
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/EncryptionTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/EncryptionTest.php
new file mode 100644
index 00000000000..cf39cb6648a
--- /dev/null
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/EncryptionTest.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) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+class Mage_Core_Model_EncryptionTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider setHelperGetHashDataProvider
+     */
+    public function testSetHelperGetHash($input)
+    {
+        $objectManager = $this->getMock('Magento_ObjectManager_Zend', array('get'), array(), '', false);
+        $objectManager->expects($this->once())
+            ->method('get')
+            ->with('Mage_Core_Helper_Data')
+            ->will($this->returnValue(new Mage_Core_Helper_Data()));
+
+        /**
+         * @var Mage_Core_Model_Encryption
+         */
+        $model = new Mage_Core_Model_Encryption($objectManager);
+        $model->setHelper($input);
+        $model->getHash('password', 1);
+    }
+
+    /**
+     * @return array
+     */
+    public function setHelperGetHashDataProvider()
+    {
+        return array(
+            'string' => array('Mage_Core_Helper_Data'),
+            'object' => array(new Mage_Core_Helper_Data()),
+        );
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testSetHelperException()
+    {
+        $objectManager = $this->getMock('Magento_ObjectManager_Zend', array(), array(), '', false);
+        /**
+         * @var Mage_Core_Model_Encryption
+         */
+        $model = new Mage_Core_Model_Encryption($objectManager);
+        /** Mock object is not instance of Mage_Code_Helper_Data and should not pass validation */
+        $input = $this->getMock('Mage_Code_Helper_Data', array(), array(), '', false);
+        $model->setHelper($input);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/LoggerTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/LoggerTest.php
index 44626919808..d0c6e4a987b 100644
--- a/dev/tests/unit/testsuite/Mage/Core/Model/LoggerTest.php
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/LoggerTest.php
@@ -33,20 +33,16 @@ class Mage_Core_Model_LoggerTest extends PHPUnit_Framework_TestCase
      */
     protected $_loggersProperty = null;
 
-    /**
-     * @var Mage_Core_Model_Config|PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_config = null;
-
     protected function setUp()
     {
-        $this->_config = $this->getMock('Mage_Core_Model_Config', array('getOptions', 'getNode'), array(), '', false);
-        $options = $this->getMock('StdClass', array('getLogDir'));
-        $options->expects($this->any())->method('getLogDir')->will($this->returnValue(TESTS_TEMP_DIR));
-        $this->_config->expects($this->any())->method('getOptions')->will($this->returnValue($options));
-        $this->_model = new Mage_Core_Model_Logger($this->_config);
+        $dirs = new Mage_Core_Model_Dir(TESTS_TEMP_DIR);
+        $this->_model = new Mage_Core_Model_Logger($dirs);
         $this->_loggersProperty = new ReflectionProperty($this->_model, '_loggers');
         $this->_loggersProperty->setAccessible(true);
+        $logDir = $dirs->getDir(Mage_Core_Model_Dir::LOG);
+        if (!is_dir($logDir)) {
+            mkdir($logDir, 0777, true);
+        }
     }
 
     /**
@@ -56,7 +52,6 @@ class Mage_Core_Model_LoggerTest extends PHPUnit_Framework_TestCase
      */
     public function testAddStreamLog($key, $fileOrWrapper)
     {
-        $this->_config->expects($this->any())->method('getNode')->will($this->returnValue(''));
         $this->assertFalse($this->_model->hasLog($key));
         $this->_model->addStreamLog($key, $fileOrWrapper);
         $this->assertTrue($this->_model->hasLog($key));
@@ -94,6 +89,11 @@ class Mage_Core_Model_LoggerTest extends PHPUnit_Framework_TestCase
 
     public function testInitForStore()
     {
+        $config = $this->getMock('Mage_Core_Model_Config', array('getNode'), array(), '', false);
+        $config->expects($this->atLeastOnce())
+            ->method('getNode')
+            ->with('global/log/core/writer_model')
+            ->will($this->returnValue('StdClass'));
         $store = $this->getMock('Mage_Core_Model_Store', array('getConfig'), array(), '', false);
         $store->expects($this->at(0))->method('getConfig')->with('dev/log/active')->will($this->returnValue(false));
         $store->expects($this->at(1))->method('getConfig')->with('dev/log/active')->will($this->returnValue(true));
@@ -101,10 +101,10 @@ class Mage_Core_Model_LoggerTest extends PHPUnit_Framework_TestCase
         $store->expects($this->at(3))->method('getConfig')->with('dev/log/exception_file')->will(
             $this->returnValue('')
         );
-        $this->_model->initForStore($store);
+        $this->_model->initForStore($store, $config);
         $this->assertFalse($this->_model->hasLog(Mage_Core_Model_Logger::LOGGER_SYSTEM));
         $this->assertFalse($this->_model->hasLog(Mage_Core_Model_Logger::LOGGER_EXCEPTION));
-        $this->_model->initForStore($store);
+        $this->_model->initForStore($store, $config);
         $this->assertTrue($this->_model->hasLog(Mage_Core_Model_Logger::LOGGER_SYSTEM));
         $this->assertTrue($this->_model->hasLog(Mage_Core_Model_Logger::LOGGER_EXCEPTION));
     }
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/ThemeTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/ThemeTest.php
index bcfe1d759e8..a7369feda35 100644
--- a/dev/tests/unit/testsuite/Mage/Core/Model/ThemeTest.php
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/ThemeTest.php
@@ -39,7 +39,6 @@ class Mage_Core_Model_ThemeTest extends PHPUnit_Framework_TestCase
      */
     protected function _getThemeModel($designDir, $targetPath)
     {
-        Mage::getConfig()->getOptions()->setData('design_dir', $designDir);
         $objectManager = Mage::getObjectManager();
 
         /** @var $themeCollection Mage_Core_Model_Resource_Theme_Collection */
@@ -57,31 +56,11 @@ class Mage_Core_Model_ThemeTest extends PHPUnit_Framework_TestCase
         );
         /** @var $themeMock Mage_Core_Model_Theme */
         $themeMock = $this->getMock('Mage_Core_Model_Theme', array('_init'), $arguments, '', true);
-        $filesystemMock = $this->getMockBuilder('Magento_Filesystem')->disableOriginalConstructor(true)->getMock();
-        $filesystemMock->expects($this->any())->method('searchKeys')
-            ->will($this->returnValueMap(array(
-                array(
-                    $designDir, 'frontend/default/iphone/theme.xml',
-                    array(
-                        str_replace('/', DIRECTORY_SEPARATOR, $designDir . '/frontend/default/iphone/theme.xml')
-                    )
-                ),
-                array(
-                    $designDir, 'frontend/default/iphone/theme_invalid.xml',
-                    array(
-                        str_replace(
-                            '/',
-                            DIRECTORY_SEPARATOR,
-                            $designDir . '/frontend/default/iphone/theme_invalid.xml'
-                        )
-                    )
-                ),
-            )
-        ));
+        $filesystem = new Magento_Filesystem(new Magento_Filesystem_Adapter_Local);
 
         /** @var $collectionMock Mage_Core_Model_Theme_Collection|PHPUnit_Framework_MockObject_MockObject */
         $collectionMock = $this->getMock('Mage_Core_Model_Theme_Collection', array('getNewEmptyItem'),
-            array($filesystemMock));
+            array($filesystem));
         $collectionMock->expects($this->any())
             ->method('getNewEmptyItem')
             ->will($this->returnValue($themeMock));
diff --git a/dev/tests/unit/testsuite/Mage/Core/Model/Validator/FactoryTest.php b/dev/tests/unit/testsuite/Mage/Core/Model/Validator/FactoryTest.php
index b13b90ae1f8..a91d18ec385 100644
--- a/dev/tests/unit/testsuite/Mage/Core/Model/Validator/FactoryTest.php
+++ b/dev/tests/unit/testsuite/Mage/Core/Model/Validator/FactoryTest.php
@@ -84,8 +84,9 @@ class Mage_Core_Model_Validator_FactoryTest extends PHPUnit_Framework_TestCase
             ->will($this->returnValue(array('/tmp/moduleOne/etc/validation.xml')));
 
         // Translate adapter mock
+        $designMock = $this->getMock('Mage_Core_Model_Design_Package', array(), array(), '', false);
         $this->_translateAdapter = $this->getMockBuilder('Mage_Core_Model_Translate')
-            ->disableOriginalConstructor()
+            ->setConstructorArgs(array($designMock))
             ->setMethods(array('_getTranslatedString'))
             ->getMock();
         $this->_translateAdapter->expects($this->any())
diff --git a/dev/tests/unit/testsuite/Mage/DesignEditor/Controller/Varien/Router/StandardTest.php b/dev/tests/unit/testsuite/Mage/DesignEditor/Controller/Varien/Router/StandardTest.php
index d3ea390aca7..1c73911e1f0 100644
--- a/dev/tests/unit/testsuite/Mage/DesignEditor/Controller/Varien/Router/StandardTest.php
+++ b/dev/tests/unit/testsuite/Mage/DesignEditor/Controller/Varien/Router/StandardTest.php
@@ -183,20 +183,26 @@ class Mage_DesignEditor_Controller_Varien_Router_StandardTest extends PHPUnit_Fr
     ) {
         // default mocks - not affected on method functionality
         $controllerFactory  = $this->getMock('Mage_Core_Controller_Varien_Action_Factory', array(), array(), '', false);
+        $objectManager      = $this->getMock('Magento_ObjectManager_Zend', array('get'), array(), '', false);
         $filesystem         = $this->getMockBuilder('Magento_Filesystem')->disableOriginalConstructor()->getMock();
         $app                = $this->getMock('Mage_Core_Model_App', array(), array(), '', false);
-        $testArea           = 'frontend';
-        $testBaseController = 'Mage_Core_Controller_Varien_Action';
 
-        $helper = $this->getMock('Mage_DesignEditor_Helper_Data', array('getFrontName'), array(), '', false);
-        $helper->expects($this->atLeastOnce())
-            ->method('getFrontName')
-            ->will($this->returnValue(self::VDE_FRONT_NAME));
-
-        $backendSession = $this->getMock('Mage_Backend_Model_Auth_Session', array('isLoggedIn'), array(), '', false);
-        $backendSession->expects($isVde ? $this->once() : $this->never())
-            ->method('isLoggedIn')
-            ->will($this->returnValue($isLoggedIn));
+        $helper         = $this->_getHelperMock();
+        $backendSession = $this->_getBackendSessionMock($isVde, $isLoggedIn);
+        $stateModel     = $this->_getStateModelMock($routers);
+        $configuration  = $this->_getConfigurationMock($isVde, $isLoggedIn, $isConfiguration);
+        $callback = function ($name) use ($helper, $backendSession, $stateModel, $configuration) {
+            switch ($name) {
+                case 'Mage_DesignEditor_Helper_Data': return $helper;
+                case 'Mage_Backend_Model_Auth_Session': return $backendSession;
+                case 'Mage_DesignEditor_Model_State': return $stateModel;
+                case 'Mage_Core_Model_Config': return $configuration;
+                default: return null;
+            }
+        };
+        $objectManager->expects($this->any())
+            ->method('get')
+            ->will($this->returnCallback($callback));
 
         $frontController = $this->getMock('Mage_Core_Controller_Varien_Front',
             array('applyRewrites', 'getRouters'), array(), '', false
@@ -210,13 +216,68 @@ class Mage_DesignEditor_Controller_Varien_Router_StandardTest extends PHPUnit_Fr
                 ->will($this->returnValue($routers));
         }
 
+        $router = new Mage_DesignEditor_Controller_Varien_Router_Standard(
+            $controllerFactory,
+            $objectManager,
+            $filesystem,
+            $app,
+            'frontend',
+            'Mage_Core_Controller_Varien_Action'
+        );
+        $router->setFront($frontController);
+        return $router;
+    }
+
+    /**
+     * @return PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getHelperMock()
+    {
+        $helper = $this->getMock('Mage_DesignEditor_Helper_Data', array('getFrontName'), array(), '', false);
+        $helper->expects($this->atLeastOnce())
+            ->method('getFrontName')
+            ->will($this->returnValue(self::VDE_FRONT_NAME));
+        return $helper;
+    }
+
+    /**
+     * @param bool $isVde
+     * @param bool $isLoggedIn
+     * @return PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getBackendSessionMock($isVde, $isLoggedIn)
+    {
+        $backendSession = $this->getMock('Mage_Backend_Model_Auth_Session', array('isLoggedIn'), array(), '', false);
+        $backendSession->expects($isVde ? $this->once() : $this->never())
+            ->method('isLoggedIn')
+            ->will($this->returnValue($isLoggedIn));
+        return $backendSession;
+    }
+
+    /**
+     * @param array $routers
+     * @return PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getStateModelMock(array $routers)
+    {
         $stateModel = $this->getMock('Mage_DesignEditor_Model_State', array('update'), array(), '', false);
         if (array_key_exists('matched', $routers)) {
             $stateModel->expects($this->once())
                 ->method('update')
                 ->with(self::AREA_CODE);
+            return $stateModel;
         }
+        return $stateModel;
+    }
 
+    /**
+     * @param bool $isVde
+     * @param bool $isLoggedIn
+     * @param bool $isConfiguration
+     * @return PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getConfigurationMock($isVde, $isLoggedIn, $isConfiguration)
+    {
         $configuration = $this->getMock('Mage_Core_Model_Config', array('getNode'), array(), '', false);
         if ($isVde && $isLoggedIn) {
             $configurationData = null;
@@ -240,19 +301,6 @@ class Mage_DesignEditor_Controller_Varien_Router_StandardTest extends PHPUnit_Fr
                     ->will($this->returnValue($elementMock));
             }
         }
-
-        $router = new Mage_DesignEditor_Controller_Varien_Router_Standard(
-            $controllerFactory,
-            $filesystem,
-            $app,
-            $testArea,
-            $testBaseController,
-            $backendSession,
-            $helper,
-            $stateModel,
-            $configuration
-        );
-        $router->setFront($frontController);
-        return $router;
+        return $configuration;
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/DesignEditor/Model/StateTest.php b/dev/tests/unit/testsuite/Mage/DesignEditor/Model/StateTest.php
index 4f11e30e20b..d1c71b1a352 100644
--- a/dev/tests/unit/testsuite/Mage/DesignEditor/Model/StateTest.php
+++ b/dev/tests/unit/testsuite/Mage/DesignEditor/Model/StateTest.php
@@ -59,12 +59,10 @@ class Mage_DesignEditor_Model_StateTest extends PHPUnit_Framework_TestCase
      */
     const AREA_CODE = 'front';
 
-    /**#@+
-     * Test theme data
+    /**
+     * Test theme id
      */
     const THEME_ID = 1;
-    const THEME_CONFIGURATION = 'test_config';
-    /**#@-*/
 
     /**
      * @var Mage_DesignEditor_Model_State
@@ -136,9 +134,7 @@ class Mage_DesignEditor_Model_StateTest extends PHPUnit_Framework_TestCase
         $this->_objectManager = $this->getMock('Magento_ObjectManager_Zend', array('addAlias'),
             array(), '', false
         );
-        $this->_designPackage = $this->getMock('Mage_Core_Model_Design_Package', array('getConfigPathByArea'),
-            array(), '', false
-        );
+        $this->_designPackage = $this->getMock('Mage_Core_Model_Design_Package', array(), array(), '', false);
         $this->_application = $this->getMock('Mage_Core_Model_App', array('getStore'),
             array(), '', false
         );
@@ -225,15 +221,10 @@ class Mage_DesignEditor_Model_StateTest extends PHPUnit_Framework_TestCase
             ->with(self::LAYOUT_UPDATE_RESOURCE_MODEL_CORE_CLASS_NAME,
             self::LAYOUT_UPDATE_RESOURCE_MODEL_VDE_CLASS_NAME);
 
-        $this->_designPackage->expects($this->once())
-            ->method('getConfigPathByArea')
-            ->with(Mage_Core_Model_App_Area::AREA_FRONTEND)
-            ->will($this->returnValue(self::THEME_CONFIGURATION));
-
         $store = $this->getMock('Mage_Core_Model_Store', array('setConfig'), array(), '', false);
         $store->expects($this->once())
             ->method('setConfig')
-            ->with(self::THEME_CONFIGURATION, self::THEME_ID);
+            ->with(Mage_Core_Model_Design_Package::XML_PATH_THEME_ID, self::THEME_ID);
 
         $this->_application->expects($this->once())
             ->method('getStore')
diff --git a/dev/tests/unit/testsuite/Mage/Index/Model/Lock/StorageTest.php b/dev/tests/unit/testsuite/Mage/Index/Model/Lock/StorageTest.php
index 203f27499d4..136cf2d14f0 100644
--- a/dev/tests/unit/testsuite/Mage/Index/Model/Lock/StorageTest.php
+++ b/dev/tests/unit/testsuite/Mage/Index/Model/Lock/StorageTest.php
@@ -24,38 +24,18 @@
  * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
-/**
- * Test for Mage_Index_Model_Lock_Storage
- */
 class Mage_Index_Model_Lock_StorageTest extends PHPUnit_Framework_TestCase
 {
-    /**
-    * Test var directory
-    */
-    const VAR_DIRECTORY = 'test';
-
-    /**
-     * Locks storage model
-     *
-     * @var Mage_Index_Model_Lock_Storage
-     */
-    protected $_storage;
-
     /**
      * Keep current process id for tests
      *
      * @var integer
      */
-    protected $_currentProcessId;
+    protected $_callbackProcessId;
 
-    protected function setUp()
+    public function testGetFile()
     {
-        $config = $this->getMock('Mage_Core_Model_Config', array('getVarDir'), array(), '', false);
-        $config->expects($this->exactly(2))
-            ->method('getVarDir')
-            ->will($this->returnValue(self::VAR_DIRECTORY));
-
+        $dirs = new Mage_Core_Model_Dir(__DIR__);
         $fileModel = $this->getMock('Mage_Index_Model_Process_File',
             array(
                 'setAllowCreateFolders',
@@ -70,7 +50,7 @@ class Mage_Index_Model_Lock_StorageTest extends PHPUnit_Framework_TestCase
             ->with(true);
         $fileModel->expects($this->exactly(2))
             ->method('open')
-            ->with(array('path' => self::VAR_DIRECTORY));
+            ->with(array('path' => __DIR__  . DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'locks'));
         $fileModel->expects($this->exactly(2))
             ->method('streamOpen')
             ->will($this->returnCallback(array($this, 'checkFilenameCallback')));
@@ -85,31 +65,28 @@ class Mage_Index_Model_Lock_StorageTest extends PHPUnit_Framework_TestCase
             ->method('createFromArray')
             ->will($this->returnValue($fileModel));
 
-        $this->_storage = new Mage_Index_Model_Lock_Storage($config, $fileFactory);
-    }
+        $storage = new Mage_Index_Model_Lock_Storage($dirs, $fileFactory);
 
-    public function testGetFile()
-    {
         /**
          * 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->_currentProcessId = $processId;
-            $this->assertInstanceOf('Mage_Index_Model_Process_File', $this->_storage->getFile($processId));
+            $this->_callbackProcessId = $processId;
+            $this->assertInstanceOf('Mage_Index_Model_Process_File', $storage->getFile($processId));
         }
-        $this->assertAttributeCount(2, '_fileHandlers', $this->_storage);
+        $this->assertAttributeCount(2, '_fileHandlers', $storage);
     }
 
     /**
-     * Check file name
+     * Check file name (callback subroutine for testGetFile())
      *
      * @param string $filename
      */
     public function checkFilenameCallback($filename)
     {
-        $expected = 'index_process_' . $this->_currentProcessId . '.lock';
+        $expected = 'index_process_' . $this->_callbackProcessId . '.lock';
         $this->assertEquals($expected, $filename);
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Page/Block/Html/HeaderTest.php b/dev/tests/unit/testsuite/Mage/Page/Block/Html/HeaderTest.php
index b335bb2d68c..251b67fb5b1 100644
--- a/dev/tests/unit/testsuite/Mage/Page/Block/Html/HeaderTest.php
+++ b/dev/tests/unit/testsuite/Mage/Page/Block/Html/HeaderTest.php
@@ -42,11 +42,6 @@ class Mage_Page_Block_Html_HeaderTest extends PHPUnit_Framework_TestCase
             ->method('getBaseUrl')
             ->will($this->returnValue('http://localhost/pub/media/'));
 
-        $configOptions = $this->getMock('Mage_Core_Model_Config_Options', array('getDir'));
-        $configOptions->expects($this->once())
-            ->method('getDir')
-            ->will($this->returnValue(__DIR__ . DIRECTORY_SEPARATOR . '_files'));
-
         $helper = $this->getMockBuilder('Mage_Core_Helper_File_Storage_Database')
             ->setMethods(array('checkDbUsage'))
             ->disableOriginalConstructor()
@@ -60,16 +55,22 @@ class Mage_Page_Block_Html_HeaderTest extends PHPUnit_Framework_TestCase
             ->method('get')
             ->will($this->returnValue($helper));
 
+        $dirsMock = $this->getMock('Mage_Core_Model_Dir', array('getDir'), array(), '', false);
+        $dirsMock->expects($this->any())
+            ->method('getDir')
+            ->with(Mage_Core_Model_Dir::MEDIA)
+            ->will($this->returnValue(__DIR__ . DIRECTORY_SEPARATOR . '_files'));
+
         $objectManager = new Magento_Test_Helper_ObjectManager($this);
 
         $arguments = array(
             'storeConfig' => $storeConfig,
             'urlBuilder' => $urlBuilder,
-            'configOptions' => $configOptions,
-            'helperFactory' => $helperFactory
+            'helperFactory' => $helperFactory,
+            'dirs' => $dirsMock
         );
-        $this->_block = $objectManager->getBlock('Mage_Page_Block_Html_Header', $arguments);
+        $block = $objectManager->getBlock('Mage_Page_Block_Html_Header', $arguments);
 
-        $this->assertEquals('http://localhost/pub/media/logo/default/image.gif', $this->_block->getLogoSrc());
+        $this->assertEquals('http://localhost/pub/media/logo/default/image.gif', $block->getLogoSrc());
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/ResourceTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/ResourceTest.php
index 9a8958abc66..0552c3c827a 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/ResourceTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/Tab/ResourceTest.php
@@ -44,7 +44,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_ResourceTest extends PHPUnit_Fra
 
         $helper = new Magento_Test_Helper_ObjectManager($this);
         $this->_block = $helper->getBlock('Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_Resource', array(
-            // TODO Remove injecting of 'urlBuilder' and 'authorizationConfig' after MAGETWO-5038 complete
+            // TODO: Remove injecting of 'urlBuilder' and 'authorizationConfig' after MAGETWO-5038 complete
             'urlBuilder' => $this->getMockBuilder('Mage_Backend_Model_Url')
                 ->disableOriginalConstructor()
                 ->getMock(),
@@ -56,7 +56,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_ResourceTest extends PHPUnit_Fra
     }
 
     /**
-     * Test isEverythingAllowed method
+     * Test isEverythingAllowed method.
      *
      * @dataProvider isEverythingAllowedDataProvider
      * @param array $selectedResources
@@ -85,11 +85,11 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_Tab_ResourceTest extends PHPUnit_Fra
     public function isEverythingAllowedDataProvider()
     {
         return array(
-            'Not Everything Allowed' => array(
+            'Not everything is allowed' => array(
                 array('customer', 'customer/get'),
                 false
             ),
-            'Everything Allowed' => array(
+            'Everything is allowed' => array(
                 array('customer', 'customer/get', Mage_Webapi_Model_Authorization::API_ACL_RESOURCES_ROOT_ID),
                 true
             )
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/TabsTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/TabsTest.php
index b1bc38ea13c..1fc1582ac25 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/TabsTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/Edit/TabsTest.php
@@ -69,7 +69,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_TabsTest extends PHPUnit_Framework_T
     }
 
     /**
-     * Test _construct method
+     * Test _construct method.
      */
     public function testConstruct()
     {
@@ -79,7 +79,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_TabsTest extends PHPUnit_Framework_T
     }
 
     /**
-     * Test for _beforeToHtml method
+     * Test for _beforeToHtml method.
      *
      * @dataProvider beforeToHtmlDataProvider
      * @param object $apiRole
@@ -105,7 +105,7 @@ class Mage_Webapi_Block_Adminhtml_Role_Edit_TabsTest extends PHPUnit_Framework_T
             array('active_tab', null, 'main_section')
         )));
 
-        // todo: do checks using toHtml() when DI is implemented for abstract blocks
+        // TODO: do checks using toHtml() when DI is implemented for abstract blocks
         $toHtmlMethod = new ReflectionMethod($this->_block, '_beforeToHtml');
         $toHtmlMethod->setAccessible(true);
         $toHtmlMethod ->invoke($this->_block);
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/EditTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/EditTest.php
index ea20048df2b..761bd99ac6c 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/EditTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/Role/EditTest.php
@@ -75,7 +75,7 @@ class Mage_Webapi_Block_Adminhtml_Role_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Test _construct method
+     * Test _construct method.
      */
     public function testConstruct()
     {
@@ -87,7 +87,7 @@ class Mage_Webapi_Block_Adminhtml_Role_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Test getSaveAndContinueUrl method
+     * Test getSaveAndContinueUrl method.
      */
     public function testGetSaveAndContinueUrl()
     {
@@ -102,7 +102,7 @@ class Mage_Webapi_Block_Adminhtml_Role_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Test getHeaderText method
+     * Test getHeaderText method.
      */
     public function testGetHeaderText()
     {
@@ -130,7 +130,7 @@ class Mage_Webapi_Block_Adminhtml_Role_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Asserts that block has button with id and label at level
+     * Asserts that block has button with ID and label at level.
      *
      * @param int $level
      * @param string $buttonId
@@ -141,10 +141,10 @@ class Mage_Webapi_Block_Adminhtml_Role_EditTest extends PHPUnit_Framework_TestCa
         $buttonsProperty = new ReflectionProperty($this->_block, '_buttons');
         $buttonsProperty->setAccessible(true);
         $buttons = $buttonsProperty->getValue($this->_block);
-        $this->assertInternalType('array', $buttons, 'Cannot get bloc buttons');
+        $this->assertInternalType('array', $buttons, 'Cannot get block buttons.');
         $this->assertArrayHasKey($level, $buttons, "Block doesn't have buttons at level $level");
         $this->assertArrayHasKey($buttonId, $buttons[$level], "Block doesn't have '$buttonId' button at level $level");
-        $this->assertArrayHasKey('label', $buttons[$level][$buttonId], "Block button doesn't have label");
-        $this->assertEquals($label, $buttons[$level][$buttonId]['label'], "Block button label has unexpected value");
+        $this->assertArrayHasKey('label', $buttons[$level][$buttonId], "Block button doesn't have label.");
+        $this->assertEquals($label, $buttons[$level][$buttonId]['label'], "Block button label has unexpected value.");
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/RoleTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/RoleTest.php
index 9cd6f2a7e1e..54a45d8be4b 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/RoleTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/RoleTest.php
@@ -48,7 +48,7 @@ class Mage_Webapi_Block_Adminhtml_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test _construct method
+     * Test _construct method.
      */
     public function testConstruct()
     {
@@ -59,7 +59,7 @@ class Mage_Webapi_Block_Adminhtml_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test getCreateUrl method
+     * Test getCreateUrl method.
      */
     public function testGetCreateUrl()
     {
@@ -74,7 +74,7 @@ class Mage_Webapi_Block_Adminhtml_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Asserts that block has button with id and label at level
+     * Asserts that block has button with ID and label at level.
      *
      * @param int $level
      * @param string $buttonId
@@ -85,10 +85,10 @@ class Mage_Webapi_Block_Adminhtml_RoleTest extends PHPUnit_Framework_TestCase
         $buttonsProperty = new ReflectionProperty($this->_block, '_buttons');
         $buttonsProperty->setAccessible(true);
         $buttons = $buttonsProperty->getValue($this->_block);
-        $this->assertInternalType('array', $buttons, 'Cannot get bloc buttons');
+        $this->assertInternalType('array', $buttons, 'Cannot get block buttons.');
         $this->assertArrayHasKey($level, $buttons, "Block doesn't have buttons at level $level");
         $this->assertArrayHasKey($buttonId, $buttons[$level], "Block doesn't have '$buttonId' button at level $level");
-        $this->assertArrayHasKey('label', $buttons[$level][$buttonId], "Block button doesn't have label");
-        $this->assertEquals($label, $buttons[$level][$buttonId]['label'], "Block button label has unexpected value");
+        $this->assertArrayHasKey('label', $buttons[$level][$buttonId], "Block button doesn't have label.");
+        $this->assertEquals($label, $buttons[$level][$buttonId]['label'], "Block button label has unexpected value.");
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/User/EditTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/User/EditTest.php
index d7cc0295cad..d3bdf778433 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/User/EditTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/User/EditTest.php
@@ -59,7 +59,7 @@ class Mage_Webapi_Block_Adminhtml_User_EditTest extends PHPUnit_Framework_TestCa
 
         $helper = new Magento_Test_Helper_ObjectManager($this);
         $this->_block = $helper->getBlock('Mage_Webapi_Block_Adminhtml_User_Edit', array(
-            // TODO Remove injecting of 'urlBuilder' after MAGETWO-5038 complete
+            // TODO: Remove injecting of 'urlBuilder' after MAGETWO-5038 complete
             'urlBuilder' => $this->getMockBuilder('Mage_Backend_Model_Url')
                 ->disableOriginalConstructor()
                 ->getMock(),
@@ -69,7 +69,7 @@ class Mage_Webapi_Block_Adminhtml_User_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Test _construct method
+     * Test _construct method.
      */
     public function testConstruct()
     {
@@ -82,7 +82,7 @@ class Mage_Webapi_Block_Adminhtml_User_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Test getHeaderText method
+     * Test getHeaderText method.
      */
     public function testGetHeaderText()
     {
@@ -110,7 +110,7 @@ class Mage_Webapi_Block_Adminhtml_User_EditTest extends PHPUnit_Framework_TestCa
     }
 
     /**
-     * Asserts that block has button with id and attribute at level
+     * Asserts that block has button with ID and attribute at level.
      *
      * @param int $level
      * @param string $buttonId
@@ -122,12 +122,12 @@ class Mage_Webapi_Block_Adminhtml_User_EditTest extends PHPUnit_Framework_TestCa
         $buttonsProperty = new ReflectionProperty($this->_block, '_buttons');
         $buttonsProperty->setAccessible(true);
         $buttons = $buttonsProperty->getValue($this->_block);
-        $this->assertInternalType('array', $buttons, 'Cannot get bloc buttons');
+        $this->assertInternalType('array', $buttons, 'Cannot get block buttons.');
         $this->assertArrayHasKey($level, $buttons, "Block doesn't have buttons at level $level");
         $this->assertArrayHasKey($buttonId, $buttons[$level], "Block doesn't have '$buttonId' button at level $level");
         $this->assertArrayHasKey($attributeName, $buttons[$level][$buttonId],
             "Block button doesn't have attribute $attributeName");
         $this->assertEquals($attributeValue, $buttons[$level][$buttonId][$attributeName],
-            "Block button $attributeName' has unexpected value");
+            "Block button $attributeName' has unexpected value.");
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/UserTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/UserTest.php
index 096db188f9e..3ee5bb31c4d 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/UserTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Block/Adminhtml/UserTest.php
@@ -34,7 +34,7 @@ class Mage_Webapi_Block_Adminhtml_UserTest extends PHPUnit_Framework_TestCase
     {
         $helper = new Magento_Test_Helper_ObjectManager($this);
         $this->_block = $helper->getBlock('Mage_Webapi_Block_Adminhtml_User', array(
-            // TODO Remove injecting of 'urlBuilder' after MAGETWO-5038 complete
+            // TODO: Remove injecting of 'urlBuilder' after MAGETWO-5038 complete
             'urlBuilder' => $this->getMockBuilder('Mage_Backend_Model_Url')
                 ->disableOriginalConstructor()
                 ->getMock(),
@@ -42,7 +42,7 @@ class Mage_Webapi_Block_Adminhtml_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test _construct method
+     * Test _construct method.
      */
     public function testConstruct()
     {
@@ -53,7 +53,7 @@ class Mage_Webapi_Block_Adminhtml_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Asserts that block has button with id and label at level
+     * Asserts that block has button with ID and label at level.
      *
      * @param int $level
      * @param string $buttonId
@@ -64,10 +64,10 @@ class Mage_Webapi_Block_Adminhtml_UserTest extends PHPUnit_Framework_TestCase
         $buttonsProperty = new ReflectionProperty($this->_block, '_buttons');
         $buttonsProperty->setAccessible(true);
         $buttons = $buttonsProperty->getValue($this->_block);
-        $this->assertInternalType('array', $buttons, 'Cannot get bloc buttons');
+        $this->assertInternalType('array', $buttons, 'Cannot get block buttons.');
         $this->assertArrayHasKey($level, $buttons, "Block doesn't have buttons at level $level");
         $this->assertArrayHasKey($buttonId, $buttons[$level], "Block doesn't have '$buttonId' button at level $level");
-        $this->assertArrayHasKey('label', $buttons[$level][$buttonId], "Block button doesn't have label");
-        $this->assertEquals($label, $buttons[$level][$buttonId]['label'], "Block button label has unexpected value");
+        $this->assertArrayHasKey('label', $buttons[$level][$buttonId], "Block button doesn't have label.");
+        $this->assertEquals($label, $buttons[$level][$buttonId]['label'], "Block button label has unexpected value.");
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/ErrorProcessorTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/ErrorProcessorTest.php
index 381d6974ede..bc713579956 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/ErrorProcessorTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/ErrorProcessorTest.php
@@ -64,12 +64,12 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
     }
 
     /**
-     * Test render method in Json format.
+     * Test render method in JSON format.
      */
     public function testRenderJson()
     {
         $_SERVER['HTTP_ACCEPT'] = 'json';
-        /** Assert jsonEncode method will be executed once. */
+        /** Assert that jsonEncode method will be executed once. */
         $this->_helperMock->expects($this->once())->method('jsonEncode')->will(
             $this->returnCallback(array($this, 'callbackJsonEncode'), $this->returnArgument(0))
         );
@@ -80,13 +80,13 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
         $actualResult = ob_get_contents();
         ob_end_clean();
         $expectedResult = '{"messages":{"error":[{"code":500,"message":"Message"}]}}';
-        $this->assertEquals($expectedResult, $actualResult, 'Wrong rendering in Json.');
+        $this->assertEquals($expectedResult, $actualResult, 'Invalid rendering in JSON.');
     }
 
     /**
      * Callback function for RenderJson and RenderJsonInDeveloperMode tests.
      *
-     * Method encode data to Json and return it.
+     * Method encodes data to JSON and returns it.
      *
      * @param $data
      * @return string
@@ -97,14 +97,14 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
     }
 
     /**
-     * Test render method in Json format with turned on developer mode.
+     * Test render method in JSON format with turned on developer mode.
      */
     public function testRenderJsonInDeveloperMode()
     {
         $_SERVER['HTTP_ACCEPT'] = 'json';
         /** Mock app to return enabled developer mode flag. */
         $this->_appMock->expects($this->any())->method('isDeveloperMode')->will($this->returnValue(true));
-        /** Assert jsonEncode method will be executed once. */
+        /** Assert that jsonEncode method will be executed once. */
         $this->_helperMock->expects($this->once())->method('jsonEncode')->will(
             $this->returnCallback(array($this, 'callbackJsonEncode'), $this->returnArgument(0))
         );
@@ -113,7 +113,7 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
         $actualResult = ob_get_contents();
         ob_end_clean();
         $expectedResult = '{"messages":{"error":[{"code":401,"message":"Message","trace":"Message trace."}]}}';
-        $this->assertEquals($expectedResult, $actualResult, 'Wrong rendering in Json.');
+        $this->assertEquals($expectedResult, $actualResult, 'Invalid rendering in JSON.');
     }
 
     /**
@@ -130,7 +130,7 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
         ob_end_clean();
         $expectedResult = '<?xml version="1.0"?><error><messages><error><data_item><code>500</code>'
             . '<message>Message</message></data_item></error></messages></error>';
-        $this->assertEquals($expectedResult, $actualResult, 'Wrong rendering in XML.');
+        $this->assertEquals($expectedResult, $actualResult, 'Invalid rendering in XML.');
     }
 
     /**
@@ -149,17 +149,17 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
         ob_end_clean();
         $expectedResult = '<?xml version="1.0"?><error><messages><error><data_item><code>401</code><message>'
             . 'Message</message><trace><![CDATA[Trace message.]]></trace></data_item></error></messages></error>';
-        $this->assertEquals($expectedResult, $actualResult, 'Wrong rendering in XML with turned on developer mode.');
+        $this->assertEquals($expectedResult, $actualResult, 'Invalid rendering in XML with turned on developer mode.');
     }
 
     /**
-     * Test default render format is Json.
+     * Test default render format is JSON.
      */
     public function testRenderDefaultFormat()
     {
         /** Set undefined rendering format. */
         $_SERVER['HTTP_ACCEPT'] = 'undefined';
-        /** Assert jsonEncode method will be executed at least once. */
+        /** Assert that jsonEncode method will be executed at least once. */
         $this->_helperMock->expects($this->atLeastOnce())->method('jsonEncode');
         $this->_errorProcessor->render('Message');
     }
@@ -173,13 +173,13 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
         $_SERVER['HTTP_ACCEPT'] = 'json';
         /** Init Mage_Webapi_Exception. */
         $apiException = new Mage_Webapi_Exception('Exception message', 500);
-        /** Assert jsonEncode will be executed once. */
+        /** Assert that jsonEncode will be executed once. */
         $this->_helperMock->expects($this->once())->method('jsonEncode');
         $this->_errorProcessor->renderException($apiException);
     }
 
     /**
-     * Test renderException method with turned on Developer mode.
+     * Test renderException method with turned on developer mode.
      */
     public function testRenderExecutionInDeveloperMode()
     {
@@ -189,7 +189,7 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
         $exception = new Exception('Message');
         /** Mock app to return enabled developer mode flag. */
         $this->_appMock->expects($this->any())->method('isDeveloperMode')->will($this->returnValue(true));
-        /** Assert jsonEncode will be executed once. */
+        /** Assert that jsonEncode will be executed once. */
         $this->_helperMock->expects($this->once())->method('jsonEncode');
         $this->_errorProcessor->renderException($exception);
     }
@@ -201,7 +201,7 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
     {
         /** Init mage_webapi_Exception. */
         $apiException = new Mage_Webapi_Exception('Message', 400);
-        /** Asser Webapi exception was not masked. */
+        /** Assert that Webapi exception was not masked. */
         $this->assertEquals(
             $this->_errorProcessor->maskException($apiException),
             $apiException,
@@ -218,7 +218,7 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
         $this->_appMock->expects($this->once())->method('isDeveloperMode')->will($this->returnValue(true));
         /** Init Logical exception. */
         $logicalException = new LogicException();
-        /** Asser Webapi exception was not masked. */
+        /** Assert that Webapi exception was not masked. */
         $this->assertEquals(
             $this->_errorProcessor->maskException($logicalException),
             $logicalException,
@@ -231,22 +231,22 @@ class Mage_Webapi_Controller_Dispatcher_ErrorProcessorTest extends PHPUnit_Frame
      */
     public function testMaskNonWebapiException()
     {
-        /** Assert exception was logged. */
+        /** Assert that exception was logged. */
         $this->_loggerMock->expects($this->once())->method('logException');
         $maskedException = $this->_errorProcessor->maskException(new LogicException());
-        /** Assert masked exception type is Mage_Webapi_Exception. */
+        /** Assert that masked exception type is Mage_Webapi_Exception. */
         $this->assertInstanceOf('Mage_Webapi_Exception', $maskedException, 'Masked exception type is not Webapi.');
-        /** Asser masked exception code is 500. */
+        /** Assert that masked exception code is 500. */
         $this->assertEquals(
             Mage_Webapi_Exception::HTTP_INTERNAL_ERROR,
             $maskedException->getCode(),
-            'Masked exception code is wrong.'
+            'Masked exception code is invalid.'
         );
         /** Assert masked exception message. */
         $this->assertEquals(
             'Internal Error. Details are available in Magento log file. Report ID: "%s"',
             $maskedException->getMessage(),
-            'Masked exception message is wrong.'
+            'Masked exception message is invalid.'
         );
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/RestTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/RestTest.php
index 4c0136fc6f7..edcf32a7bb9 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/RestTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/RestTest.php
@@ -107,7 +107,7 @@ class Mage_Webapi_Controller_Dispatcher_RestTest extends PHPUnit_Framework_TestC
         $this->_authenticationMock->expects($this->once())->method('authenticate')->will(
             $this->throwException($logicalException)
         );
-        /** Assert setException method will be executed with thrown logical Exception. */
+        /** Assert that setException method will be executed with thrown logical Exception. */
         $this->_responseMock->expects($this->once())->method('setException')->with($this->equalTo($logicalException));
 
         $this->_restDispatcher->dispatch();
@@ -124,7 +124,7 @@ class Mage_Webapi_Controller_Dispatcher_RestTest extends PHPUnit_Framework_TestC
             ->getMock();
         $routeMock->expects($this->any())->method('getResourceName');
         $this->_routerMock->expects($this->once())->method('match')->will($this->returnValue($routeMock));
-        /** Mock Api Config getMethodNameByOperation method to return isDeleted method of Varien_Onject. */
+        /** Mock Api Config getMethodNameByOperation method to return isDeleted method of Varien_Object. */
         $this->_apiConfigMock->expects($this->once())->method('getMethodNameByOperation')->will(
             $this->returnValue('isDeleted')
         );
@@ -132,9 +132,9 @@ class Mage_Webapi_Controller_Dispatcher_RestTest extends PHPUnit_Framework_TestC
         $this->_apiConfigMock->expects($this->once())->method('identifyVersionSuffix')->will($this->returnValue(''));
         $this->_apiConfigMock->expects($this->once())->method('checkDeprecationPolicy');
         $this->_authorizationMock->expects($this->once())->method('checkResourceAcl');
-        /** Create fake controller mock, e. g. Varien_Object object. */
+        /** Create fake controller mock, e.g., Varien_Object object. */
         $controllerMock = $this->getMockBuilder('Varien_Object')->disableOriginalConstructor()->getMock();
-        /** Assert isDeleted method will be executed once. */
+        /** Assert that isDeleted method will be executed once. */
         $controllerMock->expects($this->once())->method('isDeleted');
         /** Mock factory mock to return fake action controller. */
         $this->_controllerFactory->expects($this->once())->method('createActionController')->will(
@@ -144,7 +144,7 @@ class Mage_Webapi_Controller_Dispatcher_RestTest extends PHPUnit_Framework_TestC
         $this->_restPresentation->expects($this->once())->method('fetchRequestData')->will(
             $this->returnValue(array())
         );
-        /** Assert response sendResponse method will be executed once. */
+        /** Assert that response sendResponse method will be executed once. */
         $this->_responseMock->expects($this->once())->method('sendResponse');
 
         $this->_restDispatcher->dispatch();
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/Soap/AuthenticationTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/Soap/AuthenticationTest.php
index 554232b2865..c54c21f2cdd 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/Soap/AuthenticationTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/Soap/AuthenticationTest.php
@@ -133,7 +133,7 @@ class Mage_Webapi_Controller_Dispatcher_Soap_AuthenticationTest extends PHPUnit_
     }
 
     /**
-     * Exception data provider for authenticate() method
+     * Exception data provider for authenticate() method.
      *
      * @return array
      */
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/Soap/HandlerTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/Soap/HandlerTest.php
index 7c78ae3ab7e..f53360ff3f3 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/Soap/HandlerTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/Soap/HandlerTest.php
@@ -146,7 +146,7 @@ class Mage_Webapi_Controller_Dispatcher_Soap_HandlerTest extends PHPUnit_Framewo
             ->method('maskException')
             ->with($exception)
             ->will($this->returnValue($exception));
-        /** Model situation: authenticate() method throw Exception(). */
+        /** Model situation: authenticate() method throws Exception(). */
         $this->_authenticationMock->expects($this->once())
             ->method('authenticate')
             ->will($this->throwException($exception));
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/SoapTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/SoapTest.php
index e4b61f9c70d..5f32756fc34 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/SoapTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Dispatcher/SoapTest.php
@@ -106,7 +106,7 @@ class Mage_Webapi_Controller_Dispatcher_SoapTest extends PHPUnit_Framework_TestC
     }
 
     /**
-     * Clean up dispatcher and it's dependencies.
+     * Clean up dispatcher and its dependencies.
      */
     protected function tearDown()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/FrontTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/FrontTest.php
index 3e76f082a63..3437990cf5a 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/FrontTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/FrontTest.php
@@ -25,6 +25,8 @@
  */
 class Mage_Webapi_Controller_FrontTest extends PHPUnit_Framework_TestCase
 {
+    const WEBAPI_AREA_FRONT_NAME = 'webapi';
+
     /** @var Mage_Webapi_Controller_Front */
     protected $_frontControllerMock;
 
@@ -37,6 +39,9 @@ class Mage_Webapi_Controller_FrontTest extends PHPUnit_Framework_TestCase
     /** @var Mage_Webapi_Controller_Dispatcher_ErrorProcessor. */
     protected $_errorProcessorMock;
 
+    /** @var Mage_Core_Model_Config */
+    protected $_configMock;
+
     protected function setUp()
     {
         /** Prepare mocks for SUT constructor. */
@@ -48,9 +53,16 @@ class Mage_Webapi_Controller_FrontTest extends PHPUnit_Framework_TestCase
         $helperFactory = $this->getMock('Mage_Core_Model_Factory_Helper');
         $helperFactory->expects($this->any())->method('get')->will($this->returnValue($helper));
 
+        $this->_configMock = $this->getMockBuilder('Mage_Core_Model_Config')->disableOriginalConstructor()->getMock();
+        $this->_configMock->expects($this->any())->method('getAreaFrontName')->will(
+            $this->returnValue(self::WEBAPI_AREA_FRONT_NAME)
+        );
+
         $this->_dispatcherFactory = $this->getMockBuilder('Mage_Webapi_Controller_Dispatcher_Factory')
             ->disableOriginalConstructor()->getMock();
         $application = $this->getMockBuilder('Mage_Core_Model_App')->disableOriginalConstructor()->getMock();
+        $application->expects($this->any())->method('getConfig')->will($this->returnValue($this->_configMock));
+
         $this->_routeFactoryMock = $this->getMockBuilder('Magento_Controller_Router_Route_Factory')
             ->disableOriginalConstructor()->getMock();
         $this->_errorProcessorMock = $this->getMockBuilder('Mage_Webapi_Controller_Dispatcher_ErrorProcessor')
@@ -105,7 +117,7 @@ class Mage_Webapi_Controller_FrontTest extends PHPUnit_Framework_TestCase
         $restDispatcherMock = $this->getMockBuilder('Mage_Webapi_Controller_Dispatcher_Rest')
             ->disableOriginalConstructor()
             ->getMock();
-        /** Assert handle method in mocked object will be executed only once. */
+        /** Assert that handle method in mocked object will be executed only once. */
         $restDispatcherMock->expects($this->once())->method('dispatch');
         $this->_dispatcherFactory->expects($this->any())->method('get')
             ->will($this->returnValue($restDispatcherMock));
@@ -126,7 +138,7 @@ class Mage_Webapi_Controller_FrontTest extends PHPUnit_Framework_TestCase
         /** Mock dispatcher to throw Logical exception. */
         $restDispatcherMock->expects($this->any())->method('dispatch')->will($this->throwException($logicalException));
         $this->_dispatcherFactory->expects($this->any())->method('get')->will($this->returnValue($restDispatcherMock));
-        /** Assert error processor renderException method will be executed with Logical Exception. */
+        /** Assert that error processor renderException method will be executed with Logical Exception. */
         $this->_errorProcessorMock->expects($this->once())->method('renderException')->with(
             $this->equalTo($logicalException)
         );
@@ -170,7 +182,7 @@ class Mage_Webapi_Controller_FrontTest extends PHPUnit_Framework_TestCase
      */
     protected function _createMockForApiRouteAndFactory($apiType)
     {
-        $apiRouteMock = $this->getMockBuilder('Mage_Webapi_Controller_Router_Route_Webapi')
+        $apiRouteMock = $this->getMockBuilder('Mage_Webapi_Controller_Router_Route')
             ->disableOriginalConstructor()->getMock();
         $apiRouteMock->expects($this->any())->method('match')->will($this->returnValue($apiType));
         $this->_routeFactoryMock->expects($this->any())->method('createRoute')->will(
@@ -181,7 +193,7 @@ class Mage_Webapi_Controller_FrontTest extends PHPUnit_Framework_TestCase
     public function testDeterminateApiTypeApiIsSet()
     {
         $this->_createMockForApiRouteAndFactory(array('api_type' => Mage_Webapi_Controller_Front::API_TYPE_SOAP));
-        /** Assert createRoute method will be executed only once */
+        /** Assert that createRoute method will be executed only once */
         $this->_routeFactoryMock->expects($this->once())->method('createRoute');
         /** The first method call will set apiType property using createRoute method. */
         $this->_frontControllerMock->determineApiType();
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/FactoryTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/FactoryTest.php
index 89b3af60266..66a758c94a7 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/FactoryTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/FactoryTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test Webapi Json Interpreter Request Rest Controller
+ * Test Webapi Json Interpreter Request Rest Controller.
  *
  * Magento
  *
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/JsonTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/JsonTest.php
index 64371705a4a..8f444ef4b0e 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/JsonTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/JsonTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test Webapi Json Interpreter Request Rest Controller
+ * Test Webapi Json Interpreter Request Rest Controller.
  *
  * Magento
  *
@@ -68,7 +68,7 @@ class Mage_Webapi_Controller_Request_Rest_Interpreter_JsonTest extends PHPUnit_F
 
     public function testInterpretInvalidArgumentException()
     {
-        $this->setExpectedException('InvalidArgumentException', 'Invalid data type "boolean". String is expected.');
+        $this->setExpectedException('InvalidArgumentException', '"boolean" data type is invalid. String is expected.');
         $this->_jsonInterpreter->interpret(false);
     }
 
@@ -91,7 +91,7 @@ class Mage_Webapi_Controller_Request_Rest_Interpreter_JsonTest extends PHPUnit_F
         $this->assertEquals(
             $expectedDecodedJson,
             $this->_jsonInterpreter->interpret($inputEncodedJson),
-            'Invalid interpretation from json to array.'
+            'Interpretation from JSON to array is invalid.'
         );
     }
 
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/XmlTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/XmlTest.php
index 4588d164aeb..2d34455a7e3 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/XmlTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/Rest/Interpreter/XmlTest.php
@@ -77,7 +77,7 @@ class Mage_Webapi_Controller_Request_Rest_Interpreter_XmlTest extends PHPUnit_Fr
 
     public function testInterpretInvalidArgumentException()
     {
-        $this->setExpectedException('InvalidArgumentException', 'Invalid data type "boolean". String is expected.');
+        $this->setExpectedException('InvalidArgumentException', '"boolean" data type is invalid. String is expected.');
         $this->_xmlInterpreter->interpret(false);
     }
 
@@ -93,7 +93,7 @@ class Mage_Webapi_Controller_Request_Rest_Interpreter_XmlTest extends PHPUnit_Fr
         $this->assertEquals(
             $expectedArray,
             $this->_xmlInterpreter->interpret($validInputXml),
-            'Request xml body was parsed incorrectly into array of params'
+            'Request XML body was parsed incorrectly into array of params.'
         );
     }
 
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/RestTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/RestTest.php
index 8a25cf1e806..11391373c5f 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/RestTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/RestTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test Webapi Request model
+ * Test Webapi Request model.
  *
  * Magento
  *
@@ -26,7 +26,7 @@
 class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * Request mock
+     * Request mock.
      *
      * @var PHPUnit_Framework_MockObject_MockObject
      */
@@ -64,7 +64,7 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for getAcceptTypes() method
+     * Test for getAcceptTypes() method.
      *
      * @dataProvider providerAcceptType
      * @param string $acceptHeader Value of Accept HTTP header
@@ -127,7 +127,7 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for getContentType() method
+     * Test for getContentType() method.
      *
      * @dataProvider providerContentType
      * @param string $contentTypeHeader 'Content-Type' header value
@@ -149,20 +149,20 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
                 $this->assertEquals(
                     $exceptionMessage,
                     $e->getMessage(),
-                    'Exception message does not match expected one'
+                    'Exception message does not match the expected one.'
                 );
                 return;
             } else {
-                $this->fail('Exception thrown on valid header: ' . $e->getMessage());
+                $this->fail('Exception is thrown on valid header: ' . $e->getMessage());
             }
         }
         if ($exceptionMessage) {
-            $this->fail('Expected exception was not raised');
+            $this->fail('Expected exception was not raised.');
         }
     }
 
     /**
-     * Test for getOperation() method
+     * Test for getOperation() method.
      *
      * @dataProvider providerRequestMethod
      * @param string $requestMethod Request method
@@ -200,20 +200,20 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
                 $this->assertEquals(
                     $exceptionMessage,
                     $e->getMessage(),
-                    'Exception message does not match expected one'
+                    'Exception message does not match the expected one.'
                 );
                 return;
             } else {
-                $this->fail('Exception thrown on valid header: ' . $e->getMessage());
+                $this->fail('Exception is thrown on valid header: ' . $e->getMessage());
             }
         }
         if ($exceptionMessage) {
-            $this->fail('Expected exception was not raised');
+            $this->fail('Expected exception was not raised.');
         }
     }
 
     /**
-     * Test for getResourceType() method
+     * Test for getResourceType() method.
      *
      */
     public function testGetResourceType()
@@ -225,7 +225,7 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Data provider for testGetAcceptTypes()
+     * Data provider for testGetAcceptTypes().
      *
      * @return array
      */
@@ -261,7 +261,7 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Data provider for testGetContentType()
+     * Data provider for testGetContentType().
      *
      * @return array
      */
@@ -269,20 +269,20 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
     {
         return array(
             // Each element is: array(Content-Type header value, content-type part[, expected exception message])
-            array('', null, 'Content-Type header is empty'),
-            array('_?', null, 'Invalid Content-Type header'),
+            array('', null, 'Content-Type header is empty.'),
+            array('_?', null, 'Content-Type header is invalid.'),
             array('application/x-www-form-urlencoded; charset=UTF-8', 'application/x-www-form-urlencoded'),
             array('application/x-www-form-urlencoded; charset=utf-8', 'application/x-www-form-urlencoded'),
             array('text/html; charset=uTf-8', 'text/html'),
-            array('text/html; charset=', null, 'Invalid Content-Type header'),
-            array('text/html;', null, 'Invalid Content-Type header'),
+            array('text/html; charset=', null, 'Content-Type header is invalid.'),
+            array('text/html;', null, 'Content-Type header is invalid.'),
             array('application/dialog.dot-info7+xml', 'application/dialog.dot-info7+xml'),
-            array('application/x-www-form-urlencoded; charset=cp1251', null, 'UTF-8 is the only supported charset')
+            array('application/x-www-form-urlencoded; charset=cp1251', null, 'UTF-8 is the only supported charset.')
         );
     }
 
     /**
-     * Data provider for testGetOperation()
+     * Data provider for testGetOperation().
      *
      * @return array
      */
@@ -290,7 +290,7 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
     {
         return array(
             // Each element is: array(Request method, CRUD operation name[, expected exception message])
-            array('INVALID_METHOD', null, 'Invalid request method'),
+            array('INVALID_METHOD', null, 'Request method is invalid.'),
             array('GET', Mage_Webapi_Controller_Request_Rest::HTTP_METHOD_GET),
             array('POST', Mage_Webapi_Controller_Request_Rest::HTTP_METHOD_CREATE),
             array('PUT', Mage_Webapi_Controller_Request_Rest::HTTP_METHOD_UPDATE),
@@ -394,7 +394,7 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Success getOperationName() method data provider
+     * Success getOperationName() method data provider.
      *
      * @return array
      */
@@ -444,7 +444,7 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(
             'resourceNameCreate',
             $this->_request->getOperationName(),
-            'Invalid resource name for create method.'
+            'Resource name for create method is invalid.'
         );
     }
 
@@ -462,7 +462,7 @@ class Mage_Webapi_Controller_Request_RestTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(
             'resourceNameMultiCreate',
             $this->_request->getOperationName(),
-            'Invalid resource name for multi create method.'
+            'Resource name for multi create method is invalid.'
         );
     }
 
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/SoapTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/SoapTest.php
index d4f8e4a45a7..89ff95abc6e 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/SoapTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Request/SoapTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Soap API Request Test.
+ * SOAP API Request Test.
  *
  * Magento
  *
@@ -60,7 +60,7 @@ class Mage_Webapi_Controller_Request_SoapTest extends PHPUnit_Framework_TestCase
             'param_1' => 'foo',
             'param_2' => 'bar',
             $wsdlParam => true,
-            Mage_Webapi_Controller_Router_Route_Webapi::PARAM_API_TYPE => true,
+            Mage_Webapi_Controller_Request::PARAM_API_TYPE => true,
             $resourcesParam => true
         );
         $this->_soapRequest->setParams($requestParams);
@@ -106,7 +106,7 @@ class Mage_Webapi_Controller_Request_SoapTest extends PHPUnit_Framework_TestCase
         $requestParams = array(
             Mage_Webapi_Model_Soap_Server::REQUEST_PARAM_WSDL => true,
             Mage_Webapi_Model_Soap_Server::REQUEST_PARAM_RESOURCES => $resources,
-            Mage_Webapi_Controller_Router_Route_Webapi::PARAM_API_TYPE => 'soap'
+            Mage_Webapi_Controller_Request::PARAM_API_TYPE => 'soap'
         );
         $this->_soapRequest->setParams($requestParams);
         /** Execute SUT. */
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/RequestTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/RequestTest.php
index 0a65d90d599..85524bcda48 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/RequestTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/RequestTest.php
@@ -26,7 +26,7 @@
 class Mage_Webapi_Controller_RequestTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * Request object
+     * Request object.
      *
      * @var Mage_Webapi_Controller_Request
      */
@@ -40,7 +40,7 @@ class Mage_Webapi_Controller_RequestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for getFilter() method
+     * Test for getFilter() method.
      */
     public function testGetFilter()
     {
@@ -55,7 +55,7 @@ class Mage_Webapi_Controller_RequestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for getOrderDirection() method
+     * Test for getOrderDirection() method.
      */
     public function testGetOrderDirection()
     {
@@ -70,7 +70,7 @@ class Mage_Webapi_Controller_RequestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for getOrderField() method
+     * Test for getOrderField() method.
      */
     public function testGetOrderField()
     {
@@ -85,7 +85,7 @@ class Mage_Webapi_Controller_RequestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for getPageNumber() method
+     * Test for getPageNumber() method.
      */
     public function testGetPageNumber()
     {
@@ -100,7 +100,7 @@ class Mage_Webapi_Controller_RequestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for getPageSize() method
+     * Test for getPageSize() method.
      */
     public function testGetPageSize()
     {
@@ -113,7 +113,7 @@ class Mage_Webapi_Controller_RequestTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test for getRequestedAttributes() method
+     * Test for getRequestedAttributes() method.
      */
     public function testGetRequestedAttributes()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/FactoryTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/FactoryTest.php
index 496b9ff9836..70189fd5a2b 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/FactoryTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/FactoryTest.php
@@ -55,26 +55,26 @@ class Mage_Webapi_Controller_Response_FactoryTest extends PHPUnit_Framework_Test
     }
 
     /**
-     * Test get method.
+     * Test GET method.
      */
     public function testGet()
     {
-        /** Mock front controller mock to return Soap api type. */
+        /** Mock front controller mock to return SOAP API type. */
         $this->_apiFrontController->expects($this->once())->method('determineApiType')->will(
             $this->returnValue(Mage_Webapi_Controller_Front::API_TYPE_SOAP)
         );
-        /** Assert object manager get method will be executed once with Mage_Webapi_Controller_Response parameter. */
+        /** Assert that object manager get() will be executed once with Mage_Webapi_Controller_Response parameter. */
         $this->_objectManager->expects($this->once())->method('get')->with('Mage_Webapi_Controller_Response');
         $this->_factory->get();
     }
 
     /**
-     * Test get method with wrong API type.
+     * Test GET method with wrong API type.
      */
     public function testGetWithWrongApiType()
     {
         $wrongApiType = 'Wrong SOAP';
-        /**Mock front controller determine api method to return wrong api type */
+        /**Mock front controller determine API method to return wrong API type */
         $this->_apiFrontController->expects($this->once())->method('determineApiType')->will(
             $this->returnValue($wrongApiType)
         );
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/FactoryTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/FactoryTest.php
index 2e4313d5121..4a2afa1f19b 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/FactoryTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/FactoryTest.php
@@ -71,7 +71,7 @@ class Mage_Webapi_Controller_Response_Rest_Renderer_FactoryTest extends PHPUnit_
     }
 
     /**
-     * Test get method.
+     * Test GET method.
      */
     public function testGet()
     {
@@ -96,7 +96,7 @@ class Mage_Webapi_Controller_Response_Rest_Renderer_FactoryTest extends PHPUnit_
 
     protected function _createConfigElementForRenders()
     {
-        /** Xml with the list of renders types and models. */
+        /** XML with the list of renders types and models. */
         $rendersXml = <<<XML
         <renders>
             <default>
@@ -114,7 +114,7 @@ XML;
     }
 
     /**
-     * Test get method with wrong Accept Http Header.
+     * Test GET method with wrong Accept HTTP Header.
      */
     public function testGetWithWrongAcceptHttpHeader()
     {
@@ -129,7 +129,7 @@ XML;
     }
 
     /**
-     * Test get method with wrong Renderer class.
+     * Test GET method with wrong Renderer class.
      */
     public function testGetWithWrongRendererClass()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/JsonTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/JsonTest.php
index 5102307865a..ce67726aea4 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/JsonTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/JsonTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test Json Renderer for REST.
+ * Test JSON Renderer for REST.
  *
  * Magento
  *
@@ -50,18 +50,18 @@ class Mage_Webapi_Controller_Response_Rest_Renderer_JsonTest extends PHPUnit_Fra
     }
 
     /**
-     * Test render method
+     * Test render method.
      */
     public function testRender()
     {
         $arrayToRender = array('key' => 'value');
-        /** Assert jsonEncode method in mocked helper will run once */
+        /** Assert that jsonEncode method in mocked helper will run once */
         $this->_helperMock->expects($this->once())->method('jsonEncode');
         $this->_restJsonRenderer->render($arrayToRender);
     }
 
     /**
-     * Test GetMimeType method
+     * Test GetMimeType method.
      */
     public function testGetMimeType()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/XmlTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/XmlTest.php
index f49d0718c31..be76536c9a0 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/XmlTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/Rest/Renderer/XmlTest.php
@@ -71,7 +71,7 @@ class Mage_Webapi_Controller_Response_Rest_Renderer_XmlTest extends PHPUnit_Fram
     public function providerXmlRender()
     {
         return array(
-            //Each array consist of data to render, expected XML and assert message
+            //Each array consists of data to render, expected XML and assert message
             array(
                 array('value1', 'value2'),
                 '<?xml version="1.0"?><response><item>value1</item><item>value2</item></response>',
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/RestTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/RestTest.php
index 303f29f07ad..e276db7b714 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/RestTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Response/RestTest.php
@@ -79,7 +79,7 @@ class Mage_Webapi_Controller_Response_RestTest extends PHPUnit_Framework_TestCas
         /** Init Mage_Webapi_Exception */
         $apiException = new Mage_Webapi_Exception('Exception message.', 401);
         $this->_responseRest->setException($apiException);
-        /** Assert Mage_Webapi_Exception was set and presented in the list. */
+        /** Assert that Mage_Webapi_Exception was set and presented in the list. */
         $this->assertTrue(
             $this->_responseRest->hasExceptionOfType('Mage_Webapi_Exception'),
             'Mage_Webapi_Exception was not set.'
@@ -97,7 +97,7 @@ class Mage_Webapi_Controller_Response_RestTest extends PHPUnit_Framework_TestCas
         $this->_rendererMock->expects($this->any())->method('getMimeType')->will(
             $this->throwException($logicException)
         );
-        /** Assert renderException method will be executed once with specified parameters. */
+        /** Assert that renderException method will be executed once with specified parameters. */
         $this->_errorProcessorMock->expects($this->once())->method('renderException')->with(
             $logicException,
             Mage_Webapi_Exception::HTTP_INTERNAL_ERROR
@@ -108,7 +108,7 @@ class Mage_Webapi_Controller_Response_RestTest extends PHPUnit_Framework_TestCas
     }
 
     /**
-     * Test sendResponse method with Http Not Acceptable error exception during messages rendering.
+     * Test sendResponse method with HTTP Not Acceptable error exception during messages rendering.
      */
     public function testSendResponseRenderMessagesHttpNotAcceptable()
     {
@@ -118,7 +118,7 @@ class Mage_Webapi_Controller_Response_RestTest extends PHPUnit_Framework_TestCas
         $this->_rendererMock->expects($this->any())->method('getMimeType')->will(
             $this->throwException($logicException)
         );
-        /** Assert renderException method will be executed once with specified parameters. */
+        /** Assert that renderException method will be executed once with specified parameters. */
         $this->_errorProcessorMock->expects($this->once())->method('renderException')->with(
             $logicException,
             Mage_Webapi_Exception::HTTP_NOT_ACCEPTABLE
@@ -199,12 +199,12 @@ class Mage_Webapi_Controller_Response_RestTest extends PHPUnit_Framework_TestCas
             'Mage_Webapi_Exception' => array(
                 new Mage_Webapi_Exception('Message', 400),
                 '{"messages":{"error":[{"code":400,"message":"Message"}]}}',
-                'Wrong response sending with Mage_Webapi_Exception'
+                'Response sending with Mage_Webapi_Exception is invalid'
             ),
             'Logical Exception' => array(
                 new LogicException('Message', 100),
                 '{"messages":{"error":[{"code":500,"message":"Message"}]}}',
-                'Wrong response sending with Logical Exception'
+                'Response sending with Logical Exception is invalid'
             ),
         );
     }
@@ -220,12 +220,12 @@ class Mage_Webapi_Controller_Response_RestTest extends PHPUnit_Framework_TestCas
             'Mage_Webapi_Exception' => array(
                 new Mage_Webapi_Exception('Message', 400),
                 '{"messages":{"error":[{"code":400,"message":"Message","trace":"',
-                'Wrong response sending with Mage_Webapi_Exception in developer mode'
+                'Response sending with Mage_Webapi_Exception in developer mode is invalid'
             ),
             'Logical Exception' => array(
                 new LogicException('Message'),
                 '{"messages":{"error":[{"code":500,"message":"Message","trace":"',
-                'Wrong response sending with Logical Exception in developer mode'
+                'Response sending with Logical Exception in developer mode is invalid'
             ),
         );
     }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/ResponseTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/ResponseTest.php
index 186f852018e..40efbdbc707 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/ResponseTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/ResponseTest.php
@@ -59,16 +59,16 @@ class Mage_Webapi_Controller_ResponseTest extends PHPUnit_Framework_TestCase
             ),
         );
         $actualHeader = $this->_response->setMimeType('application/xml')->getHeaders();
-        /** Assert headers are equal */
+        /** Assert that headers are equal */
         $this->assertEquals($expectedHeader, $actualHeader, 'Mime type is not set.');
     }
 
     /**
-     * Test addMessage, hasMessage, getMessage and clearMessages methods.
+     * Test addMessage, hasMessage, getMessage, and clearMessages methods.
      */
     public function testMessagesCrud()
     {
-        /** Test new object does not contain any messages. */
+        /** Test that new object does not contain any messages. */
         $this->assertFalse($this->_response->hasMessages(), 'New object contains messages.');
 
         /** Test message adding functionality. */
@@ -78,7 +78,7 @@ class Mage_Webapi_Controller_ResponseTest extends PHPUnit_Framework_TestCase
             array('key' => 'value'),
             Mage_Webapi_Controller_Response::MESSAGE_TYPE_SUCCESS
         );
-        $this->assertTrue($this->_response->hasMessages(), 'New message is not added right.');
+        $this->assertTrue($this->_response->hasMessages(), 'New message is not added correctly.');
 
         /** Test message getting functionality. */
         $expectedMessage = array(
@@ -86,7 +86,7 @@ class Mage_Webapi_Controller_ResponseTest extends PHPUnit_Framework_TestCase
                 array('key' => 'value', 'message' => 'Message text', 'code' => 200)
             )
         );
-        $this->assertEquals($expectedMessage, $this->_response->getMessages(), 'Message is got wrong.');
+        $this->assertEquals($expectedMessage, $this->_response->getMessages(), 'Message is got incorrectly.');
 
         /** Test message clearing functionality. */
         $this->_response->clearMessages();
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/Route/RestTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/Route/RestTest.php
index 58c8b331d81..44f4d5d9921 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/Route/RestTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/Route/RestTest.php
@@ -46,12 +46,12 @@ class Mage_Webapi_Controller_Router_Route_RestTest extends PHPUnit_Framework_Tes
      */
     public function testResourceName()
     {
-        /** Assert new object has no Resource name set. */
-        $this->assertNull($this->_restRoute->getResourceName(), 'New object has an set Resource name.');
+        /** Assert that new object has no Resource name set. */
+        $this->assertNull($this->_restRoute->getResourceName(), 'New object has a set Resource name.');
         /** Set Resource name. */
         $resourceName = 'Resource name';
         $this->_restRoute->setResourceName($resourceName);
-        /** Assert Resource name was set. */
+        /** Assert that Resource name was set. */
         $this->assertEquals($resourceName, $this->_restRoute->getResourceName(), 'Resource name is wrong.');
     }
 
@@ -60,12 +60,12 @@ class Mage_Webapi_Controller_Router_Route_RestTest extends PHPUnit_Framework_Tes
      */
     public function testResourceType()
     {
-        /** Assert new object has no Resource type set. */
-        $this->assertNull($this->_restRoute->getResourceType(), 'New object has an set Resource type.');
+        /** Assert that new object has no Resource type set. */
+        $this->assertNull($this->_restRoute->getResourceType(), 'New object has a set Resource type.');
         /** Set Resource type. */
         $resourceType = 'Resource type';
         $this->_restRoute->setResourceType($resourceType);
-        /** Assert Resource type was set. */
+        /** Assert that Resource type was set. */
         $this->assertEquals($resourceType, $this->_restRoute->getResourceType(), 'Resource type is wrong.');
     }
 }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/Route/ApiTypeTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/RouteTest.php
similarity index 78%
rename from dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/Route/ApiTypeTest.php
rename to dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/RouteTest.php
index a84868ecaaf..b86e93ea7fd 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/Route/ApiTypeTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Controller/Router/RouteTest.php
@@ -25,15 +25,17 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-class Mage_Webapi_Controller_Router_Route_WebapiTest extends PHPUnit_Framework_TestCase
+class Mage_Webapi_Controller_Router_RouteTest extends PHPUnit_Framework_TestCase
 {
     public function testMatch()
     {
-        $route = new Mage_Webapi_Controller_Router_Route_Webapi(
-            Mage_Webapi_Controller_Router_Route_Webapi::getApiRoute());
+        $areaName = 'webapi';
+        $route = new Mage_Webapi_Controller_Router_Route(
+            $areaName . '/:' . Mage_Webapi_Controller_Request::PARAM_API_TYPE
+        );
 
         $testApiType = 'test_api';
-        $testUri = str_replace(':api_type', $testApiType, Mage_Webapi_Controller_Router_Route_Webapi::getApiRoute());
+        $testUri = "$areaName/$testApiType";
         $request = new Zend_Controller_Request_Http();
         $request->setRequestUri($testUri);
 
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/Role/FactoryTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/Role/FactoryTest.php
index 8243e10e3ec..77184718fd2 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/Role/FactoryTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/Role/FactoryTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test class for Mage_Webapi_Model_Acl_Role_Factory
+ * Test class for Mage_Webapi_Model_Acl_Role_Factory.
  *
  * Magento
  *
@@ -59,7 +59,7 @@ class Mage_Webapi_Model_Acl_Role_FactoryTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test create method
+     * Test create method.
      */
     public function testCreate()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/Role/InRoleUserUpdaterTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/Role/InRoleUserUpdaterTest.php
index 885d38fc410..223cd2d48e8 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/Role/InRoleUserUpdaterTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/Role/InRoleUserUpdaterTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Test class for Mage_Webapi_Model_Acl_Role_InRoleUserUpdater
+ * Test class for Mage_Webapi_Model_Acl_Role_InRoleUserUpdater.
  *
  * Magento
  *
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/RoleTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/RoleTest.php
index 329f8141184..d3040ea4200 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/RoleTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/RoleTest.php
@@ -66,7 +66,7 @@ class Mage_Webapi_Model_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Create Role model
+     * Create Role model.
      *
      * @param Mage_Webapi_Model_Resource_Acl_Role $roleResource
      * @param Mage_Webapi_Model_Resource_Acl_Role_Collection $resourceCollection
@@ -83,7 +83,7 @@ class Mage_Webapi_Model_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test constructor
+     * Test constructor.
      */
     public function testConstructor()
     {
@@ -94,7 +94,7 @@ class Mage_Webapi_Model_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test get collection and _construct
+     * Test GET collection and _construct
      */
     public function testGetCollection()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/RuleTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/RuleTest.php
index e5ffbe455f9..742016a500c 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/RuleTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/RuleTest.php
@@ -66,7 +66,7 @@ class Mage_Webapi_Model_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Create Rule model
+     * Create Rule model.
      *
      * @param Mage_Webapi_Model_Resource_Acl_Rule|PHPUnit_Framework_MockObject_MockObject $ruleResource
      * @param Mage_Webapi_Model_Resource_Acl_User_Collection $resourceCollection
@@ -83,7 +83,7 @@ class Mage_Webapi_Model_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test constructor
+     * Test constructor.
      */
     public function testConstructor()
     {
@@ -94,7 +94,7 @@ class Mage_Webapi_Model_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test method getRoleUsers()
+     * Test getRoleUsers() method.
      */
     public function testGetRoleUsers()
     {
@@ -109,7 +109,7 @@ class Mage_Webapi_Model_Acl_RuleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test get collection and _construct
+     * Test GET collection and _construct
      */
     public function testGetCollection()
     {
@@ -131,13 +131,13 @@ class Mage_Webapi_Model_Acl_RuleTest extends PHPUnit_Framework_TestCase
 
         $model = $this->_createModel($this->_ruleResource, $collection);
 
-        // test _construct
+        // Test _construct
         $result = $model->getCollection();
 
         $this->assertAttributeEquals('Mage_Webapi_Model_Acl_Rule', '_model', $result);
         $this->assertAttributeEquals('Mage_Webapi_Model_Resource_Acl_Rule', '_resourceModel', $result);
 
-        // test getByRole
+        // Test getByRole
         $resultColl = $result->getByRole(1);
         $this->assertInstanceOf('Mage_Webapi_Model_Resource_Acl_Rule_Collection', $resultColl);
     }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/User/FactoryTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/User/FactoryTest.php
index 0c9a2fb783d..b5528f2bd34 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/User/FactoryTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/User/FactoryTest.php
@@ -59,7 +59,7 @@ class Mage_Webapi_Model_Acl_User_FactoryTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test create method
+     * Test create method.
      */
     public function testCreate()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/UserTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/UserTest.php
index f1258d3906d..b3e97f53964 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/UserTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Acl/UserTest.php
@@ -66,7 +66,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Create User model
+     * Create User model.
      *
      * @param Mage_Webapi_Model_Resource_Acl_User $userResource
      * @param Mage_Webapi_Model_Resource_Acl_User_Collection $resourceCollection
@@ -83,7 +83,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test constructor
+     * Test constructor.
      */
     public function testConstructor()
     {
@@ -94,7 +94,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test method getRoleUsers()
+     * Test getRoleUsers() method.
      */
     public function testGetRoleUsers()
     {
@@ -111,7 +111,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test method loadByKey()
+     * Test loadByKey() method.
      */
     public function testLoadByKey()
     {
@@ -127,7 +127,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test public getters
+     * Test public getters.
      */
     public function testPublicGetters()
     {
@@ -140,7 +140,7 @@ class Mage_Webapi_Model_Acl_UserTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test get collection and _construct
+     * Test GET collection and _construct
      */
     public function testGetCollection()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Config/ReaderTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Config/ReaderTest.php
index 3c80c106904..9006aecb4e5 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Config/ReaderTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Config/ReaderTest.php
@@ -54,7 +54,7 @@ class Mage_Webapi_Model_Authorization_Config_ReaderTest extends PHPUnit_Framewor
     }
 
     /**
-     * Unset reader instance
+     * Unset reader instance.
      */
     protected function tearDown()
     {
@@ -63,7 +63,7 @@ class Mage_Webapi_Model_Authorization_Config_ReaderTest extends PHPUnit_Framewor
     }
 
     /**
-     * Check that correct xsd file is provided
+     * Check that correct XSD file is provided.
      */
     public function testGetSchemaFile()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/ConfigTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/ConfigTest.php
index bb75a1490ae..c85263a87b2 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/ConfigTest.php
@@ -46,7 +46,7 @@ class Mage_Webapi_Model_Authorization_ConfigTest extends PHPUnit_Framework_TestC
     protected $_config;
 
     /**
-     * Set up before test
+     * Set up before test.
      */
     protected function setUp()
     {
@@ -82,7 +82,7 @@ class Mage_Webapi_Model_Authorization_ConfigTest extends PHPUnit_Framework_TestC
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Config::getAclResources()
+     * Test for Mage_Webapi_Model_Authorization_Config::getAclResources().
      */
     public function testGetAclResources()
     {
@@ -111,7 +111,7 @@ class Mage_Webapi_Model_Authorization_ConfigTest extends PHPUnit_Framework_TestC
     }
 
     /**
-     * Get resources array recursively
+     * Get resources array recursively.
      *
      * @param DOMNodeList $resources
      * @return array
@@ -133,7 +133,7 @@ class Mage_Webapi_Model_Authorization_ConfigTest extends PHPUnit_Framework_TestC
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Config::getAclVirtualResources
+     * Test for Mage_Webapi_Model_Authorization_Config::getAclVirtualResources.
      */
     public function testGetAclVirtualResources()
     {
@@ -167,7 +167,7 @@ class Mage_Webapi_Model_Authorization_ConfigTest extends PHPUnit_Framework_TestC
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Config::getAclResourcesAsArray
+     * Test for Mage_Webapi_Model_Authorization_Config::getAclResourcesAsArray.
      *
      * @dataProvider aclResourcesDataProvider
      * @param string $actualXmlFile
@@ -244,7 +244,7 @@ class Mage_Webapi_Model_Authorization_ConfigTest extends PHPUnit_Framework_TestC
     }
 
     /**
-     * Test for method _getSortedBySortOrder
+     * Test for _getSortedBySortOrder method.
      *
      * @dataProvider getSortedBySortOrderDataProvider
      * @param array $originArray
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/ResourceTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/ResourceTest.php
index cba83036b14..b67d2dbbbed 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/ResourceTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/ResourceTest.php
@@ -46,7 +46,7 @@ class Mage_Webapi_Model_Authorization_Loader_ResourceTest extends PHPUnit_Framew
     protected $_config;
 
     /**
-     * Set up before test
+     * Set up before test.
      */
     protected function setUp()
     {
@@ -77,7 +77,7 @@ class Mage_Webapi_Model_Authorization_Loader_ResourceTest extends PHPUnit_Framew
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Loader_Resource::populateAcl
+     * Test for Mage_Webapi_Model_Authorization_Loader_Resource::populateAcl.
      */
     public function testPopulateAcl()
     {
@@ -105,7 +105,7 @@ class Mage_Webapi_Model_Authorization_Loader_ResourceTest extends PHPUnit_Framew
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Loader_Resource::populateAcl with invalid Virtual resources DOM
+     * Test for Mage_Webapi_Model_Authorization_Loader_Resource::populateAcl with invalid Virtual resources DOM.
      */
     public function testPopulateAclWithInvalidDOM()
     {
@@ -124,7 +124,7 @@ class Mage_Webapi_Model_Authorization_Loader_ResourceTest extends PHPUnit_Framew
     }
 
     /**
-     * Get Resources DOMXPath from fixture
+     * Get Resources DOMXPath from fixture.
      *
      * @return DOMXPath
      */
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/RoleTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/RoleTest.php
index 62217937fc3..8f95375b4b7 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/RoleTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/RoleTest.php
@@ -46,7 +46,7 @@ class Mage_Webapi_Model_Authorization_Loader_RoleTest extends PHPUnit_Framework_
     protected $_acl;
 
     /**
-     * Set up before test
+     * Set up before test.
      */
     protected function setUp()
     {
@@ -68,9 +68,9 @@ class Mage_Webapi_Model_Authorization_Loader_RoleTest extends PHPUnit_Framework_
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Loader_Role::populateAcl
+     * Test for Mage_Webapi_Model_Authorization_Loader_Role::populateAcl.
      *
-     * Test with existing role Ids
+     * Test with existing role IDs.
      */
     public function testPopulateAclWithRoles()
     {
@@ -101,9 +101,9 @@ class Mage_Webapi_Model_Authorization_Loader_RoleTest extends PHPUnit_Framework_
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Loader_Role::populateAcl
+     * Test for Mage_Webapi_Model_Authorization_Loader_Role::populateAcl.
      *
-     * Test with No existing role Ids
+     * Test with No existing role IDs.
      */
     public function testPopulateAclWithNoRoles()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/RuleTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/RuleTest.php
index 8f04a84accb..c63127754a0 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/RuleTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Authorization/Loader/RuleTest.php
@@ -58,7 +58,7 @@ class Mage_Webapi_Model_Authorization_Loader_RuleTest extends PHPUnit_Framework_
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Loader_Rule::populateAcl
+     * Test for Mage_Webapi_Model_Authorization_Loader_Rule::populateAcl.
      */
     public function testPopulateAcl()
     {
@@ -97,7 +97,7 @@ class Mage_Webapi_Model_Authorization_Loader_RuleTest extends PHPUnit_Framework_
     }
 
     /**
-     * Test for Mage_Webapi_Model_Authorization_Loader_Rule::populateAcl without rules
+     * Test for Mage_Webapi_Model_Authorization_Loader_Rule::populateAcl without rules.
      */
     public function testPopulateAclWithoutRules()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/RoleTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/RoleTest.php
index d4124a66d56..e9621c509b1 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/RoleTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/RoleTest.php
@@ -26,7 +26,7 @@
 class Mage_Webapi_Model_Resource_Acl_RoleTest extends Mage_Webapi_Model_Resource_Acl_TestAbstract
 {
     /**
-     * Create resource model
+     * Create resource model.
      *
      * @param Varien_Db_Select $selectMock
      * @return Mage_Webapi_Model_Resource_Acl_Role
@@ -80,7 +80,7 @@ class Mage_Webapi_Model_Resource_Acl_RoleTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test constructor
+     * Test constructor.
      */
     public function testConstructor()
     {
@@ -91,7 +91,7 @@ class Mage_Webapi_Model_Resource_Acl_RoleTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test _initUniqueFields()
+     * Test _initUniqueFields().
      */
     public function testGetUniqueFields()
     {
@@ -102,7 +102,7 @@ class Mage_Webapi_Model_Resource_Acl_RoleTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test getRolesList()
+     * Test getRolesList().
      */
     public function testGetRolesList()
     {
@@ -127,7 +127,7 @@ class Mage_Webapi_Model_Resource_Acl_RoleTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test getRolesIds()
+     * Test getRolesIds().
      */
     public function testGetRolesIds()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/RuleTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/RuleTest.php
index c0108298a67..0e194f91a33 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/RuleTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/RuleTest.php
@@ -26,7 +26,7 @@
 class Mage_Webapi_Model_Resource_Acl_RuleTest extends Mage_Webapi_Model_Resource_Acl_TestAbstract
 {
     /**
-     * Create resource model
+     * Create resource model.
      *
      * @param Varien_Db_Select $selectMock
      * @return Mage_Webapi_Model_Resource_Acl_Rule
@@ -86,7 +86,7 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test constructor
+     * Test constructor.
      */
     public function testConstructor()
     {
@@ -97,7 +97,7 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test getRuleList()
+     * Test getRuleList().
      */
     public function testGetRuleList()
     {
@@ -117,7 +117,7 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test getResourceIdsByRole()
+     * Test getResourceIdsByRole().
      */
     public function testGetResourceIdsByRole()
     {
@@ -142,11 +142,11 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test saveResources()
+     * Test saveResources().
      */
     public function testSaveResources()
     {
-        // init rule resource
+        // Init rule resource.
         $ruleResource = $this->getMockBuilder('Mage_Webapi_Model_Resource_Acl_Rule')
             ->disableOriginalConstructor()
             ->setMethods(array('saveResources', 'getIdFieldName', 'getReadConnection', 'getResources'))
@@ -162,7 +162,7 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends Mage_Webapi_Model_Resource
             ->withAnyParameters()
             ->will($this->returnValue($this->getMock('Varien_Db_Adapter_Pdo_Mysql', array(), array(), '', false)));
 
-        // init rule
+        // Init rule.
         $rule = $this->getMockBuilder('Mage_Webapi_Model_Acl_Rule')
             ->setConstructorArgs(array(
                 'eventDispatcher' => $this->getMock('Mage_Core_Model_Event_Manager', array(), array(), '', false),
@@ -179,7 +179,7 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends Mage_Webapi_Model_Resource
 
         $model = $this->_createModel();
 
-        // init adapter
+        // Init adapter.
         $this->_adapter->expects($this->any())
             ->method('delete')
             ->withAnyParameters()
@@ -194,7 +194,7 @@ class Mage_Webapi_Model_Resource_Acl_RuleTest extends Mage_Webapi_Model_Resource
         $rule->setRoleId(1);
         $model->saveResources($rule);
 
-        // init adapter
+        // Init adapter.
         $this->_adapter->expects($this->any())
             ->method('delete')
             ->withAnyParameters()
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/UserTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/UserTest.php
index 30003fdd3ea..e49ecdf0603 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/UserTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Resource/Acl/UserTest.php
@@ -26,7 +26,7 @@
 class Mage_Webapi_Model_Resource_Acl_UserTest extends Mage_Webapi_Model_Resource_Acl_TestAbstract
 {
     /**
-     * Create resource model
+     * Create resource model.
      *
      * @param Varien_Db_Select $selectMock
      * @return Mage_Webapi_Model_Resource_Acl_User
@@ -75,7 +75,7 @@ class Mage_Webapi_Model_Resource_Acl_UserTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test constructor
+     * Test constructor.
      */
     public function testConstructor()
     {
@@ -86,7 +86,7 @@ class Mage_Webapi_Model_Resource_Acl_UserTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test _initUniqueFields()
+     * Test _initUniqueFields().
      */
     public function testGetUniqueFields()
     {
@@ -97,7 +97,7 @@ class Mage_Webapi_Model_Resource_Acl_UserTest extends Mage_Webapi_Model_Resource
     }
 
     /**
-     * Test getRoleUsers()
+     * Test getRoleUsers().
      */
     public function testGetRoleUsers()
     {
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Rest/Oauth/ServerTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Rest/Oauth/ServerTest.php
index 22ed8a88245..e01a6b9d5e5 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Rest/Oauth/ServerTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Rest/Oauth/ServerTest.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Two-legged oAuth server test.
+ * Two-legged OAuth server test.
  *
  * Magento
  *
@@ -66,14 +66,14 @@ class Mage_Webapi_Model_Rest_Oauth_ServerTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test two legged authentication
+     * Test two-legged authentication
      */
     public function testAuthenticateTwoLegged()
     {
         $testUserKey = 'foo_user';
         $testUserSecret = 'bar_secret';
         $testUrl = 'http://foo.bar/api/rest/v1/baz';
-        // Prepare signature and oAuth parameters
+        // Prepare signature and OAuth parameters.
         $utility = new Zend_Oauth_Http_Utility();
         $params = array(
             'oauth_consumer_key' => $testUserKey,
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/AutoDiscoverTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/AutoDiscoverTest.php
index 1b58c2199a2..cb0e5020710 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/AutoDiscoverTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/AutoDiscoverTest.php
@@ -160,20 +160,20 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Test handle method with loading wsdl from cache.
+     * Test handle method with loading WSDL from cache.
      */
     public function testHandleLoadWsdlFromCache()
     {
         /** Mock cache canUse method to return true. */
         $this->_cacheMock->expects($this->once())->method('canUse')->will($this->returnValue(true));
-        /** Mock cache load method to return cache Id. */
+        /** Mock cache load method to return cache ID. */
         $this->_cacheMock->expects($this->once())->method('load')->will($this->returnArgument(0));
         $requestedResources = array(
             'res1' => 'v1',
             'res2' => 'v2'
         );
         $result = $this->_autoDiscover->handle($requestedResources, 'http://magento.host');
-        /** Assert handle method will return string that starts with WSDL. */
+        /** Assert that handle method will return string that starts with WSDL. */
         $this->assertStringStartsWith(
             Mage_Webapi_Model_Soap_AutoDiscover::WSDL_CACHE_ID,
             $result,
@@ -202,7 +202,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Data provider for generate() test
+     * Data provider for generate() test.
      *
      * @return array
      */
@@ -274,7 +274,7 @@ class Mage_Webapi_Model_Soap_AutoDiscoverTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Create mock for DOMElement
+     * Create mock for DOMElement.
      *
      * @return PHPUnit_Framework_MockObject_MockObject
      */
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/FaultTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/FaultTest.php
index b2d146ab456..ff742cce490 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/FaultTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/FaultTest.php
@@ -62,14 +62,14 @@ XML;
         $this->assertXmlStringEqualsXmlString(
             $expectedResult,
             $actualXml,
-            'Wrong soap fault message with default parameters.'
+            'Wrong SOAP fault message with default parameters.'
         );
     }
 
     public function testToXmlDeveloperModeOn()
     {
         $actualXml = $this->_soapFault->toXml(true);
-        $this->assertContains('<ExceptionTrace>', $actualXml, 'Exception trace not found in XML.');
+        $this->assertContains('<ExceptionTrace>', $actualXml, 'Exception trace is not found in XML.');
     }
 
     /**
@@ -101,17 +101,17 @@ XML;
      */
     public function dataProviderForGetSoapFaultMessageTest()
     {
-        /** Include file with all expected soap fault XMLs. */
+        /** Include file with all expected SOAP fault XMLs. */
         $expectedXmls = include __DIR__ . '/../../_files/soap_fault/soap_fault_expected_xmls.php';
         return array(
-            //Each array contains data for SOAP Fault Message, Expected XML and Assert Message.
+            //Each array contains data for SOAP Fault Message, Expected XML, and Assert Message.
             array(
                 'Fault reason',
                 'Sender',
                 'cn',
                 array('key1' => 'value1', 'key2' => 'value2'),
                 $expectedXmls['expectedResultArrayDataDetails'],
-                'Wrong soap fault message with associated array data details.'
+                'SOAP fault message with associated array data details is invalid.'
             ),
             array(
                 'Fault reason',
@@ -119,7 +119,7 @@ XML;
                 'en',
                 array('value1', 'value2'),
                 $expectedXmls['expectedResultIndexArrayDetails'],
-                'Wrong soap fault message with index array data details.'
+                'SOAP fault message with index array data details is invalid.'
             ),
             array(
                 'Fault reason',
@@ -127,7 +127,7 @@ XML;
                 'en',
                 array(),
                 $expectedXmls['expectedResultEmptyArrayDetails'],
-                'Wrong soap fault message with empty array data details.'
+                'SOAP fault message with empty array data details is invalid.'
             ),
             array(
                 'Fault reason',
@@ -135,7 +135,7 @@ XML;
                 'en',
                 (object)array('key' => 'value'),
                 $expectedXmls['expectedResultObjectDetails'],
-                'Wrong soap fault message with object data details.'
+                'SOAP fault message with object data details is invalid.'
             ),
             array(
                 'Fault reason',
@@ -143,7 +143,7 @@ XML;
                 'en',
                 'String details',
                 $expectedXmls['expectedResultStringDetails'],
-                'Wrong soap fault message with string data details.'
+                'SOAP fault message with string data details is invalid.'
             ),
             array(
                 'Fault reason',
@@ -151,7 +151,7 @@ XML;
                 'en',
                 array('key' => array('sub_key' => 'value')),
                 $expectedXmls['expectedResultComplexDataDetails'],
-                'Wrong soap fault message with complex data details.'
+                'SOAP fault message with complex data details is invalid.'
             ),
         );
     }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/Security/UsernameTokenTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/Security/UsernameTokenTest.php
index dd072623f37..007d2324c94 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/Security/UsernameTokenTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/Security/UsernameTokenTest.php
@@ -52,7 +52,7 @@ class Mage_Webapi_Model_Soap_Security_UsernameTokenTest extends PHPUnit_Framewor
     {
         $this->_nonceStorageMock = $this->getMockBuilder('Mage_Webapi_Model_Soap_Security_UsernameToken_NonceStorage')
             ->disableOriginalConstructor()
-            ->setConstructorArgs(array('validateNonce'))
+            ->setMethods(array('validateNonce'))
             ->getMock();
         $this->_userMock = $this->getMockBuilder('Mage_Webapi_Model_Acl_User')
             ->disableOriginalConstructor()
@@ -119,7 +119,7 @@ class Mage_Webapi_Model_Soap_Security_UsernameTokenTest extends PHPUnit_Framewor
     }
 
     /**
-     * Data provider for testConstructNewUsernameToken
+     * Data provider for testConstructNewUsernameToken.
      *
      * @return array
      */
@@ -154,7 +154,7 @@ class Mage_Webapi_Model_Soap_Security_UsernameTokenTest extends PHPUnit_Framewor
     }
 
     /**
-     * Data provider for testConstructNewUsernameTokenWithInvalidCreatedDate
+     * Data provider for testConstructNewUsernameTokenWithInvalidCreatedDate.
      *
      * @return array
      */
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/ServerTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/ServerTest.php
index 2f9441f02b2..ab29dd0c223 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/ServerTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/ServerTest.php
@@ -25,15 +25,20 @@
  */
 class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
 {
+    const WEBAPI_AREA_FRONT_NAME = 'webapi';
+
     /** @var Mage_Webapi_Model_Soap_Server */
     protected $_soapServer;
 
     /** @var Mage_Core_Model_App */
-    protected $_applicationMock;
+    protected $_appMock;
 
     /** @var Mage_Core_Model_Store */
     protected $_storeMock;
 
+    /** @var Mage_Core_Model_Config */
+    protected $_configMock;
+
     /** @var Mage_Webapi_Controller_Request_Soap */
     protected $_requestMock;
 
@@ -44,8 +49,13 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
     {
         /** Init all dependencies for SUT. */
         $this->_storeMock = $this->getMockBuilder('Mage_Core_Model_Store')->disableOriginalConstructor()->getMock();
-        $this->_applicationMock = $this->getMockBuilder('Mage_Core_Model_App')->disableOriginalConstructor()->getMock();
-        $this->_applicationMock->expects($this->any())->method('getStore')->will($this->returnValue($this->_storeMock));
+        $this->_configMock = $this->getMockBuilder('Mage_Core_Model_Config')->disableOriginalConstructor()->getMock();
+        $this->_configMock->expects($this->any())->method('getAreaFrontName')->will(
+            $this->returnValue(self::WEBAPI_AREA_FRONT_NAME)
+        );
+        $this->_appMock = $this->getMockBuilder('Mage_Core_Model_App')->disableOriginalConstructor()->getMock();
+        $this->_appMock->expects($this->any())->method('getStore')->will($this->returnValue($this->_storeMock));
+        $this->_appMock->expects($this->any())->method('getConfig')->will($this->returnValue($this->_configMock));
         $this->_requestMock = $this->getMockBuilder('Mage_Webapi_Controller_Request_Soap')->disableOriginalConstructor()
             ->getMock();
         $this->_domDocumentFactory = $this->getMockBuilder('Magento_DomDocument_Factory')
@@ -53,7 +63,7 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
 
         /** Init SUT. */
         $this->_soapServer = new Mage_Webapi_Model_Soap_Server(
-            $this->_applicationMock,
+            $this->_appMock,
             $this->_requestMock,
             $this->_domDocumentFactory
         );
@@ -64,7 +74,7 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
     protected function tearDown()
     {
         unset($this->_soapServer);
-        unset($this->_applicationMock);
+        unset($this->_appMock);
         unset($this->_requestMock);
         unset($this->_storeMock);
         parent::tearDown();
@@ -76,7 +86,11 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
     public function testGetApiCharset()
     {
         $this->_storeMock->expects($this->once())->method('getConfig')->will($this->returnValue('Windows-1251'));
-        $this->assertEquals('Windows-1251', $this->_soapServer->getApiCharset(), 'Wrong API charset encoding getting.');
+        $this->assertEquals(
+            'Windows-1251',
+            $this->_soapServer->getApiCharset(),
+            'API charset encoding getting is invalid.'
+        );
     }
 
     /**
@@ -88,7 +102,7 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(
             Mage_Webapi_Model_Soap_Server::SOAP_DEFAULT_ENCODING,
             $this->_soapServer->getApiCharset(),
-            'Wrong default API charset encoding getting.'
+            'Default API charset encoding getting is invalid.'
         );
     }
 
@@ -104,8 +118,8 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
             $this->returnValue(array('res' => 'v1'))
         );
         $actualResult = $this->_soapServer->generateUri();
-        $expectedResult = 'http://magento.com/api/soap?resources%5Bres%5D=v1';
-        $this->assertEquals($expectedResult, $actualResult, 'Wrong URI generation with default parameter.');
+        $expectedResult = 'http://magento.com/' . self::WEBAPI_AREA_FRONT_NAME . '/soap?resources%5Bres%5D=v1';
+        $this->assertEquals($expectedResult, $actualResult, 'URI generation with default parameter is invalid.');
     }
 
     /**
@@ -133,10 +147,10 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
         $this->_storeMock->expects($this->once())->method('getBaseUrl')->will(
             $this->returnValue('http://magento.com/')
         );
-        $expectedResult = 'http://magento.com/' . Mage_Webapi_Controller_Router_Route_Webapi::API_AREA_NAME . '/'
+        $expectedResult = 'http://magento.com/' . self::WEBAPI_AREA_FRONT_NAME . '/'
             . Mage_Webapi_Controller_Front::API_TYPE_SOAP;
         $actualResult = $this->_soapServer->getEndpointUri();
-        $this->assertEquals($expectedResult, $actualResult, 'Wrong endpoint URI building.');
+        $this->assertEquals($expectedResult, $actualResult, 'Endpoint URI building is invalid.');
     }
 
     /**
@@ -147,7 +161,7 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
         /** Init Exception. */
         $exception = new Exception();
         $faultResult = $this->_soapServer->fault($exception);
-        /** Assert returned object is instance of SoapFault class. */
+        /** Assert that returned object is instance of SoapFault class. */
         $this->assertInstanceOf('SoapFault', $faultResult, 'SoapFault was not returned.');
     }
 
@@ -158,7 +172,7 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
     {
         /** Mock Webapi Soap fault. */
         $apiFault = $this->getMockBuilder('Mage_Webapi_Model_Soap_Fault')->disableOriginalConstructor()->getMock();
-        /** Assert mocked fault toXml method will be executed once. */
+        /** Assert that mocked fault toXml method will be executed once. */
         $apiFault->expects($this->once())->method('toXml');
         $this->_soapServer->fault($apiFault);
     }
@@ -168,25 +182,26 @@ class Mage_Webapi_Model_Soap_ServerTest extends PHPUnit_Framework_TestCase
      */
     public function providerForGenerateUriTest()
     {
+        $webapiFrontName = self::WEBAPI_AREA_FRONT_NAME;
         return array(
             //Each array contains isWsdl flag, resources, expected URI and assert message.
             'Several resources' => array(
                 false,
                 array('customer' => 'v1', 'product' => 'v2'),
-                'http://magento.com/api/soap?resources%5Bcustomer%5D=v1&resources%5Bproduct%5D=v2',
-                'Wrong URI generation with several resources.'
+                "http://magento.com/$webapiFrontName/soap?resources%5Bcustomer%5D=v1&resources%5Bproduct%5D=v2",
+                'URI generation with several resources is invalid.'
             ),
             'Several resources with WSDL' => array(
                 true,
                 array('customer' => 'v1', 'product' => 'v2'),
-                'http://magento.com/api/soap?resources%5Bcustomer%5D=v1&resources%5Bproduct%5D=v2&wsdl=1',
-                'Wrong URI generation with several resources and WSDL.'
+                "http://magento.com/$webapiFrontName/soap?resources%5Bcustomer%5D=v1&resources%5Bproduct%5D=v2&wsdl=1",
+                'URI generation with several resources and WSDL is invalid.'
             ),
             'Empty resources list' => array(
                 true,
                 array(),
-                'http://magento.com/api/soap?wsdl=1',
-                'Wrong URI generation without resources.'
+                "http://magento.com/$webapiFrontName/soap?wsdl=1",
+                'URI generation without resources is invalid.'
             ),
         );
     }
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy/ConfigBasedTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy/ConfigBasedTest.php
index 5012207f262..0525cfa307c 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy/ConfigBasedTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Soap/Wsdl/ComplexTypeStrategy/ConfigBasedTest.php
@@ -74,7 +74,7 @@ class Mage_Webapi_Model_Soap_Wsdl_ComplexTypeStrategy_ConfigBasedTest extends PH
     }
 
     /**
-     * Test that addComplexType returns type wsdl name
+     * Test that addComplexType returns type WSDL name
      * if it has already been processed (registered at includedTypes in WSDL)
      */
     public function testCheckTypeName()
@@ -124,7 +124,7 @@ class Mage_Webapi_Model_Soap_Wsdl_ComplexTypeStrategy_ConfigBasedTest extends PH
     }
 
     /**
-     * Data provider for testAddComplexTypeSimpleParameters()
+     * Data provider for testAddComplexTypeSimpleParameters().
      *
      * @return array
      */
@@ -279,7 +279,7 @@ class Mage_Webapi_Model_Soap_Wsdl_ComplexTypeStrategy_ConfigBasedTest extends PH
     }
 
     /**
-     * Create mock for DOMElement
+     * Create mock for DOMElement.
      *
      * @return PHPUnit_Framework_MockObject_MockObject
      */
diff --git a/dev/tests/unit/testsuite/Mage/Webapi/Model/Source/Acl/RoleTest.php b/dev/tests/unit/testsuite/Mage/Webapi/Model/Source/Acl/RoleTest.php
index cf131431b58..f31c97ca8d2 100644
--- a/dev/tests/unit/testsuite/Mage/Webapi/Model/Source/Acl/RoleTest.php
+++ b/dev/tests/unit/testsuite/Mage/Webapi/Model/Source/Acl/RoleTest.php
@@ -31,7 +31,7 @@
 class Mage_Webapi_Model_Source_Acl_RoleTest extends PHPUnit_Framework_TestCase
 {
     /**
-     * Check output format
+     * Check output format.
      *
      * @dataProvider toOptionsHashDataProvider
      *
@@ -58,7 +58,7 @@ class Mage_Webapi_Model_Source_Acl_RoleTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * Data provider for testing toOptionHash
+     * Data provider for testing toOptionHash.
      *
      * @return array
      */
diff --git a/dev/tests/unit/testsuite/Magento/ShellTest.php b/dev/tests/unit/testsuite/Magento/ShellTest.php
index f4f8e78c819..88788b34e1d 100644
--- a/dev/tests/unit/testsuite/Magento/ShellTest.php
+++ b/dev/tests/unit/testsuite/Magento/ShellTest.php
@@ -27,50 +27,74 @@
 
 class Magento_ShellTest extends PHPUnit_Framework_TestCase
 {
-    public function testGetSetVerbose()
+    /**
+     * Test that a command with input arguments returns an expected result
+     *
+     * @param Magento_Shell $shell
+     * @param string $command
+     * @param array $commandArgs
+     * @param string $expectedResult
+     */
+    protected function _testExecuteCommand(Magento_Shell $shell, $command, $commandArgs, $expectedResult)
     {
-        $shell = new Magento_Shell(false);
-        $this->assertFalse($shell->isVerbose());
-
-        $shell->setVerbose(true);
-        $this->assertTrue($shell->isVerbose());
+        $this->expectOutputString(''); // nothing is expected to be ever printed to the standard output
+        $actualResult = $shell->execute($command, $commandArgs);
+        $this->assertEquals($expectedResult, $actualResult);
+    }
 
-        $shell->setVerbose(false);
-        $this->assertFalse($shell->isVerbose());
+    /**
+     * @param string $command
+     * @param array $commandArgs
+     * @param string $expectedResult
+     * @dataProvider executeDataProvider
+     */
+    public function testExecute($command, $commandArgs, $expectedResult)
+    {
+        $this->_testExecuteCommand(new Magento_Shell(), $command, $commandArgs, $expectedResult);
     }
 
     /**
-     * @param string $phpCommand
-     * @param bool $isVerbose
-     * @param string $expectedOutput
+     * @param string $command
+     * @param array $commandArgs
      * @param string $expectedResult
+     * @param array $expectedLogRecords
      * @dataProvider executeDataProvider
      */
-    public function testExecute($phpCommand, $isVerbose, $expectedOutput, $expectedResult = '')
+    public function testExecuteLog($command, $commandArgs, $expectedResult, $expectedLogRecords)
     {
-        $this->expectOutputString($expectedOutput);
-        $shell = new Magento_Shell($isVerbose);
-        $actualResult = $shell->execute('php -r %s', array($phpCommand));
-        $this->assertEquals($expectedResult, $actualResult);
+        $quoteChar = substr(escapeshellarg(' '), 0, 1); // environment-dependent quote character
+        $logger = $this->getMock('Zend_Log', array('log'));
+        foreach ($expectedLogRecords as $logRecordIndex => $expectedLogMessage) {
+            $expectedLogMessage = str_replace('`', $quoteChar, $expectedLogMessage);
+            $logger
+                ->expects($this->at($logRecordIndex))
+                ->method('log')
+                ->with($expectedLogMessage, Zend_Log::INFO)
+            ;
+        }
+        $this->_testExecuteCommand(new Magento_Shell($logger), $command, $commandArgs, $expectedResult);
     }
 
     public function executeDataProvider()
     {
-        $quote = substr(escapeshellarg(' '), 0, 1);
-        $eol = PHP_EOL;
+        // backtick symbol (`) has to be replaced with environment-dependent quote character
         return array(
-            'capture STDOUT' => array(
-                'echo 27181;', false, '', '27181',
+            'STDOUT' => array(
+                'php -r %s', array('echo 27181;'), '27181',
+                array('php -r `echo 27181;` 2>&1', '27181'),
             ),
-            'print STDOUT' => array(
-                'echo 27182;', true, "php -r {$quote}echo 27182;{$quote} 2>&1{$eol}27182{$eol}", '27182',
+            'STDERR' => array(
+                'php -r %s', array('fwrite(STDERR, 27182);'), '27182',
+                array('php -r `fwrite(STDERR, 27182);` 2>&1', '27182'),
             ),
-            'capture STDERR' => array(
-                'fwrite(STDERR, 27183);', false, '', '27183',
+            'piping STDERR -> STDOUT' => array(
+                // intentionally no spaces around the pipe symbol
+                'php -r %s|php -r %s', array('fwrite(STDERR, 27183);', 'echo fgets(STDIN);'), '27183',
+                array('php -r `fwrite(STDERR, 27183);` 2>&1|php -r `echo fgets(STDIN);` 2>&1', '27183'),
             ),
-            'print STDERR' => array(
-                'fwrite(STDERR, 27184);', true, "php -r {$quote}fwrite(STDERR, 27184);{$quote} 2>&1{$eol}27184{$eol}",
-                '27184',
+            'piping STDERR -> STDERR' => array(
+                'php -r %s | php -r %s', array('fwrite(STDERR, 27184);', 'fwrite(STDERR, fgets(STDIN));'), '27184',
+                array('php -r `fwrite(STDERR, 27184);` 2>&1 | php -r `fwrite(STDERR, fgets(STDIN));` 2>&1', '27184'),
             ),
         );
     }
@@ -87,31 +111,21 @@ class Magento_ShellTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * @param string $phpCommand
-     * @param bool $isVerbose
-     * @param string $expectedOutput
+     * @param string $command
+     * @param array $commandArgs
      * @param string $expectedError
      * @dataProvider executeDataProvider
      */
-    public function testExecuteFailureDetails($phpCommand, $isVerbose, $expectedOutput, $expectedError)
+    public function testExecuteFailureDetails($command, $commandArgs, $expectedError)
     {
         try {
             /* Force command to return non-zero exit code */
-            $phpFailingCommand = $phpCommand . ' exit(42);';
-            $expectedOutput = str_replace($phpCommand, $phpFailingCommand, $expectedOutput);
-            $this->testExecute($phpFailingCommand, $isVerbose, $expectedOutput);
+            $commandArgs[count($commandArgs) - 1] .= ' exit(42);';
+            $this->testExecute($command, $commandArgs, ''); // no result is expected in a case of a command failure
         } catch (Magento_Exception $e) {
             $this->assertInstanceOf('Exception', $e->getPrevious());
             $this->assertEquals($expectedError, $e->getPrevious()->getMessage());
             $this->assertEquals(42, $e->getPrevious()->getCode());
         }
     }
-
-    public function testOutput()
-    {
-        $fixture = uniqid();
-        $this->expectOutputString($fixture . PHP_EOL);
-        $shell = new Magento_Shell;
-        $shell->output($fixture);
-    }
 }
diff --git a/index.php b/index.php
index 3c539f7b347..ced5562a056 100644
--- a/index.php
+++ b/index.php
@@ -26,7 +26,14 @@
  * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-require_once __DIR__ . '/app/bootstrap.php';
+require __DIR__ . '/app/bootstrap.php';
+Mage::run($_SERVER);
 
-$appOptions = new Mage_Core_Model_App_Options($_SERVER);
-Mage::run($appOptions->getRunCode(), $appOptions->getRunType(), $appOptions->getRunOptions());
+/**
+ * Example - run a particular store or website:
+ *
+ * $params = $_SERVER;
+ * $params['MAGE_RUN_CODE'] = 'website2';
+ * $params['MAGE_RUN_TYPE'] = 'website';
+ * Mage::run($params)
+ */
diff --git a/lib/Magento/Filesystem/Adapter/Local.php b/lib/Magento/Filesystem/Adapter/Local.php
index 176a89978e5..74f189e5c3a 100644
--- a/lib/Magento/Filesystem/Adapter/Local.php
+++ b/lib/Magento/Filesystem/Adapter/Local.php
@@ -290,7 +290,12 @@ class Magento_Filesystem_Adapter_Local implements
      */
     public function touch($key, $fileModificationTime = null)
     {
-        if (!@touch($key, $fileModificationTime)) {
+        if ($fileModificationTime === null) {
+            $success = @touch($key);
+        } else {
+            $success = @touch($key, $fileModificationTime);
+        }
+        if (!$success) {
             throw new Magento_Filesystem_Exception(sprintf('Failed to touch %s', $key));
         }
     }
diff --git a/lib/Magento/ObjectManager/Zend.php b/lib/Magento/ObjectManager/Zend.php
index 6f28e52e3a4..130fc7bda04 100644
--- a/lib/Magento/ObjectManager/Zend.php
+++ b/lib/Magento/ObjectManager/Zend.php
@@ -117,7 +117,12 @@ class Magento_ObjectManager_Zend implements Magento_ObjectManager
     }
 
     /**
-     * Add shared instance
+     * A proxy for adding shared instance
+     *
+     * Normally Di object manager determines a hash based on the class name and incoming arguments.
+     * But in client code it is inconvenient (or nearly impossible) to "know" arguments for the objects you depend on.
+     * This is a dirty hack that allows bypassing "hash checking" by Di object manager and therefore referring
+     * to an instance using class name (or alias), but not specifying its non-injectable arguments.
      *
      * @param object $instance
      * @param string $classOrAlias
diff --git a/lib/Magento/Shell.php b/lib/Magento/Shell.php
index 175c38181a5..bf31706cfd7 100644
--- a/lib/Magento/Shell.php
+++ b/lib/Magento/Shell.php
@@ -30,42 +30,20 @@
 class Magento_Shell
 {
     /**
-     * Verbosity of command execution - whether command output is printed to the standard output or not
+     * Logger instance
      *
-     * @var bool
+     * @var Zend_Log
      */
-    protected $_isVerbose;
+    protected $_logger;
 
     /**
      * Constructor
      *
-     * @param bool $isVerbose Whether command output is printed to the standard output or not
+     * @param Zend_Log $logger Logger instance to be used to log commands and their output
      */
-    public function __construct($isVerbose = false)
+    public function __construct(Zend_Log $logger = null)
     {
-        $this->_isVerbose = $isVerbose;
-    }
-
-    /**
-     * Set verbosity
-     *
-     * @param bool $isVerbose
-     * @return Magento_Shell
-     */
-    public function setVerbose($isVerbose)
-    {
-        $this->_isVerbose = $isVerbose;
-        return $this;
-    }
-
-    /**
-     * Get verbosity
-     *
-     * @return bool
-     */
-    public function isVerbose()
-    {
-        return $this->_isVerbose;
+        $this->_logger = $logger;
     }
 
     /**
@@ -79,15 +57,12 @@ class Magento_Shell
     public function execute($command, array $arguments = array())
     {
         $arguments = array_map('escapeshellarg', $arguments);
-        $command = vsprintf("$command 2>&1", $arguments); // Output errors to STDOUT instead of STDERR
-        if ($this->_isVerbose) {
-            $this->output($command);
-        }
+        $command = preg_replace('/\s?\||$/', ' 2>&1$0', $command); // Output errors to STDOUT instead of STDERR
+        $command = vsprintf($command, $arguments);
+        $this->_log($command);
         exec($command, $output, $exitCode);
         $output = implode(PHP_EOL, $output);
-        if ($this->_isVerbose) {
-            $this->output($output);
-        }
+        $this->_log($output);
         if ($exitCode) {
             $commandError = new Exception($output, $exitCode);
             throw new Magento_Exception("Command `$command` returned non-zero exit code.", 0, $commandError);
@@ -96,12 +71,14 @@ class Magento_Shell
     }
 
     /**
-     * Echo the specified message
+     * Log a message, if a logger is specified
      *
      * @param string $message
      */
-    public function output($message)
+    protected function _log($message)
     {
-        echo $message . PHP_EOL;
+        if ($this->_logger) {
+            $this->_logger->log($message, Zend_Log::INFO);
+        }
     }
 }
diff --git a/lib/Varien/Data/Form/Element/Date.php b/lib/Varien/Data/Form/Element/Date.php
index 5178fbf56ae..da00b74644f 100644
--- a/lib/Varien/Data/Form/Element/Date.php
+++ b/lib/Varien/Data/Form/Element/Date.php
@@ -38,7 +38,7 @@ class Varien_Data_Form_Element_Date extends Varien_Data_Form_Element_Abstract
      */
     protected $_value;
 
-    public function __construct($attributes=array())
+    public function __construct($attributes = array())
     {
         parent::__construct($attributes);
         $this->setType('text');
@@ -104,8 +104,7 @@ class Varien_Data_Form_Element_Date extends Varien_Data_Form_Element_Abstract
         }
         try {
             $this->_value = new Zend_Date($value, $format, $locale);
-        }
-        catch (Exception $e) {
+        } catch (Exception $e) {
             $this->_value = '';
         }
         return $this;
@@ -124,7 +123,7 @@ class Varien_Data_Form_Element_Date extends Varien_Data_Form_Element_Abstract
             return '';
         }
         if (null === $format) {
-            $format = $this->getFormat();
+            $format = $this->getDateFormat();
         }
         return $this->_value->toString($format);
     }
@@ -148,6 +147,7 @@ class Varien_Data_Form_Element_Date extends Varien_Data_Form_Element_Abstract
      * - the value must be instantiated (Zend_Date)
      * - output format must be set (compatible with Zend_Date)
      *
+     * @throws Exception
      * @return string
      */
     public function getElementHtml()
@@ -155,19 +155,21 @@ class Varien_Data_Form_Element_Date extends Varien_Data_Form_Element_Abstract
         $this->addClass('input-text');
 
         $html = sprintf(
-            '<input name="%s" id="%s" value="%s" %s style="width:110px !important;" ' . $this->_getUiId('hidden') . '/>',
-            $this->getName(), $this->getHtmlId(), $this->_escape($this->getValue()), $this->serialize($this->getHtmlAttributes()),
-            $this->getImage(), $this->getHtmlId(), 'Select Date', ($this->getDisabled() ? 'display:none;' : '')
+            '<input name="%s" id="%s" value="%s" %s style="width:110px !important;" />',
+            $this->getName(),
+            $this->getHtmlId(),
+            $this->_escape($this->getValue()),
+            $this->serialize($this->getHtmlAttributes())
         );
         $dateFormat = $this->getDateFormat();
         $timeFormat = $this->getTimeFormat();
         if (empty($dateFormat)) {
-            throw new Exception('Output format is not specified. Please, specify "format" key in constructor, or set it using setFormat().');
+            throw new Exception('Output format is not specified. '
+                . 'Please, specify "format" key in constructor, or set it using setFormat().');
         }
 
         $html .= sprintf('
             <script type="text/javascript">
-            //<![CDATA[
             (function($) {
                 $("#%s").calendar({
                     dateFormat: "%s",
@@ -177,8 +179,7 @@ class Varien_Data_Form_Element_Date extends Varien_Data_Form_Element_Abstract
                     buttonText: "%s",
                     disabled: %s
                 })
-            })(jQuery)
-            //]]>
+            })(jQuery);
             </script>',
             $this->getHtmlId(),
             $dateFormat,
diff --git a/pub/.htaccess b/pub/.htaccess
index 51fde249567..518d6c87420 100644
--- a/pub/.htaccess
+++ b/pub/.htaccess
@@ -134,11 +134,6 @@
     RewriteCond %{REQUEST_METHOD} ^TRAC[EK]
     RewriteRule .* - [L,R=405]
 
-############################################
-## always send 404 on missing files in these folders
-
-    RewriteCond %{REQUEST_URI} !^/(media|js)/
-
 ############################################
 ## never rewrite for existing files, directories and links
 
diff --git a/pub/get.php b/pub/get.php
index 2e2c763d1fb..050d2eb26d2 100644
--- a/pub/get.php
+++ b/pub/get.php
@@ -26,21 +26,17 @@
  * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-require_once __DIR__ . '/../app/bootstrap.php';
-
-$varDirectory = BP . DS . Mage_Core_Model_Config_Options::VAR_DIRECTORY;
-$publicDirectory = BP . DS . Mage_Core_Model_Config_Options::PUB_DIRECTORY;
-$configCacheFile = $varDirectory . DS . 'resource_config.json';
+require dirname(__DIR__) . '/app/bootstrap.php';
 
 $mediaDirectory = null;
 $allowedResources = array();
-
+$configCacheFile = dirname(__DIR__) . '/var/resource_config.json';
 if (file_exists($configCacheFile) && is_readable($configCacheFile)) {
     $config = json_decode(file_get_contents($configCacheFile), true);
 
     //checking update time
     if (filemtime($configCacheFile) + $config['update_time'] > time()) {
-        $mediaDirectory = trim(str_replace($publicDirectory, '', $config['media_directory']), DS);
+        $mediaDirectory = trim(str_replace(__DIR__, '', $config['media_directory']), DS);
         $allowedResources = array_merge($allowedResources, $config['allowed_resources']);
     }
 }
@@ -49,7 +45,7 @@ $request = new Zend_Controller_Request_Http();
 
 $pathInfo = str_replace('..', '', ltrim($request->getPathInfo(), '/'));
 
-$filePath = str_replace('/', DS, $publicDirectory . DS . $pathInfo);
+$filePath = str_replace('/', DS, __DIR__ . DS . $pathInfo);
 
 if ($mediaDirectory) {
     if (0 !== stripos($pathInfo, $mediaDirectory . '/') || is_dir($filePath)) {
@@ -61,18 +57,20 @@ if ($mediaDirectory) {
     sendFile($filePath);
 }
 
-$appOptions = new Mage_Core_Model_App_Options($_SERVER);
 if (empty($mediaDirectory)) {
-    Mage::init($appOptions->getRunCode(), $appOptions->getRunType(), $appOptions->getRunOptions());
+    Mage::init($_SERVER);
 } else {
-    $appRunOptions = array_merge($appOptions->getRunOptions(), array('cache' => array('disallow_save' => true)));
-    Mage::init($appOptions->getRunCode(), $appOptions->getRunType(), $appRunOptions, array('Mage_Core'));
+    $params = array_merge(
+        $_SERVER,
+        array(Mage_Core_Model_Cache::APP_INIT_PARAM => array('disallow_save' => true))
+    );
+    Mage::init($params, array('Mage_Core'));
 }
 Mage::app()->requireInstalledInstance();
 
 if (!$mediaDirectory) {
     $config = Mage_Core_Model_File_Storage::getScriptConfig();
-    $mediaDirectory = str_replace($publicDirectory, '', $config['media_directory']);
+    $mediaDirectory = str_replace(__DIR__, '', $config['media_directory']);
     $allowedResources = array_merge($allowedResources, $config['allowed_resources']);
 
     $relativeFilename = str_replace($mediaDirectory . '/', '', $pathInfo);
@@ -93,11 +91,11 @@ if (0 !== stripos($pathInfo, $mediaDirectory . '/')) {
 }
 
 try {
-    $databaseFileSotrage = Mage::getModel('Mage_Core_Model_File_Storage_Database');
-    $databaseFileSotrage->loadByFilename($relativeFilename);
+    $databaseFileStorage = Mage::getModel('Mage_Core_Model_File_Storage_Database');
+    $databaseFileStorage->loadByFilename($relativeFilename);
 } catch (Exception $e) {
 }
-if ($databaseFileSotrage->getId()) {
+if ($databaseFileStorage->getId()) {
     $directory = dirname($filePath);
     if (!is_dir($directory)) {
         mkdir($directory, 0777, true);
@@ -106,7 +104,7 @@ if ($databaseFileSotrage->getId()) {
     $fp = fopen($filePath, 'w');
     if (flock($fp, LOCK_EX | LOCK_NB)) {
         ftruncate($fp, 0);
-        fwrite($fp, $databaseFileSotrage->getContent());
+        fwrite($fp, $databaseFileStorage->getContent());
     }
     flock($fp, LOCK_UN);
     fclose($fp);
diff --git a/pub/index.php b/pub/index.php
index 64099054a49..15c5b4a4674 100644
--- a/pub/index.php
+++ b/pub/index.php
@@ -26,4 +26,7 @@
  * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-require __DIR__ . '/../index.php';
+require __DIR__ . '/../app/bootstrap.php';
+$params = $_SERVER;
+$params[Mage_Core_Model_App::INIT_OPTION_URIS][Mage_Core_Model_Dir::PUB] = '';
+Mage::run($params);
diff --git a/pub/lib/.htaccess b/pub/lib/.htaccess
new file mode 100644
index 00000000000..0932cbcce43
--- /dev/null
+++ b/pub/lib/.htaccess
@@ -0,0 +1,6 @@
+############################################
+## always send 404 on missing files
+
+<IfModule mod_rewrite.c>
+    RewriteEngine off
+</IfModule>
diff --git a/pub/lib/jquery/jstree/jquery.hotkeys.js b/pub/lib/jquery/jstree/jquery.hotkeys.js
new file mode 100644
index 00000000000..fbd71c71ec7
--- /dev/null
+++ b/pub/lib/jquery/jstree/jquery.hotkeys.js
@@ -0,0 +1,99 @@
+/*
+ * jQuery Hotkeys Plugin
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ *
+ * Based upon the plugin by Tzury Bar Yochay:
+ * http://github.com/tzuryby/hotkeys
+ *
+ * Original idea by:
+ * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
+*/
+
+(function(jQuery){
+	
+	jQuery.hotkeys = {
+		version: "0.8",
+
+		specialKeys: {
+			8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
+			20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
+			37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", 
+			96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
+			104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/", 
+			112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", 
+			120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta"
+		},
+	
+		shiftNums: {
+			"`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", 
+			"8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<", 
+			".": ">",  "/": "?",  "\\": "|"
+		}
+	};
+
+	function keyHandler( handleObj ) {
+		// Only care when a possible input has been specified
+		if ( typeof handleObj.data !== "string" ) {
+			return;
+		}
+		
+		var origHandler = handleObj.handler,
+			keys = handleObj.data.toLowerCase().split(" ");
+	
+		handleObj.handler = function( event ) {
+			// Don't fire in text-accepting inputs that we didn't directly bind to
+			if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
+				 event.target.type === "text") ) {
+				return;
+			}
+			
+			// Keypress represents characters, not special keys
+			var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ],
+				character = String.fromCharCode( event.which ).toLowerCase(),
+				key, modif = "", possible = {};
+
+			// check combinations (alt|ctrl|shift+anything)
+			if ( event.altKey && special !== "alt" ) {
+				modif += "alt+";
+			}
+
+			if ( event.ctrlKey && special !== "ctrl" ) {
+				modif += "ctrl+";
+			}
+			
+			// TODO: Need to make sure this works consistently across platforms
+			if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
+				modif += "meta+";
+			}
+
+			if ( event.shiftKey && special !== "shift" ) {
+				modif += "shift+";
+			}
+
+			if ( special ) {
+				possible[ modif + special ] = true;
+
+			} else {
+				possible[ modif + character ] = true;
+				possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
+
+				// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
+				if ( modif === "shift+" ) {
+					possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
+				}
+			}
+
+			for ( var i = 0, l = keys.length; i < l; i++ ) {
+				if ( possible[ keys[i] ] ) {
+					return origHandler.apply( this, arguments );
+				}
+			}
+		};
+	}
+
+	jQuery.each([ "keydown", "keyup", "keypress" ], function() {
+		jQuery.event.special[ this ] = { add: keyHandler };
+	});
+
+})( jQuery );
\ No newline at end of file
diff --git a/pub/lib/mage/adminhtml/grid.js b/pub/lib/mage/adminhtml/grid.js
index 1797ec04d87..9cc58f2012a 100644
--- a/pub/lib/mage/adminhtml/grid.js
+++ b/pub/lib/mage/adminhtml/grid.js
@@ -40,6 +40,7 @@ varienGrid.prototype = {
         this.initCallback = false;
         this.initRowCallback = false;
         this.doFilterCallback = false;
+        this.sortableUpdateCallback = false;
 
         this.reloadParams = false;
 
@@ -280,6 +281,22 @@ varienGrid.prototype = {
             Event.observe(dataElements[i], 'change', dataElements[i].setHasChanges.bind(dataElements[i]));
         }
     },
+    bindSortable: function(){
+        if (jQuery('#' + this.containerId).find('.ui-icon-grip-dotted-vertical').length) {
+            jQuery('#' + this.containerId).find('tbody').sortable({
+                axis: 'y',
+                handle: '.ui-icon-grip-dotted-vertical',
+                helper: function(event, ui) {
+                    ui.children().each(function() {
+                        jQuery(this).width(jQuery(this).width());
+                    });
+                    return ui;
+                },
+                update: this.sortableUpdateCallback ? this.sortableUpdateCallback : function(){},
+                tolerance: 'pointer'
+            });
+        }
+    },
     filterKeyPress:function (event) {
         if (event.keyCode == Event.KEY_RETURN) {
             this.doFilter();
diff --git a/pub/lib/mage/backend/action-link.js b/pub/lib/mage/backend/action-link.js
index 821c7d4c7cd..7fe481f9fc6 100644
--- a/pub/lib/mage/backend/action-link.js
+++ b/pub/lib/mage/backend/action-link.js
@@ -56,4 +56,4 @@
             });
         }
     });
-})(jQuery);
\ No newline at end of file
+})(jQuery);
diff --git a/pub/lib/mage/backend/multisuggest.js b/pub/lib/mage/backend/multisuggest.js
new file mode 100644
index 00000000000..9044d15df61
--- /dev/null
+++ b/pub/lib/mage/backend/multisuggest.js
@@ -0,0 +1,152 @@
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    mage
+ * @package     mage
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/*jshint jquery:true browser:true*/
+(function($) {
+    'use strict';
+    $.widget('mage.multisuggest', $.mage.suggest, {
+        /**
+         * @override
+         */
+        _create: function() {
+            this._super();
+            this.valueField.hide();
+        },
+
+        /**
+         * @override
+         */
+        _prepareValueField: function() {
+            this._super();
+            if (!this.options.valueField && this.options.selectedItems) {
+                $.each(this.options.selectedItems, $.proxy(function(i, item) {
+                    this._addOption(item);
+                }, this));
+            }
+        },
+
+        /**
+         * @override
+         */
+        _createValueField: function() {
+            return $('<select/>', {
+                type: 'hidden',
+                multiple: 'multiple'
+            });
+        },
+
+        /**
+         * @override
+         */
+        _selectItem: function() {
+            if (this.isDropdownShown() && this._focused) {
+                this._selectedItem = this._readItemData(this._focused);
+                if (this.valueField.find('option[value=' + this._selectedItem.id + ']').length) {
+                    this._selectedItem = this._nonSelectedItem;
+                }
+                if (this._selectedItem !== this._nonSelectedItem) {
+                    this._term = '';
+                    this._addOption(this._selectedItem);
+                }
+            }
+        },
+
+        /**
+         * Add selected item in to select options
+         * @param item
+         * @private
+         */
+        _addOption: function(item) {
+            this.valueField.append(
+                '<option value="' + item.id + '" selected="selected">' + item.label + '</option>'
+            );
+        },
+
+        /**
+         * Remove item from select options
+         * @param item
+         * @private
+         */
+        _removeOption: function(item) {
+            this.valueField.find('option[value=' + item.id + ']').remove();
+        },
+
+        /**
+         * @override
+         */
+        _hideDropdown: function() {
+            this._super();
+            this.element.val('');
+        }
+    });
+
+    $.widget('mage.multisuggest', $.mage.multisuggest, {
+        options: {
+            multiSuggestWrapper: '<ul class="category-selector-choices">' +
+                '<li class="category-selector-search-field"></li></ul>',
+            choiceTemplate: '<li class="category-selector-search-choice button"><div>${text}</div>' +
+                '<span class="category-selector-search-choice-close" tabindex="-1" ' +
+                'data-mage-init="{&quot;actionLink&quot;:{&quot;event&quot;:&quot;removeOption&quot;}}"></span></li>'
+        },
+
+        /**
+         * @override
+         */
+        _render: function() {
+            this._super();
+            this.element.wrap(this.options.multiSuggestWrapper);
+            this.elementWrapper = this.element.parent();
+            this.valueField.find('option').each($.proxy(function(i, option) {
+                option = $(option);
+                this._renderOption({id: option.val(), label: option.text()});
+            }, this));
+        },
+
+        /**
+         * @override
+         */
+        _selectItem: function() {
+            this._superApply(arguments);
+            if (this._selectedItem !== this._nonSelectedItem) {
+                this._renderOption(this._selectedItem);
+            }
+        },
+
+        /**
+         * Render visual element of selected item
+         * @param {Object} item - selected item
+         * @private
+         */
+        _renderOption: function(item) {
+            $.tmpl(this.options.choiceTemplate, {text: item.label})
+                .data(item)
+                .insertBefore(this.elementWrapper)
+                .trigger('contentUpdated')
+                .on('removeOption', $.proxy(function(e) {
+                    this._removeOption($(e.currentTarget).data());
+                    $(e.currentTarget).remove();
+                }, this));
+        }
+    });
+})(jQuery);
diff --git a/pub/lib/mage/backend/suggest.js b/pub/lib/mage/backend/suggest.js
index d4d7f2cdc55..bd099ce4338 100644
--- a/pub/lib/mage/backend/suggest.js
+++ b/pub/lib/mage/backend/suggest.js
@@ -40,23 +40,17 @@
             delay: 500,
             events: {},
             appendMethod: 'after',
-            control: 'menu',
             controls: {
-                menu: {
-                    selector: ':ui-menu',
-                    eventsMap: {
-                        focus: 'menufocus',
-                        blur: 'menublur',
-                        select: 'menuselect'
-                    }
+                selector: ':ui-menu, .jstree',
+                eventsMap: {
+                    focus: ['menufocus', 'hover_node'],
+                    blur: ['menublur', 'dehover_node'],
+                    select: ['menuselect', 'select_tree_node']
                 }
             },
-            wrapperAttributes: {
-                'class': 'mage-suggest'
-            },
-            attributes: {
-                'class': 'mage-suggest-dropdown'
-            }
+            className: null,
+            inputWrapper:'<div class="mage-suggest"><div class="mage-suggest-inner"></div></div>',
+            dropdownWrapper: '<div class="mage-suggest-dropdown"></div>'
         },
 
         /**
@@ -64,22 +58,57 @@
          * @private
          */
         _create: function() {
-            this._setTemplate();
             this._term = '';
-            this._selectedItem = {value: '', label: ''};
-            this.dropdown = $('<div/>', this.options.attributes).hide();
+            this._nonSelectedItem = {id: '', label: ''};
+            this._renderedContext = null;
+            this._selectedItem = this._nonSelectedItem;
+            this._control = this.options.controls || {};
+            this._setTemplate();
+            this._prepareValueField();
+            this._render();
+            this._bind();
+        },
+
+        /**
+         * Render base elemments for suggest component
+         * @private
+         */
+        _render: function() {
+            this.dropdown = $(this.options.dropdownWrapper).hide();
+            var wrapper = this.options.className ?
+                $(this.options.inputWrapper).addClass(this.options.className) :
+                $(this.options.inputWrapper);
             this.element
-                .wrap($('<div><div class="mage-suggest-inner"></div></div>')
-                .prop(this.options.wrapperAttributes))
+                .wrap(wrapper)
                 [this.options.appendMethod](this.dropdown)
                 .attr('autocomplete', 'off');
-            this.hiddenInput = $('<input/>', {
-                type: 'hidden',
-                name: this.element.attr('name')
-            }).insertBefore(this.element);
-            this.element.removeAttr('name');
-            this._control = this.options.controls[this.options.control] || {};
-            this._bind();
+        },
+
+        /**
+         * Define a field for storing item id (find in DOM or create a new one)
+         * @private
+         */
+        _prepareValueField: function() {
+            if (this.options.valueField) {
+                this.valueField = $(this.options.valueField);
+            } else {
+                this.valueField = this._createValueField()
+                    .insertBefore(this.element)
+                    .attr('name', this.element.attr('name'));
+                this.element.removeAttr('name');
+            }
+        },
+
+        /**
+         * Create value field which keeps a id for selected option
+         * can be overridden in descendants
+         * @return {jQuery}
+         * @private
+         */
+        _createValueField: function() {
+            return $('<input/>', {
+                type: 'hidden'
+            });
         },
 
         /**
@@ -87,11 +116,14 @@
          * @private
          */
         _destroy: function() {
-            this.element.removeAttr('autocomplete')
+            this.element
                 .unwrap()
-                .attr('name', this.hiddenInput.attr('name'));
+                .removeAttr('autocomplete');
+            if (!this.options.valueField) {
+                this.element.attr('name', this.valueField.attr('name'));
+                this.valueField.remove();
+            }
             this.dropdown.remove();
-            this.hiddenInput.remove();
             this._off(this.element, 'keydown keyup blur');
         },
 
@@ -110,7 +142,12 @@
          * @private
          */
         _proxyEvents: function(event) {
-            this.dropdown.find(this._control.selector).triggerHandler(event);
+            var fakeEvent = $.extend({}, $.Event(event.type), {
+                ctrlKey: event.ctrlKey,
+                keyCode: event.keyCode,
+                which: event.keyCode
+            });
+            this.dropdown.find(this._control.selector).trigger(fakeEvent);
         },
 
         /**
@@ -122,15 +159,12 @@
                 keydown: function(event) {
                     var keyCode = $.ui.keyCode;
                     switch (event.keyCode) {
-                        case keyCode.HOME:
-                        case keyCode.END:
                         case keyCode.PAGE_UP:
                         case keyCode.PAGE_DOWN:
                         case keyCode.UP:
                         case keyCode.DOWN:
-                        case keyCode.LEFT:
-                        case keyCode.RIGHT:
                             if (!event.shiftKey) {
+                                event.preventDefault();
                                 this._proxyEvents(event);
                             }
                             break;
@@ -190,43 +224,77 @@
          */
         _bindDropdown: function() {
             var events = {
-                click: this._selectItem,
+                click: function(e) {
+                    // prevent default browser's behavior of changing location by anchor href
+                    e.preventDefault();
+                },
                 mousedown: function(e) {
                     e.preventDefault();
                 }
             };
-            events[this._control.eventsMap.select] = this._selectItem;
-            events[this._control.eventsMap.focus] = function(e, ui) {
-                this.element.val(ui.item.text());
-            };
-            events[this._control.eventsMap.blur] = function() {
-                this.element.val(this._term);
-            };
+            $.each(this._control.eventsMap, $.proxy(function(suggestEvent, controlEvents) {
+                $.each(controlEvents, $.proxy(function(i, handlerName) {
+                    switch(suggestEvent) {
+                        case 'select' :
+                            events[handlerName] = this._selectItem;
+                            break;
+                        case 'focus' :
+                            events[handlerName] = this._focusItem;
+                            break;
+                        case 'blur' :
+                            events[handlerName] = this._blurItem;
+                            break;
+                    }
+                }, this));
+            }, this));
             this._on(this.dropdown, events);
         },
 
+        /**
+         * Handle focus event of options item
+         * @param {Object} e - event object
+         * @param {Object} option
+         * @private
+         */
+        _focusItem: function(e, option) {
+            this._focused = option.item;
+            this.element.val(this._readItemData(this._focused).label);
+        },
+
+        /**
+         * Handle blur event of options item
+         * @private
+         */
+        _blurItem: function() {
+            this._focused = null;
+            this.element.val(this._term);
+        },
+
         /**
          * Save selected item and hide dropdown
          * @private
          */
         _selectItem: function() {
-            var term = this._value();
-            if (this.isDropdownShown() && term) {
-                /**
-                 * @type {(Object|null)} - label+value object of selected item
-                 * @private
-                 */
-                this._selectedItem = $.grep(this._items, $.proxy(function(v) {
-                    return v.label === term;
-                }, this))[0] || {value: '', label: ''};
-                if (this._selectedItem.value) {
+            if (this.isDropdownShown() && this._focused) {
+                this._selectedItem = this._readItemData(this._focused);
+                if (this._selectedItem !== this._nonSelectedItem) {
                     this._term = this._selectedItem.label;
-                    this.hiddenInput.val(this._selectedItem.value);
+                    this.valueField.val(this._selectedItem.id);
                     this._hideDropdown();
                 }
             }
         },
 
+        /**
+         * Read option data from item element
+         * @param {Element} item
+         * @return {Object}
+         * @private
+         */
+        _readItemData: function(item) {
+            return item.data('suggestOption') || this._nonSelectedItem;
+        },
+
         /**
          * Check if dropdown is shown
          * @return {boolean}
@@ -251,6 +319,7 @@
          */
         _hideDropdown: function() {
             this.element.val(this._selectedItem.label);
+            this._renderedContext = null;
             this.dropdown.hide().empty();
         },
 
@@ -259,9 +328,12 @@
          * @private
          */
         _setTemplate: function() {
-            this.template = $(this.options.template).length ?
-                $(this.options.template).template() :
-                $.template('suggestTemplate', this.options.template);
+            this.templateName = 'suggest' + Math.random().toString(36).substr(2);
+            if ($(this.options.template).length) {
+                $(this.options.template).template(this.templateName);
+            } else {
+                $.template(this.templateName, this.options.template);
+            }
         },
 
         /**
@@ -275,8 +347,8 @@
                 if (term) {
                     this._search(term);
                 } else {
-                    this._selectedItem = {value: '', label: ''};
-                    this.hiddenInput.val(this._selectedItem.value);
+                    this._selectedItem = this._nonSelectedItem;
+                    this.valueField.val(this._selectedItem.id);
                 }
             }
         },
@@ -311,21 +383,28 @@
         _prepareDropdownContext: function(context) {
             return $.extend(context, {
                 items: this._items,
-                term: this._term
+                term: this._term,
+                optionData: function(item) {
+                    return 'data-suggest-option="' + JSON.stringify(item).replace(/"/g, '&quot;') + '"';
+                }
             });
         },
 
         /**
          * Render content of suggest's dropdown
-         * @param {Array} items - list of label+value objects
+         * @param {Array} items - list of label+id objects
          * @param {Object} context - template's context
          * @private
          */
         _renderDropdown: function(items, context) {
             this._items = items;
-            $.tmpl(this.template, this._prepareDropdownContext(context))
+            $.tmpl(this.templateName, this._prepareDropdownContext(context))
                 .appendTo(this.dropdown.empty());
-            this.dropdown.trigger('contentUpdated');
+            this.dropdown.trigger('contentUpdated')
+                .find(this._control.selector).on('focus', function(e) {
+                    e.preventDefault();
+                });
+            this._renderedContext = context;
             this._showDropdown();
         },
 
@@ -347,13 +426,19 @@
                     url: this.options.source,
                     type: 'POST',
                     dataType: 'json',
-                    data: {q: term},
-                    success: renderer,
-                    showLoader: true
+                    data: {name_part: term},
+                    success: renderer
                 }, this.options.ajaxOptions || {}));
             }
         },
 
+        _abortSearch: function() {
+            clearTimeout(this._searchTimeout);
+            if (this._xhr) {
+                this._xhr.abort();
+            }
+        },
+
         /**
          * Perform filtering in advance loaded items and returns search result
          * @param {Array} items - all available items
@@ -363,7 +448,7 @@
         filter: function(items, term) {
             var matcher = new RegExp(term, 'i');
             return $.grep(items, function(value) {
-                return matcher.test(value.label || value.value || value);
+                return matcher.test(value.label || value.id || value);
             });
         }
     });
@@ -371,10 +456,10 @@
     /**
      * Implements height prediction functionality to dropdown item
      */
-    $.widget('mage.suggest', $.mage.suggest, {
+    /*$.widget('mage.suggest', $.mage.suggest, {
         /**
          * Extension specific options
-         */
+         *//*
         options: {
             bottomMargin: 35
         },
@@ -382,7 +467,7 @@
         /**
          * @override
          * @private
-         */
+         *//*
         _renderDropdown: function() {
             this._superApply(arguments);
             this._recalculateDropdownHeight();
@@ -391,7 +476,7 @@
         /**
          * Recalculates height of dropdown and cut it if needed
          * @private
-         */
+         *//*
         _recalculateDropdownHeight: function() {
             var dropdown = this.dropdown.css('visibility', 'hidden'),
                 fromTop = dropdown.offset().top,
@@ -403,14 +488,14 @@
                 [isOverflowApplied ? 'addClass':'removeClass']('overflow-y')
                 .height(isOverflowApplied ? winHeight - fromTop - this.options.bottomMargin : '');
         }
-    });
+    });*/
 
     /**
      * Implement storing search history and display recent searches
      */
     $.widget('mage.suggest', $.mage.suggest, {
         options: {
-            showRecent: true,
+            showRecent: false,
             storageKey: 'suggest',
             storageLimit: 10
         },
@@ -437,13 +522,15 @@
          */
         _bind: function() {
             this._super();
-            this._on({
-                focus: function() {
-                    if (!this._value()) {
-                        this._renderDropdown(this._recentItems);
+            if (this.options.showRecent) {
+                this._on({
+                    focus: function() {
+                        if (!this._value()) {
+                            this._renderDropdown(this._recentItems);
+                        }
                     }
-                }
-            });
+                });
+            }
         },
 
         /**
@@ -451,12 +538,11 @@
          */
         search: function() {
             this._super();
-            if (!this._term) {
-                clearTimeout(this._searchTimeout);
-                if (this._xhr) {
-                    this._xhr.abort();
+            if (this.options.showRecent) {
+                if (!this._term) {
+                    this._abortSearch();
+                    this._renderDropdown(this._recentItems);
                 }
-                this._renderDropdown(this._recentItems);
             }
         },
 
@@ -465,20 +551,20 @@
          * @private
          */
         _selectItem: function() {
-            this._super();
-            if (this._selectedItem.value) {
+            this._superApply(arguments);
+            if (this._selectedItem.id && this.options.showRecent) {
                 this._addRecent(this._selectedItem);
             }
         },
 
         /**
          * Add selected item of search result into storage of recents
-         * @param {Object} item - label+value object
+         * @param {Object} item - label+id object
          * @private
          */
         _addRecent: function(item) {
             this._recentItems = $.grep(this._recentItems, function(obj){
-                return obj.value !== item.value;
+                return obj.id !== item.id;
             });
             this._recentItems.unshift(item);
             this._recentItems = this._recentItems.slice(0, this.options.storageLimit);
@@ -497,21 +583,47 @@
         _bind: function() {
             this._super();
             this._on(this.dropdown, {
-                showAll: function() {
-                    this._search('', {_allSown: true});
-                }
+                showAll: this._showAll
             });
         },
 
+        /**
+         *
+         * @private
+         */
+        _showAll: function() {
+            this._abortSearch();
+            if (!this._allItems) {
+                this._search('', {_allShown: true});
+            } else if (!this._renderedContext || !this._renderedContext._allShown) {
+                this._renderDropdown(this._allItems, {_allShown: true});
+            }
+        },
+
+        /**
+         * @override
+         * @param items
+         * @param context
+         * @private
+         */
+        _renderDropdown: function(items, context) {
+            this._superApply(arguments);
+            if (context && context._allShown && !this.allItems) {
+                this._allItems = this._items;
+            }
+        },
+
         /**
          * @override
          * @private
          */
         _prepareDropdownContext: function() {
             var context = this._superApply(arguments);
-            return $.extend(context, {allShown: function(){
-                return !!context._allSown;
-            }});
+            return $.extend(context, {
+                allShown: function(){
+                    return !!context._allShown;
+                }
+            });
         }
     });
 })(jQuery);
diff --git a/pub/lib/mage/backend/tree-suggest.js b/pub/lib/mage/backend/tree-suggest.js
new file mode 100644
index 00000000000..2153a696061
--- /dev/null
+++ b/pub/lib/mage/backend/tree-suggest.js
@@ -0,0 +1,169 @@
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    mage
+ * @package     mage
+ * @copyright   Copyright (c) 2013 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+/*jshint jquery:true browser:true*/
+(function($) {
+    'use strict';
+    $.extend(true, $, {
+        // @TODO: Move method 'treeToList' in file with utility functions
+        mage: {
+            treeToList: function(list, nodes, level, path) {
+                $.each(nodes, function() {
+                    list.push({
+                        label: this.label,
+                        id: this.id,
+                        level: level,
+                        item: this,
+                        path: path + this.label
+                    });
+                    if ('children' in this) {
+                        $.mage.treeToList(list, this.children, level + 1, path + this.label + ' / ' );
+                    }
+                });
+                return list;
+            }
+        }
+    });
+
+    var hover_node = $.jstree._instance.prototype.hover_node;
+    var dehover_node = $.jstree._instance.prototype.dehover_node;
+    var select_node = $.jstree._instance.prototype.select_node;
+    var init = $.jstree._instance.prototype.init;
+    $.extend(true, $.jstree._instance.prototype, {
+        /**
+         * @override
+         */
+        init: function() {
+            this.get_container()
+                .show()
+                .on('keydown', $.proxy(function(e) {
+                if (e.keyCode === $.ui.keyCode.ENTER) {
+                    var o = this.data.ui.hovered || this.data.ui.last_selected || -1;
+                    this.select_node(o, true);
+                }
+            }, this));
+            init.call(this);
+        },
+
+        /**
+         * @override
+         */
+        hover_node: function(obj) {
+            hover_node.apply(this, arguments);
+            obj = this._get_node(obj);
+            if (!obj.length) {
+                return false;
+            }
+            this.get_container().trigger('hover_node', [{item: obj.find('a:first')}]);
+        },
+
+        /**
+         * @override
+         */
+        dehover_node: function() {
+            dehover_node.call(this);
+            this.get_container().trigger('dehover_node');
+        },
+
+        /**
+         * @override
+         */
+        select_node: function(o) {
+            select_node.apply(this, arguments);
+            (o ? $(o) : this.data.ui.last_selected).trigger('select_tree_node');
+        }
+    });
+
+    $.widget('mage.treeSuggest', $.mage.multisuggest, {
+        /**
+         * @override
+         */
+        _bind: function() {
+            this._super();
+            this._on({
+                keydown: function(event) {
+                    var keyCode = $.ui.keyCode;
+                    switch (event.keyCode) {
+                        case keyCode.LEFT:
+                        case keyCode.RIGHT:
+                            if (this.isDropdownShown()) {
+                                event.preventDefault();
+                                this._proxyEvents(event);
+                            }
+                    }
+                }
+            });
+            this._on({
+                focus: function() {
+                    this.search();
+                }
+            });
+        },
+
+        /**
+         * @override
+         */
+        search: function() {
+            if (!this.options.showRecent && !this._value()) {
+                this._showAll();
+            } else {
+                this._super();
+            }
+        },
+
+        /**
+         * @override
+         */
+        _prepareDropdownContext: function() {
+            var context = this._superApply(arguments),
+                optionData = context.optionData,
+                templateName = this.templateName;
+                context.optionData = function(item) {
+                    item = $.extend({}, item);
+                    delete item.children;
+                    return optionData(item);
+                };
+            return $.extend(context, {
+                renderTreeLevel: function(children) {
+                    var _context = $.extend({}, this.data, {items: children, nested: true});
+                    return $('<div>').append($.tmpl(templateName, _context)).html();
+                }
+            });
+        },
+
+        /**
+         * @override
+         */
+        _renderDropdown: function(items, context) {
+            if(!context._allShown) {
+                items = this.filter($.mage.treeToList([], items, 0, ''), this._term);
+            }
+            var control = this.dropdown.find(this._control.selector);
+            if (control.length && control.hasClass('jstree')) {
+                control.jstree("destroy");
+            }
+            this._superApply([items, context]);
+        }
+    });
+})(jQuery);
diff --git a/pub/lib/mage/mage.js b/pub/lib/mage/mage.js
index a4ec587480f..bf6f6a56f73 100644
--- a/pub/lib/mage/mage.js
+++ b/pub/lib/mage/mage.js
@@ -23,18 +23,37 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 /*jshint eqnull:true browser:true jquery:true*/
-/*global head:true */
+/*global head:true console:true*/
 (function($) {
     "use strict";
     /**
-     * Main namespace for Magento extansions
+     * Store developer mode flag value
+     * @type {boolean}
+     * @private
+     */
+    var _isDevMode = false;
+
+    /**
+     * Main namespace for Magento extensions
      * @type {Object}
      */
-    $.mage = {};
+    $.mage = {
+        /**
+         * Setter and getter for developer mode flag
+         * @param {(undefined|boolean)} flag
+         * @return {boolean}
+         */
+        isDevMode: function(flag) {
+            if (typeof flag !== 'undefined') {
+                _isDevMode = !!flag;
+            }
+            return _isDevMode && typeof console !== 'undefined';
+        }
+    };
 })(jQuery);
 
 /**
- * Plugin mage and group of heplers for it
+ * Plugin mage and group of helpers for it
  */
 (function($) {
     "use strict";
@@ -44,9 +63,8 @@
      * @param {}
      * @return {Object}
      */
-    $.fn.mage = function() {
-        var name = arguments[0],
-            args = Array.prototype.slice.call(arguments, 1);
+    $.fn.mage = function(name) {
+        var args = Array.prototype.slice.call(arguments, 1);
         return this.each(function(){
             var inits = _getInitData(this);
             if (name) {
@@ -66,18 +84,30 @@
     /**
      * Execute initialization callback when all resources are loaded
      * @param {Array} args - list of resources
-     * @param {Function} handler - initialization callback
+     * @param {(Function|undefined)} handler - initialization callback
      * @private
      */
     function _onload(args, handler) {
-        args.push(handler);
-        head.js.apply(head, args);
+        args = $.grep(args, function(resource) {
+            var script = $('script[src="' + resource + '"]');
+            return !script.length || typeof script[0].onload === 'function';
+        });
+
+        if (typeof handler === 'function' && args.length) {
+            args.push(handler);
+        }
+
+        if (args.length) {
+            head.js.apply(head, args);
+        } else {
+            handler();
+        }
     }
 
     /**
      * Run initialization of a component
-     * @param {Object} init - setting for a component in format
-     *      {name: {string}[, options: {Object}][, args: {Array}][, resources: {Array}]}
+     * @param {String} name
+     * @param {Array} args
      * @private
      */
     function _initComponent(name, args) {
@@ -100,13 +130,13 @@
         }
         // Build an initialization handler
         var handler = $.proxy(function() {
-            this[init.name].apply(this, init.args);
+            if (typeof this[init.name] === 'function') {
+                this[init.name].apply(this, init.args);
+            } else if ($.mage.isDevMode()) {
+                console.error('Cannot initialize components "' + init.name + '"');
+            }
         }, $(this));
-        if (init.resources.length) {
-            _onload(init.resources, handler);
-        } else {
-            handler();
-        }
+        _onload(init.resources, handler);
     }
 
     /**
@@ -175,9 +205,9 @@
         /**
          * Declare a new component or several components at a time in the mage widget
          * @param {(string|Object)} component - name of component
-         *      or several componets with lists of required resources
+         *      or several components with lists of required resources
          *      {component1: {Array}, component2: {Array}}
-         * @param {(string|Array)} resources - URL of one resource or list of URLs
+         * @param {(string|Array)} component - URL of one resource or list of URLs
          * @return {Object} $.mage
          */
         component: function(component) {
@@ -192,7 +222,7 @@
         /**
          * Helper allows easily bind handler with component's initialisation
          * @param {string} component - name of a component
-         *      which initialization shold be customized
+         *      which initialization should be customized
          * @param {(string|Function)} selector [optional]- filter of component's elements
          *      or a handler function if selector is not defined
          * @param {Function} handler - handler function
@@ -213,14 +243,14 @@
 
         /**
          * Load all resource for certain component or several components
-         * @param {string} component - name of a component
+         * @param {String} component - name of a component
          *     (several components may be passed also as separate arguments)
          * @return {Object} $.mage
          */
-        load: function() {
+        load: function(component) {
             $.each(arguments, function(i, component) {
                 if (_resources[component] && _resources[component].length) {
-                    head.js.apply(head, _resources[component]);
+                    _onload(_resources[component]);
                 }
             });
             return this;
diff --git a/pub/lib/mage/validation.js b/pub/lib/mage/validation.js
index 8906c55a4af..5cb77cb5a6d 100644
--- a/pub/lib/mage/validation.js
+++ b/pub/lib/mage/validation.js
@@ -785,12 +785,6 @@
              },
             'Please select a file'
         ],
-        'validate-super-product-attributes': [
-            function(v) {
-                return (v !== "no-attributes");
-            },
-            'Please select one or more attributes.'
-        ],
         "validate-ajax-error": [
             function(v, element) {
                 element = $(element);
-- 
GitLab