diff --git a/.gitignore b/.gitignore
index ee2ae170cef66d49bd229bcd3cf590116044b43f..1f08e5627debd6fb4107eedb52fc085707a752fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,4 +29,3 @@ atlassian*
 /pub/media/customer/*
 /pub/media/downloadable/*
 /var/*
-
diff --git a/.htaccess b/.htaccess
index e02679d64faa95ecc9a9d2066479af1dea63bebf..0a28bdaf0303a310ed6612bcd1751c0b2bf5bdee 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 c8816df725678398c73accf37f340c2f903c0a3d..32e34eceb038f78b37f2774d60edce5e4f8ea082 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 6629187adfc32230e93d27b532762af0eeaf3ee2..02c46493940c31431cbebad64edd8a414ef9939e 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 22da0bd5b7a7099a2ea0af1a05365f33b7b1f2aa..bac5bf5a10db94474c246040d72c85776e8c69a7 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 0000000000000000000000000000000000000000..1f8e478523f14dcdebcf505beeb8ee548e969a5b
--- /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 0000000000000000000000000000000000000000..756f5d88845054892197f681b8a2c64ebfba5e8e
--- /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 0000000000000000000000000000000000000000..66f3f11a7d7eb801260d44bd6c8aff10bf12141c
--- /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 0000000000000000000000000000000000000000..0132077acd0ea95b666c8c07fe030c9460cd0e65
--- /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 0000000000000000000000000000000000000000..f220af82959b6037509f966a2f8884288dc145c4
--- /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 0000000000000000000000000000000000000000..f199067242dfefa4c6a4e7082c8c691ca2f64db8
--- /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 0000000000000000000000000000000000000000..ed57e4098fc58b58edabdb327f4a18ed216885dd
--- /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 0000000000000000000000000000000000000000..2acc4d1ec6983cf9fb98510ddd02b467bf55b751
--- /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 0000000000000000000000000000000000000000..bacf853a40378c57801380cdd9b7f2cd2fa8afaf
--- /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 0c005e426c6bc277eeff61ea36e839f0833f36f8..54f560c56e1f0cf0b61d83436880bf347cf8c216 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 0000000000000000000000000000000000000000..104e6a116b8dc906c04ed7c1358108c56f5f141e
--- /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 0000000000000000000000000000000000000000..ce33093e6136e75970a7d458f75e2cfb845f8671
--- /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 0000000000000000000000000000000000000000..4ef7f8cf40c5ff1305145f2df7c5ae755f4f5d59
--- /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 0000000000000000000000000000000000000000..3dddfc461779601082f176e51133fdea48613ab8
--- /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 0000000000000000000000000000000000000000..14851aa8436f29537e3ae038501f9c5d29f24cdd
--- /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 0000000000000000000000000000000000000000..0e635df67223bd36c8c47a4eeadafbe13c5e6f1d
--- /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 78ad8b75d2d0605b0112b5bfc9158ad240ec2ea5..00cb782c93b322d3fe7a700953f9a40433685a9a 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 586e53d870c7166f12bf5a1911b898a81be089d0..fae5ad7042fdc0177380e641bde97a07cba7817d 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 f23fc2bc472f7272b805503d6c83cc7e55589062..7724605a743323ec24b7ff304b0cbe4505be9775 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 bf7f14eafc80c57d65c4e598f20c9c2be493da12..0000000000000000000000000000000000000000
--- 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 223400b1163c739ee16e4a68e84102025d2da378..b94eff85227c3bafdd256c041a874d51465756b0 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 9cdbb7bb09efd359f62efd3e2c479c7ed076eb90..3bee6f60ffb272e7254c4853b43ae49d20f20198 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 c7d8b7fbc85ed93102665da9a7aa1067a90caad9..171985da8a1f5b055e1915d1ad804bc3a2a74ca8 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 b9b92e2584993b8f182066a21f17d769049c8b06..bb570115e480a8c2cf38016eebf02c677a8d1509 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 b8b99879cf5d112b9bbb6ead13c8304fabf3aa9a..7a011f5e6ff2ffdfc68c7c48cd04f6ee088b5a44 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 63927e368da695be2e489e34bdf706ccd93d515a..0000000000000000000000000000000000000000
--- 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 7f41c1c581d25954e6ce796b0a2fcaf40657c306..0000000000000000000000000000000000000000
--- 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 84d07a3a1da95d5fbf7ffce22e82a806b5999e76..0000000000000000000000000000000000000000
--- 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 db427839100a62b957771cf682e2570613976b77..c220ca7c6813347704636e138b5aa2304b2534ed 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 e478fdffe24375aa3d4ea25137397e0288411fea..7005c3ddbbce93d97ff9b2480d0d85388c4a06c5 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 2ea53cbc5694e7512a724405e9b5e3613258c4f9..547514f11c12d2f8423b393139e1d452cad1608a 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 06288f4a741dd2e603eb659bbee1bbc1c42c49c5..2b3c08e6335dd69537215df5c412bea6b08c58e3 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 9066114ea7e7d126176bc38749217c1752d50452..8e103aeca0c375c4f3000c0cae4029b51e3e3a46 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 3573522dc494739eb1aa9e49e0c8ab9b44d03e0b..0030bce0a1824986595fdaa88d17c82be9982227 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 b1305f7896741f54b2f33ed20665e9ced707e04f..fc4d93df92dfe1bd873f4806c26e82bb619661ca 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 d650589a44fe80b24593701b932cf835fd013f66..034f003835a62702f44722504261316a7b15c9af 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 649fbf39db9cceb2bc699931362f43a177be8d00..4fad233aa8588ab7c3adeb5b69d510a303ae590b 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 d29e500b04c452a62fa72fa051ef3522cd6111a7..f1e276eafe4c51fd60733fbde9502d6d38d6c668 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 1f6840ff29950e4dafd7ee24081f7851484fa11f..2ada9fa34bf25e98f877e715fcd532c12e9a889d 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 f28c0b5c32a18708df0edb3a639ac6f1066bfa9f..0000000000000000000000000000000000000000
--- 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 0000000000000000000000000000000000000000..8b5823da1a91cd3cf9bbbfe666eb7cd3d4769fa4
--- /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 0000000000000000000000000000000000000000..8c06e6269a9d960b1dc6503332df8fd77edef8ff
--- /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 52548bc6ee61aa037e85b686ce2e673aed73bc42..fa08d7763b7de81cc313d77f432810960c7dd309 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 0000000000000000000000000000000000000000..11fb8f6d2b0a67c707bcf779807af300b763e02a
--- /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 0000000000000000000000000000000000000000..1d64e04c55492201b5f6fc1e1e834c98ce4e5bea
--- /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 454f1534ae86932509a6112b50f96595e47cc658..422ad419ad8e002065c63eec1a8496bd6c973418 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 0000000000000000000000000000000000000000..03cc092e5390bd6f863a47bb29340b885c36fbbe
--- /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 d66d2b3fc0e92a6b4e90b40b0f4e9327350e8db5..38fd74195f7ce77a981353036bcb605a7a6a2c42 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 0000000000000000000000000000000000000000..a632e48c7bf0e5584040a43b49b4879ff64265ab
--- /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 0000000000000000000000000000000000000000..d1cafe10be58219eff2b48356ca9643f3953c22b
--- /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 d66d2b3fc0e92a6b4e90b40b0f4e9327350e8db5..ede0536cc52fb6c61173bfdf0cbe96cf9d629e35 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 ea6d1a6990891b67211eb82222760066296105c1..341c97801ef48c29ce433853b493f9067eb3185d 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 1b8f4f993b98b372a027aa35ac80105a6eb19b00..7a7050a6097223d64ba8a5d47d65207e9417039d 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 e5df89f39bd71ab46ff5b6e6433f4a0539b85235..ee4e2f5743ad98f1d1d4f8a2b31102278756b96f 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 a48249c31ddf87d7eca53b115d7241750f38477e..a9760647a36537427f60555c0687be6618339c8f 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 0f9f54be33f3f061cc057e2902cc6e015aaf882d..d12e65c82947f2766b5d15e36829ee0625c273c5 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 7b77b65c6a47e3583ba67df4085af68480dae47b..e1bf3bf7e7bb441bf64e63d42b84147753ad0671 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 5b8eb223ed8cc83ffa6c3bba7dac5efc9b38486b..3cd2bbdaa9eff6d74ca21daf7f4a6bada51054d3 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 e3a9e1837d74eaed07b339d4b258ad93e2e44942..c8ce55442660839cf8c75d27712a0c9c88086846 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 d01eefba207a42aae19c10adcc9488d0efa7a4ac..1f69e3ab83d0098be2fef3c2047d4ef6d70e725c 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 21fbab070863b35dcb89f99b2bbcc96f0fdad75c..b1ff06f43a5acb675fc9c16a53386130dad6b021 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 24ead0511beb7cf912ec94112f51a61223ff3520..3fb0020093cf11de659f924943d4954c82c6716d 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 313d4fe971f4b9690fc2d13400d391c065745bcb..ff9a18fb391ab377aa73cef8a7f03211f9a79464 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 d846a9742ed8e296591f6e0eab70cfbd53d5c945..c52ecf8b104c0df9f07ecdbc56ece97614e40f40 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 dbfd8971a105b1048f31439e2b0dfea34648a915..0000000000000000000000000000000000000000
--- 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 0000000000000000000000000000000000000000..e378d3e5a7324a3bc32112085ad337eb7a0824c8
--- /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 0000000000000000000000000000000000000000..e290bd268f82a2fbaef792d39facb16503632120
--- /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 0000000000000000000000000000000000000000..a7bd732c3de3a166fbc56c78e434c0fa9d025eb0
--- /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 0000000000000000000000000000000000000000..3fb69610582c56d9feb2e045a1c7c5efcb3640fb
--- /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 0000000000000000000000000000000000000000..e771e5e9874025df563e1b2eae7d6f2bdd2ba8d5
--- /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 0000000000000000000000000000000000000000..1a4bd2ff482444bbc63a87aa16a9f11ec92d2b8d
--- /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 0000000000000000000000000000000000000000..10d240d0f42fb0210d868739b77e29c63dc66ba2
--- /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 0000000000000000000000000000000000000000..c30cae453e22d866946889e65e3b42ca4449ad61
--- /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 0000000000000000000000000000000000000000..2da227383f12ce46230c9367c4effb5c637ef2f6
--- /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 0000000000000000000000000000000000000000..3833e18fd04b4ae64e0bd324cd7f8eb5fa6828fb
--- /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 0000000000000000000000000000000000000000..2abff6da50ec3bc3477fcad7bde54d20b7a25033
--- /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 0000000000000000000000000000000000000000..30573f5d8440953e0d92feef7db2ad5475b78126
--- /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 0000000000000000000000000000000000000000..afffbc50fd4134bb2129e502aae28800fadeb323
--- /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 0000000000000000000000000000000000000000..7cb39b0aa1ff78f6dea6c2a8907c3f7210857edf
--- /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 0000000000000000000000000000000000000000..9eb406b78b20ceae47fecf4ade20ae7269139e6c
--- /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 0000000000000000000000000000000000000000..b637787a41f67b9b6fe0b3363c5fb69d188dabc0
--- /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 0000000000000000000000000000000000000000..6a7e0154d92a98b71e0c32fb9c076eaaed3e7edf
--- /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 0000000000000000000000000000000000000000..7af32b391cf0a2558f0985b56c7c1b5986c08bbb
--- /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 0000000000000000000000000000000000000000..9676fe097a591e8b15b6a40ff2d34075fb31b111
--- /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 0000000000000000000000000000000000000000..b302d527928125d70a668fdd5f713703f7fded17
--- /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 0000000000000000000000000000000000000000..9349e9a6b9a7833bd3d229b401d7e75664546e9d
--- /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 0000000000000000000000000000000000000000..7756864fe32c1d34e0e4541e01c9a3071e347eea
--- /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 0000000000000000000000000000000000000000..9c13b1f73ea4397757a1352303ca2069bacd36d8
--- /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 0000000000000000000000000000000000000000..811d1cce262a0aca3fb6d700cb05c22fc4066a95
--- /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 0000000000000000000000000000000000000000..50459268f5ea01c54434dd83db958b09988a82d9
--- /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 0000000000000000000000000000000000000000..7363ffc260e2c78d604fc22af916b6273374c62d
--- /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 0000000000000000000000000000000000000000..6af4054c9843512741df0b22949171d683429231
--- /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 0000000000000000000000000000000000000000..fd3f412e84e178cc7317ebad7daf2a5bd2a9b7d2
--- /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 0000000000000000000000000000000000000000..b3859b94d1eabaf0e23135b688d20ab8c7026c18
--- /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 0000000000000000000000000000000000000000..58649ff834fdd51891c3302475186f4ef045b86a
--- /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 0000000000000000000000000000000000000000..d3d62dca2369c7fca84651d11c991c8421bc9818
--- /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 0000000000000000000000000000000000000000..376b016693e20cade86b4b81273af98cadd30d38
--- /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 0000000000000000000000000000000000000000..4cd286f41ea8abc3abb3fa97539a2ba64d9498eb
--- /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 0000000000000000000000000000000000000000..6552147c922cd139db3efbf6140adea3b018b878
--- /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 0000000000000000000000000000000000000000..d9dfae0fe6981643c319c901f9bea85ee07ee463
--- /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 0000000000000000000000000000000000000000..a3101d94f9f418718b2781cb495650ebaf345600
--- /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 0000000000000000000000000000000000000000..b9a5e525cd26de949572229d28b34f97aecb1308
--- /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 0000000000000000000000000000000000000000..3f251767854d2f8e69dee06e2d18331dcbe08541
--- /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 0000000000000000000000000000000000000000..12040ef47a9b3e69558f8b611653879b8b0544b5
--- /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 0000000000000000000000000000000000000000..56fe6649657debed4fe401c07aa44fbc263c6e2d
--- /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 0000000000000000000000000000000000000000..5e6fbb18d29415be9f86f194475fa853a8dd6577
--- /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 0000000000000000000000000000000000000000..2466831fc6984bf493932adff57a518c7a6c92c1
--- /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 0000000000000000000000000000000000000000..c7740c5e0a661dea751ff6ec51b256ddc28924a2
--- /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 0000000000000000000000000000000000000000..ece2e625063dc9dd44d27f855aaf7789723dd1b0
--- /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 0000000000000000000000000000000000000000..36495d74f3a5192af073c391c93f7de1559a72f5
--- /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 0000000000000000000000000000000000000000..5fa3bfab38660c61c69e402500360c324dc28e93
--- /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 0000000000000000000000000000000000000000..fd9fe0d5dd39f94c9a1528a3be89c9d1bb202da0
--- /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 0000000000000000000000000000000000000000..0db28ab286910254a2758db7cc5a3667ae41c0dd
--- /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 0000000000000000000000000000000000000000..4d060c6fd98dc54a245946723ed463b5dd8d9baa
--- /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 0000000000000000000000000000000000000000..5c6674a0d99c62b49c97d66c3609accc1f53483b
--- /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 0000000000000000000000000000000000000000..972a0ac704b2a9192ac1bbbb688d8f0340fa126a
--- /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 0000000000000000000000000000000000000000..9389383ef216978971b273187086083dd7e4262a
--- /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 0000000000000000000000000000000000000000..62570ad76ad788be83453e0ac0d8f3ad0957ff29
--- /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 0000000000000000000000000000000000000000..bebef0b86a0e41fb8a678aac9fec6f25fbf0afd0
--- /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 0000000000000000000000000000000000000000..9130432dcadc7662e30673ac84c18ed3e0e38d0a
--- /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 0000000000000000000000000000000000000000..d47e2af40010f20e8a803bd2276f02f355b9ea2b
--- /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 3d4d163fb864bed6fdfcae9d9f8098ed132ffbcb..6dda3399ee75abf845a4f2e335d370a3627ff24f 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 0000000000000000000000000000000000000000..c1a695ea5e592158251300ffc86be6dba0fc04c1
--- /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 e899dc9f8cb712c6b59a8eed6803e226491a237f..23f4d599cf74cf899110aebc055caa287f355a2d 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 481459bdd6775cc9ccdeef830c2f6fd56c342343..11437b020fdbff236d3a3ca3bb1251beeddf13f5 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 9248b2bde7451368c01c2b48f65f550ad4c6222b..513d5d98775ddf69b3a0ed9a69c3295fb301f76c 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 87d6c11fb5b0ab02f69d218e2cd855c3c3100a3d..1d2239516bb93a6633694bb89258dc56f45669c2 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 037b7de0a44b18acded42d661ad79320093f5bb2..6a532dcfcb457d2063375948cee882956089c478 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 d27d31ecbd80ca22b02245b4b85f32274cf1ede3..64386ce1b164efedd2667919ea466058c421cc44 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 e72e8eb0326fd7f6f2b4f703ac3f5c9368906a1e..edc23dd8c7b0e88fdb89ea02fb5f8afc604e4280 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 8bcdb7dcc50a8fa2a266f7d2b6cba9d69a797876..5a125de297a06141ffb1850c55c364e299644e7c 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 9429e122de3aa645aabd4072e6ffc9be8f40be8c..464ccd6377df0a9a8b9563e8698ef1333ca1c7e7 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 7c45a2c456f26dd50c62ed18f0ce98c011ba3901..5f9d1502f7dadcaf5e81b742d386777308c41733 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 8ffe8e654359cd6dc821798861c85579b412bfe8..d1255f361323aba6c28677197fe14f3cea184e37 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 378c20fafd0aedbd2d2eb5671d22067985087209..4b0eac884b1f9b982c0b9a4203dfe80ea11ce0f6 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 3d5d3b39490d9133cd1287235b9edf47c68c914f..cacd32d8e9921631a995cf6b8efe5b02911f993f 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 0000000000000000000000000000000000000000..51f6e5772d39df4df54ac53a389d361b5f3ef76f
--- /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 7d6cf0f49a86e2354d8e22825d8d6b3453695e5c..70b849f819b94156930f7ca9db17c79b315c9019 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 0000000000000000000000000000000000000000..9d6f8f9dc29e290b16dd88cc3bbdb271b9b81ac2
--- /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 43ff0f47db51bd33ab901fc9d59128497e8e8622..b5acc9dcc7b0dfcdf6aebc6cc2e9609cc18282ed 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 69edb6106b76a87cca0a7e1c29b0c1e1dcbaa8eb..40e83c96eeb321a607f8ab1ace4868bb8df6a4c9 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 fd7aef02d15c8024c41a03143fa289c80c62789d..2871c24a2c48f12b0d324fe4b9b92c61f17075c6 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 fade2e4deb145b6ffb0668deb38e52ff5923a039..dec72875b4ba8b9d8dc637fda407f56a2a6e8496 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 f102cb970320128a74e90d0155b16d5f6f5a08da..dbff31c365f00b1e57061a160922bf055b3d5027 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 db1ff39699d127526d1a8f0ed07ea706f2500ddb..9260fc85e3dfc2d3aa3936d56e5a404ff6555909 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 b8e4b8540baa080dd229c8ecc520a09d4e137842..dc44094df0c89833db02c1432703b9ffd094866e 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 3cfa4a58f23257d6f539535142a67770b077c178..21bc64d7c131be66f95ae106aa5cc2ac6f14ae58 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 a618e8245bc33e1cc0e81b076ddf63157810aeed..7cb28967d4efda3fb785154de323865de396a9cf 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 8936a2f809caaf3682599d02f91a1ae40e43d496..e8dbf667f01ef51edfb967dd3b08d386544f97a9 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 b3e679acf48064bbab6dcfaa7aa961fb42e044d0..fb88eb4faf6b3da14cb662d446236c0190717e10 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 482e8817b960ec220789c47b7e529daddf61d7cc..1aaacc3843dd8c53fb8a4f896563e61dda3e342d 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 0000000000000000000000000000000000000000..0ca525c5a28121ccc1558975d1ab237cd08ed440
--- /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 0000000000000000000000000000000000000000..c3decb6dbf3029a33df02d10fbe994cbd8efb833
--- /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 b2584771ca643733f80cbc859845ffa2be44070b..6b42eaef50749c1c3dc3124587609ffdf0b8f747 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 d5653c16673f9644db3f3b34dd794fda128fcdaf..7b02d320e23932dc66f46ddf035b5fc126da6ce2 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 9554a1729747cc4459adcd58706fbd013e5b5fa7..7295ff398a5a929cb9625a6dc9348da10bb27d2f 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 88ff45f13cd779599091c3852eb4d3a4d4b063c6..e3844c3d7bbba87d09433b9104134dd6ece10c00 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 27e7ce46814483633b7106ba592381a91752a633..04ad0b43ac1ee6adf6d0aa6724d285771f727b35 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 be91d72983cf9a817c1c35cc99e34728d9ba0adf..34131609db0ff2e1d12c9979677cb927e1750119 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 063e4862e1cec164768d8e14cf4927ce12cd9ac5..2d177c897376c29dbdac526920f0463ee74ca2a7 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 2603c37b5ef88c1f47cfed3d51b749a5cf138f71..9dfceb9e55efaa325f9c36d405d3323b55d42622 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 07562d12b8d198f6fd8106c908d69dd82dbecb21..410a83d0ec8e5602e4e6f93cb02d3985f27c2845 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 0000000000000000000000000000000000000000..e63a825b3d1a7c1a2333badd42389522959a4687
--- /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 0000000000000000000000000000000000000000..fe6f85d92290c7162b19c0b163a7610fbb8391d5
--- /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 0000000000000000000000000000000000000000..ef968559942253d01373fe86dc6359770a7609ae
--- /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 0000000000000000000000000000000000000000..261101ce0bc7b068e2bf1df11f2d0ef2168594a5
--- /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 0000000000000000000000000000000000000000..6a1179a77c06d556b553cd63b38c93a4481ed6e0
--- /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 0000000000000000000000000000000000000000..4aa133612a0e0dbb01092d8d119c330a3f0f2e69
--- /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 0000000000000000000000000000000000000000..771d370171f0be40f2a7989aa67ee33867875f2f
--- /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 1218dd955f85fe2fc669fb2076270b18ed84b31a..ba8fc9dbc790bf0e5cd8884e6a68a88606c9b156 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 4e6989b12f3b6cb34877a9fd68fb9a74a0c80116..1943108295d6056725ce6a127a412e1f016bd1ef 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 0000000000000000000000000000000000000000..cacdb4d57ca356f8b4abec74bacf838ab8cd878e
--- /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 0000000000000000000000000000000000000000..d74389daea7cfceebcf2f806d24a8bff32690412
--- /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 0000000000000000000000000000000000000000..53ca84511ff088d45e6123980fd1349e3342ccc4
--- /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 0000000000000000000000000000000000000000..b9098d6140834928d555671c10d62a51211e7857
--- /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 e4c946c177983e1502bc308258c894f57a38d166..c04904896e8b4516172561bbe9175c949b850035 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 0000000000000000000000000000000000000000..48665dc4ee0adf07500facb83f6faae9d777d994
--- /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 0000000000000000000000000000000000000000..35a1abaf46ef8319aafa80de737b0d77c9bd0220
--- /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 0000000000000000000000000000000000000000..66489bb9baf20d8b46edcffcdce55b6a4bd8358f
--- /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 0000000000000000000000000000000000000000..d3569545110aaa821c11fb1020edbccadbed6812
--- /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 0000000000000000000000000000000000000000..14e4080bbac00d438220d9e1c7539c52f9da9d47
--- /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 0000000000000000000000000000000000000000..1ac8113387509ce05f4cfd7440353c4a99e5cfb0
--- /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 0000000000000000000000000000000000000000..bee8a8ae90866d16f04571ea485a1b395e6909a8
--- /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 0000000000000000000000000000000000000000..d7a6717c2d6ec5a1620b4893f00964d035abf4b1
--- /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 0000000000000000000000000000000000000000..836a1273877c049251c711b6445864314a2a02d8
--- /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 0000000000000000000000000000000000000000..7078a21b21609277703ee08e5e78a75f9ff54640
--- /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 0000000000000000000000000000000000000000..5d8d0f4af1a3955fdbf2db3ae5a95ccf230f0491
--- /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 0000000000000000000000000000000000000000..44bc37a2ce85642bb16d36f2f923d4b9e907fa20
--- /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 0000000000000000000000000000000000000000..7413553be01bb227823a58cd93b288825e7d9ab9
--- /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 0000000000000000000000000000000000000000..99f91899ccf699f195ac454ac135299030514ce5
--- /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 0f96e0dbb3e6c81442665236d4ae1769d5d8b97a..1309196453742114b41a5ca566257a7971f8f94c 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 0000000000000000000000000000000000000000..ffd986fc589ab9a536fedd0d6c18562af74a8154
--- /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 0000000000000000000000000000000000000000..4034fb87856304b1267d0a0cd5eaa79489260e33
--- /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 0000000000000000000000000000000000000000..d0bd149e308d97c3c6408a5b69b3d9882a883ec1
--- /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 0000000000000000000000000000000000000000..22ea67baa3da3cde1439e9b48126201d0e7b8c4a
--- /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 0000000000000000000000000000000000000000..950855a5f0ac8f78e3222fa0a8a48b0a9627ac0f
--- /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 5707aed823d3ad368ffe9a0483c44d462d096332..63f6c4426ba5bac16b4822ddd72cb4e1feade63e 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 0000000000000000000000000000000000000000..65b13e5e5480a2a8421fb0abd82ad9fc90c467bf
--- /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 7e2c060b86fecfb4892532627c277d37b132bdc7..8061349713854ec9e1d3a4e526a995400cca0b2c 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 053a895321be1db065d348d64bd594d408d0bd9e..574a19efc85b21dda4cfc2bdad3cf215a11223f8 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 0000000000000000000000000000000000000000..b43852cb546ae2c6f465bda0e270629e61c0f4ab
--- /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 0000000000000000000000000000000000000000..54bc68c1b3212b8c1fe8c85964971bb807942e03
--- /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 0000000000000000000000000000000000000000..282d8192d20c7154a070561527682e3989e37bbf
--- /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 0000000000000000000000000000000000000000..6291e9cc039c808324dde7c81965c9368f8655b8
--- /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 0000000000000000000000000000000000000000..6812d85cb0547701931247ae6ab92bd75f4bda87
--- /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 19d2cc05b88f9e27ed2d56a35d0f1fd346ac3677..e5de26bf74316ed00aee547da12fb99e0910e4fa 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 0000000000000000000000000000000000000000..48c9b3784a361f2ac7f268c20512b9f5bc61d91b
--- /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 0000000000000000000000000000000000000000..34a314d3f6f8fcc9534eafb71c9d4e0e94680901
--- /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 0000000000000000000000000000000000000000..c46cc692935260a634e76a152d9e430cc13fce23
--- /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 0000000000000000000000000000000000000000..7eb79c58f64e6d4b739a1551ca12967c30f57863
--- /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 0000000000000000000000000000000000000000..0b964922b2c34f2c40b10006041ea4adefb36fcd
--- /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 0000000000000000000000000000000000000000..32d7ad1981c38b1183dd63916f67e1e729909cac
--- /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 0000000000000000000000000000000000000000..2867f6ec0431a9cf496c487707ad894d499e2f74
--- /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 0000000000000000000000000000000000000000..e5248395e02b7d1ff8829020e6ac3aac8fe45f2f
--- /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 0000000000000000000000000000000000000000..1069273cd3cbe3e13f21929b1c96f8f91a71f0fb
--- /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 0000000000000000000000000000000000000000..b26d0164dd6eee2264cab31f68f3b10b980373ca
--- /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 0000000000000000000000000000000000000000..b3be46c0cbc31feeaf8d592c4ddb80316741ae95
--- /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 0000000000000000000000000000000000000000..077c8c69e18a06b2aa4c860bd14ea9a2e34f7f81
--- /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 0000000000000000000000000000000000000000..2994c9f52389e2f3e1ded4251d3f71bc5c7f593d
--- /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 0000000000000000000000000000000000000000..cf31b878945a5999d62a2e3500a202f8020382f1
--- /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 0000000000000000000000000000000000000000..5d7058852f63bda30fe2d254f866b771a95c74d8
--- /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 0000000000000000000000000000000000000000..d3e73dab15a8e88482b2dd8876e76d8224d99df1
--- /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 0000000000000000000000000000000000000000..7102732f4ef8064ce4f527885b3c8f19baa2fba9
--- /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 0000000000000000000000000000000000000000..71c218acd9021264064fe0604f59ec14fa027284
--- /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 d9b871fbe09314a5ecd3bc53bf0fd60a15e481e8..a282b00c54a4a850ddb878fadfd8068908deb09a 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 abcd1c2839e2ccfcdc630bfddcc8c0537bad6b03..f9915a25832306ed68ed6394250235de7a3a7a93 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 69afaf06fbfe2d221907f8993d6f3e82456e6757..e7f6898aa722bc05201e25e0c83c497cb0ff79c3 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 88b5769ac0e373e0704e718c368c59f1feed1a26..33bd094732645e4783d8c04f4b45893b43abe7ea 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 3d16eea73032e9f7716b49f3592720a27d57f7c7..c68abf106657af6cfba41ab2f86cf3b5647115a6 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 f14298d53d5befdaf6ec47cedc901a5239cbaf55..cc761c071b5c9e1629ec17eda8dea1c775f328e2 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 f32493c6e69fcd08745c1584558c838c134d7141..523d5a5097229b335246fe5a64b95e3e44ce9a8d 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 eabc277684393a00b091b36d4cc7e54aed6f4823..aa38dca9352f83accf8311240b1b6d0ad6bb22f5 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 b1dd0f4178fdd8686c6173fe0cf61026c63c8a97..438c732d9ee9332492bc369bc430b483e8c7896b 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 960dc267a36c53f9076d44577e9fa1d0b6bf87f1..0000000000000000000000000000000000000000
--- 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 9104d3f6302e966d6f3ab7692ca7aeeb3b4132b0..217f503840b5dcdbc5a98c4a6e223b1fb4d38e7c 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 9ca5a3418cb996c5bb17df924d29258830b9decf..788c0ced7595eb42db7ec03a45924cf6494f88f7 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 216ad012cbf9e42ea176db792a800556c291c831..0000000000000000000000000000000000000000
--- 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 e35d351afc5afafb1fb10e243de20c299613df92..a12d50f48e5541c1609965c32104ae3748a0d610 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 68e23926eea963e90ae368c8d3ea2685b9b305ef..6d0ab0f4b39f378ed3db2bb07a0ba6c4b006cf33 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 4be237dd8639819780d115b27481aa8127b6ef57..97b7c23ad9b918943148ca5573231493be3bcfbb 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 0000000000000000000000000000000000000000..02d94af059f9f80d4b4a0ebfff40b5e4bdecb17c
--- /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 1e8f48b92e22328cd0d754e0cdc46cfa730f028a..2882f5c4111ad10fb4e36306105806341aba1902 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 3d6184ecd0997fedc79b89eb6de6c0fe23c81c6a..e9fdc1f5413a0c57a58653482c97893854fa8426 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 5cd7ef0d454755b800b917ad6539f7a9e6d89252..e168830d79f0702fc34e88b22cac3a8ebbd51f6c 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 e49727f60386ae93a6600f70c2ac79043c512ef4..324b874be1c78e11e15283792ee3455e71fc0efe 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 402828073ce9f202267dcc39a69ac6d57581742b..b3f1509a39672c7ec3c4ddb1bb27c38b3bd3fc8d 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 0000000000000000000000000000000000000000..fdb10b15f732c4ff862b6541370f37e74c83e4f7
--- /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 b6f8c24ac67bc308807d8ebf01d92797462c0876..84f9698af280bd3b1c7d71302346609fabd90c41 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 c848b029c9c191446f5e726a84e8e762ad22234f..2229101f412323d4d0806a65beb19ba2f6ffc725 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 a5fade2330f8c209b348b898b410289c81186938..87c2a644dc04a52346701c9d968cfea65733ed57 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 0000000000000000000000000000000000000000..5f125dc368a6bb741e827538a2b1b2dc56996e25
--- /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 6731c5639953c1cff174e58b7bd6ca6a7a199650..66dad5004106a878e8429800bbf2c743ba7742c2 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 f53b7712b0627fa951d4e7e1e9e8289369554f68..6b5bff23f59da9474dd91fe26aba96131ad7c74c 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 2bf939db1ee9e4eece8fadb7abfed55984c6806b..ab0f6e6484e81a53e82a44236f4604ac8277d863 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 4ba0e34826e0b340e400b359f51ee19467f7ad5d..5671f1504715ced2c5d39f028671553030b7ca53 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 9d77b139ace88b8e4ff6eb4ffa30b7a21e03161a..dbbd7e2bc11a6630d284906ed670be44971500a2 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 9b149871abb4dfce33b6f248a285e621e5235c8e..6d4f65d0c668789cb164de32ff2a7fc75aefe357 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 0000000000000000000000000000000000000000..648c653c8c9d44a34f345b7cb6b4e5e145fd887e
--- /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 7cfcd73d5cee12773255f506d976be6edac7f7d0..c93420ebf083785935fda18577171d527c3fbd7b 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 0000000000000000000000000000000000000000..8f3116b73f284e56afc606dc28181b2e8f867243
--- /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 0000000000000000000000000000000000000000..7e2b3b71557ff03904c7b6346420efebc878c86d
--- /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 0000000000000000000000000000000000000000..8ff9218547c39ae56a341dcd82bd809f4054110c
--- /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 0000000000000000000000000000000000000000..953c798b1e23f808a670fb0f01ea060e8b20199f
--- /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 0000000000000000000000000000000000000000..109181556b3f8eee22d1fea3166d14b1f21236e6
--- /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 0000000000000000000000000000000000000000..75469a0f3d3a9d953e7dada2aa8895811287a76d
--- /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 0000000000000000000000000000000000000000..bf85c7f144e99ee605bc0b8327e54b1930acf84e
--- /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 0000000000000000000000000000000000000000..a4ee0448257a2688342f5315cf8cf106414d6da5
--- /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 0000000000000000000000000000000000000000..13a3e260aef220b6e6db5c5ab794517f102a3e73
--- /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 0000000000000000000000000000000000000000..5a0522bfdc6600b730916cc6c85632b4313b2fde
--- /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 0000000000000000000000000000000000000000..133b88763966f26f4a91ca65cdfe2aee87abc164
--- /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 0000000000000000000000000000000000000000..abef413cafc44d055219580a1595c4604d89e2d7
--- /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 6bc9731cdb0d179cd78af50698ed2a9a63264f9e..13a588e6677938768e6f50d0a7d44ef346adcde9 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 3d50b570c6ffeaba2ab142ff36f7673ac0891f3a..a5ff2933c1bda0b92df5e01fbf0f0223e257f2f4 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 aba1c01d1d68e9a9deb18b8c61d147a7ad4bfa13..26bead77691ee5ab4165115ed1d9c1ac1d6aa434 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 a7de4a69673090633850cdbe5420cabc2f9429e8..0aa20e7f09eb312bb232115e736c1c13c762c9ea 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 af2bacc37bb564e7b4bf02576c38e82e14fca609..f402c76a0743e603fddb29e1cc1abc774f0575c9 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 1a5807cfc3d4d038d8b8efad400d2ec7616dc01c..e8e43fbaf459d0ce8a589902a6c2d5dfcf01d1b3 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 0000000000000000000000000000000000000000..6c8181f7f39591ad2b21ccb3afa9befca4f2b9f0
--- /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 0000000000000000000000000000000000000000..fa4330adadff0ad734c50f3fd116f3b74b8d84a8
--- /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 0000000000000000000000000000000000000000..9a27b5520812714131fe3be920e2fe21a8cd4133
--- /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 0000000000000000000000000000000000000000..21cb7e3750b799d61fcfc8f00ea35f28e46048d9
--- /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 0000000000000000000000000000000000000000..a51475857cb6306e99a470af2acc7dd2e100c2a7
--- /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 0000000000000000000000000000000000000000..5ace22429397ca334693a189d9465247e805a672
--- /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 0000000000000000000000000000000000000000..eca62b5d0cbd050761c81af2b389c9199329c569
--- /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 2b69a9385e4f85c4d5455b8d33b39eb917e7f806..d9ebf8ef1902fbdba89250a434bc0ba17cd995d4 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 0000000000000000000000000000000000000000..69d713b961e31ccd879a451891b78159f914bdd9
--- /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 0000000000000000000000000000000000000000..037577bfb4e4ff374d26a67c07f767332d14569e
--- /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 0000000000000000000000000000000000000000..d4ae42cc52030e1d3b3c5e7cd0252111a999685d
--- /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 0000000000000000000000000000000000000000..5ee342e6d175661b0098215a2607606d73861d66
--- /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 0000000000000000000000000000000000000000..7b9d2fe8d8ac56fb36739f7039e7ccd6e0802eaf
--- /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 0000000000000000000000000000000000000000..b463be954b204538fc2aea20471058543a29a52d
--- /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 0000000000000000000000000000000000000000..498eb427f3c4f82f34ca20e78805cdf45dd01d85
--- /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 0000000000000000000000000000000000000000..776dc6f7c12ab773effdfe6e4ba85368357ed04f
--- /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 0000000000000000000000000000000000000000..16fb55058c60df1849c8f42db977eb1d2d74bacd
--- /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 0000000000000000000000000000000000000000..fe1225eaca9708d159821237894d63b3906d5d47
--- /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 0000000000000000000000000000000000000000..9fd677d2cac069bc12d3fb493c5a14cf52bc143e
--- /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 0000000000000000000000000000000000000000..155d52646b593e66d09b48c8291db937494ecda4
--- /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 88033575fa80a3f8e63e6a06b76068af98ca848e..ead66fc53bf0692883f6456894369b8d6ab749d4 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 7226ecf950646ee60d3f7f9f84b0ac5d52fd8eee..c7f565c418988bbd5620843b00af3b98e63e94da 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 dc5a07c6b9d3f0618782772015ad6e4eebe6320a..9cf9de8f593c9bb728b2dbc75f6f54574e7ec877 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 66e9ee2a9c6da4d2e0aae198d52636c3994e131d..9df3af7dccf7b053489c1c5f8f6ea60086173b76 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 f90aef951207bf9b5b3a245d4998ebc180404e66..d73c915e0214c9d084e514bd7d2b5ebf6a81a658 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 00cd5f4a3e0e17c8a0e051e975d6ac496ae62edf..6ed540a871b1809f4e8d08a4942ed8da35d34441 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 2e24f56799f8813eefa0517cf80f8496356fe49a..3a39c9e8eb8d5bb9b28200efc359e3ee126475a0 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 fabfa65fb3cdb510049869ef444cc4b354f6204d..5287116ac352ae98d3e3ac45b3e0809809b41804 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 914195803d1df27b96a58b852b01d2805389087e..d8de080187c7edb9c9db29f35c5ccadf7a9f9f87 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 9d908286988549c3754dedd7d3f551c1beba3d26..6ed3afd47d2d95a453392fbff22fb166a650bc50 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 c37edd15ce2181fa15d9210e37d2b7b93ae39209..6b030c247e0bd9ba5097726a25716d375e0ef9d6 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 d00dadf8abf54f26008719fd3fc251553624405a..214572d9dcb4fd43db67bb037840f3461d334654 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 4ed93a7bdbd2a00e197997413894f4aaf073ca75..708c1d33b02bfeb6b800da5f6924c70ac1954f42 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 f3969e89c1a5ad4176e840942d93ea97c155aeef..695971337b8d39e332d17f7d7eaeb0f5e7a5ce0b 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 00dc3bf625efea5c580dc4c4cc6c94d9fd024ce7..05d5871fc5326d1e7bdf593d00d4f23f569c4ce2 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 8e21aa0cda05358df83800a7bdddf9eeee47232e..36e3543c40a9e5699f422c4b2deac70b25e81fad 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 169ab5552bbfcac8e36b42c6c6677fdc3fabf856..a81d1ee4f8916266a1c30692929e7787cc75a853 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 a89d872ed6c92ef0ca1650a166585a64940d659a..79da788a4f6836d1f77c95a7d0be302b50b7d837 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 3e7bab145dd346a6610a9c00dcc120ed3381e615..f2ed6c4c2fbfb85fad0df0f3f221323e155dfc21 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 d028b185ce0ad931a8d2dc42c92256c564adf9c0..ce0ab92157d9caa526803d87c44cc649a6a09a9b 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 78d86906d7e61bb977041dfdf4351d2f101567c7..f2b861e70e31ffa8fefade6d2d72c93863672119 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 9655fcfe5dc78a0c6b6637cacfcabf5a296cf9f1..4bc68dc0f746edb13c82781d43e8a5ad8aab63da 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 f0dff830307b7456473affbee29ac6bf0c896217..1ba306ce5d37a708da8391bc4f492a888ef2d825 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 4a4fba8c49931502521561477009b4192e6a75d6..37d94043d391c46fa01a9c66f5ae06dbec2db4bf 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 781eb5449555ccd8d1fc2735ed0a2c4af9647ff6..188f8eec750df9f1fd08d670ec85dd2c127ed10e 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 3088de94da134b347d0cc89b7c17b921f38377a1..bb35772e5035ffdcfd238aaeae3c45c6b40808cc 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 5c6bda09b2952076b862b6bf57a84b3df5f64a61..9647d2b8a60bb8242c20d14b8ccf3feabe5d0bbb 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 0000000000000000000000000000000000000000..179e32f83524652515c68e79d623b6f457358c8f
--- /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 6867c42c4c5619fce5f7e64cf985a85b517a3c18..a06cf6038199978d5575c97fae271648fbfe1e4d 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 0000000000000000000000000000000000000000..318a0f94ce19cb40faf2394d53dcfdc7371ef143
--- /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 0000000000000000000000000000000000000000..d3d84294cb439b247a6daad4532d74e25fa9792e
--- /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 0000000000000000000000000000000000000000..f79941ae3885e6013c9925efaed8c3357b580b0c
--- /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 0000000000000000000000000000000000000000..c8fc4fc6df3f3183ef4917ad520f799d02f2d442
--- /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 0000000000000000000000000000000000000000..8f2a97d57223efea84e80386a6de3245c1a90860
--- /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 0000000000000000000000000000000000000000..3694674b6610f765c03fb6279341501c14b240ce
--- /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 a7a0aaa8d104fee19a52a399aafdbdb255ef4c53..46e8b5bbb8fe8aae49f92d0d4c75cd3d64a55b35 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 0000000000000000000000000000000000000000..a7598a7de65e80664c96e73644a3f0d55fe28e14
--- /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 0000000000000000000000000000000000000000..dc6767e50a6e81444f042c66e72c43b2c720846f
--- /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 0000000000000000000000000000000000000000..24686784941e73902736efba4819a65a06df08ec
--- /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 0000000000000000000000000000000000000000..343e3330dd71e1832666203ef2218e0631f99ef6
--- /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 0000000000000000000000000000000000000000..0d697c86ce8655f8d1df3432501bd501315fc743
--- /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 c9a841d36f904c8d5adda10b29eb2c925c8194b3..85dff9eccc9a3d9d7af8372fafe81b178af16810 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 857a7fa270275b97061d864eb6a329d03fb7554d..b8e8837857492761ef0328f7f794e625ec462ab7 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 9b131ff2b87e47f968ecaf953c7581a7779aad69..355bb0961b45746a1b3dd51d6a0e6d9731a8332d 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 0000000000000000000000000000000000000000..b3d8d716ec0dddc1499ee16c62f7fc96a8fbe79a
--- /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 0000000000000000000000000000000000000000..756502479936596cc9671470144f7240fabb73c8
--- /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 0000000000000000000000000000000000000000..f8ca46a630d52eda7e6a8dccff8f312a32186bff
--- /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 0000000000000000000000000000000000000000..c7d114736c7e619cd3fced5dec2f2ec49caabb45
--- /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 0000000000000000000000000000000000000000..615e2a445837df5510209229f77d988c3c9491e4
--- /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 9d695ad4fa6225c5bb5bf2e9402c7ba729c7143b..e316a844e119e5c1b751688f16a6c146794a5157 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 af765b4529af600ccfba61589c666cab2d1746e0..fe1b3ff9af1fa3c8622dc21256c85a4a83380533 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 7ea5bd9ff7b0fd620789ea947ee01e74307cf6a0..4c07225d798ae4a5067ea2bd808737196c3f03ee 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 815036b8344e6647eeb5bb7f0145798babaa795e..4aeb73cbd80622f84d4a53b8cf420efe878796ef 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 0000000000000000000000000000000000000000..f5a73cfc61c6f5e789c283186a1aa7dafb444d15
--- /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 0000000000000000000000000000000000000000..e9b7ea94c9eab5ccac7c7b533cdaee883b1572f1
--- /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 94193c037006505fa4a78d1f5fc4b8c769543e2a..ffd5e5fb158382ebf8b24765708fb891a0e7d1ed 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 8d436e4afacca7b0a1fb31982b6f7addf399466a..9d4d196cb727a2bf91b1a578f4a7fafd6e64a808 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 46abbd72b0616060fb0689593a2cb31aa42505a1..bd5b9f0251ccd6e75d0bad28032deac14dc39d6f 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 773ee5dbcc42d1f9d8657f4371f49b7a575d58bb..48151e1e537b049a10c61ee70fbec2b730b88bef 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 2a8a0656e4e5414d4db454b4146af280728dffb7..08a954475529f808b794b3892f239949fb84d969 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 8e00c687cde1e33b49fea67bb844c983cb8e3577..2888d07c2c45d43dc369d11b36d7e6db69cf0a74 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 371559b7f950d85ffa207fcb4f38cca71344ea26..41d1d0494ebd9f95608705289c5aa02b25841880 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 31851fed1566e0387db5e1291e18710221f5804e..722a159f0d951310da31ed53b59f7af89235eb9b 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 b5edcd6425bd9401b0cfab34c4e7dd2b24605a47..56aabdf35c10620b92d8ac3d08287bb5429f4097 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 a8039c7eedea796abc7720956cc98c9da155de13..7ffde825c517b47b4df8e1235ed7ad2942ea2a4e 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 64bb74405a1d2bc783a9f9d4df8e0aa47d750ce8..a1a2aa47d84478024e3eb2ace03bb4b41c7495e2 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 c139217b918dde1117300fcd8d73672a9b1af118..5ed7ace1655bf2b8e871708e33c01c8b2530377f 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 864f6b1a3d1b651cbd76d60da98021922e33111c..6fe290683d711e5a7bac2f7cec957fc669396a69 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 5609192b5675c7c3fccd9bae0729d5d29019db94..f543e9163c5f293d87c1e42b12b435a50fbe286f 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 332a4fbc88cf4dd952706f473825e0b281f46914..0dbadc30ed3d2fbd884bb5b690fd5b48a408133f 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 73dab0d689d05ab33cdfd962b238971c6dc9ae79..d90be7a2f48072d08ade61b6aa72f82ce23c9322 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 47bd9a8d83ab42e0453c8a44f466033c927d5e3c..4529bcc78704671927d8da8cc4afba22b7f06226 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 5ddae74868555b685f96c422da3e8768c93d090f..549d2c85bdc0802ff93e2a893e8e8a35a76005d6 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 fb416de6960634fd1fce8eb481098ff326acccb1..924848848d27586194ac2cde9372d06e442054be 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 f383725f2b98ac2040ef15cdfe80a998ffead578..557cdf5c1da356c80e310ef3a98ae31a94a3b740 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 17e75d27f2c529e058202dd70d13088a0560866c..4e8be43ed80ca901046b56b7ba4d376ceb47806a 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 6f787cad3fc126cf879a75d89c8a438744d224d2..b79a7e56c2eaa69c8d2065c99c54db6354465593 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 0000000000000000000000000000000000000000..6789a751b05fe0d2cce577ceaffa4217487ad70f
--- /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 0000000000000000000000000000000000000000..4d7f0d86b80e1415ee2893eb6b8baf8b06869153
--- /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 2c049df6c16914d864fd7010ad3526fa23030095..e37a4cc610d43b17d018a3332befdb6f37096c3a 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 b63f1ab1f4e71547f1b8434732907c6b9c64ae71..e0e64a7dd36b442a062f6891ef41097313c5d2f0 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 0000000000000000000000000000000000000000..54c500ebe3bb97b3685a3942341899ef22f39fa3
--- /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 0c01547dde314e9eb0133d6f13cd1dc02284b160..e547eacb857f1966161e674e95cdc6f14b4eceda 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 cb26d2aa4f3f559f071bd1b0e46a1cb30e84a346..7ef528ffeb4122c60ecbbdf0910a86c0c179867c 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 2c783a3eecac069a86e6f924ae0ff8d910aeb88c..f6109a62ea5b18bd4c2d8885a98063c482a224b6 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 c5a1cd3e069103713489d323ede26e2406afa083..f4d542cd440108daa6212c00ebdeea1634dd3b5b 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 737f1c5ac1f39f8dd01470627a2ed25f8c3ad2e2..0000000000000000000000000000000000000000
--- 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 632e23019405ac76da85ee7079d9075cb49be401..6594b5b6c17e3077e8eae02da022375ac280492e 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 0000000000000000000000000000000000000000..aaf332100bb00afd47ad941f1b702699a3b9df6f
--- /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 0570d8d31f2cc61e683366064755ac4c9b72d865..5c02b9572fb6582ea5c831a77ca6233a11f46fc2 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 83598e82947ebdeb5e5a207217f3059874ae71bf..29decfe9f8b1707f957dec4c69ed51094f8e5258 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 eeba98de52d142662f9b11fa9dede61dfe5e6325..f08c99dcaac3eead0b21b59de700ddabbc3cb405 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 0000000000000000000000000000000000000000..7e87bc7e94cd309d5bd11941a155192d17fbdf65
--- /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 0000000000000000000000000000000000000000..36dba811686e650a88db7cb2495641d0711fbb40
--- /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 0000000000000000000000000000000000000000..5dcd7ad218b0f3e079e5cd5338a9c45159cb114f
--- /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 a5f14a8427fc970f28fa9cce56a1dc5a1e0a0478..783f03bf178fd3389078eff0f3c91207d5731c75 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 a0ae7015c79748c87878785d5930645ac4e0edc5..221196265c7016ec970ad02fc0dc9c9e9b3d774f 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 b7869eef1570c18a0fc0a354d0923578faa5f874..08d24895585a6b4ef57ab6227252d81f2b6a41bc 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 7efdbfcaa72f4028918ab459ae24eed676d368fc..9e13d09d73ea13cb44fcf73e5ac1f2a5a662519f 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 2062847df06f674b5831a8b4bd5fff7e589dd9b6..68a59d1bc2977dd41491d5096fc010ecdff7d931 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 153d70d33b9dc24fe0950b11bdb7a40ebf0c5dfa..597a28347ba537280683a90cb542a5a6aa32c87c 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 d6591f9808c0ebbf4ccb4da68e8d7db341a69f0b..11553a173b0645b282810cc9ced1593d86f633f2 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 966e1d28ae3bda47cb0f5645995d0d81b3e70105..7afde5b2fbce6892a9670d82a4c10b6ac888f215 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 0000000000000000000000000000000000000000..12d815266586f74ad871b616dccffa0c8e9deb81
--- /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 0000000000000000000000000000000000000000..400449e2146951d3a70aea11b10b72e328bb4db6
--- /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 b0191c39f97135550685d30cc9865460c9d2fbf1..e9faf4626c781be84c531819fccc15a3b03ed45e 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 3e0dfd76b43a2b400c79728f3fe6447e03dd191e..5ab09150d0c042b2919a22c6f4acac1abd0ed47b 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 0000000000000000000000000000000000000000..8907b50e2cc672c4058f6f471871a1af96fff2c0
--- /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 0000000000000000000000000000000000000000..6de32d1bfb7f2ed07342be92314893d31f9ec17f
--- /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 0000000000000000000000000000000000000000..786e21ab45f0b9daccaef8e9d89919cd1f9647c5
--- /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 0000000000000000000000000000000000000000..a9c6f18f57f3488f601c6beafc310ea13bc200d3
--- /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 356f3e4d4ee00aee310f16cfae62ea927a9dd06b..d3cd274b3531a5cbdab9ccfc9317f73f1d6c6589 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 0000000000000000000000000000000000000000..e2c450e66f48cbc176ff0162291b4c59268f32fd
--- /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 0000000000000000000000000000000000000000..fefe0d38dcb996d3e9b62fa1ab2615cf7968279b
--- /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 0000000000000000000000000000000000000000..2b40d6452140865b8351af6d702156dcaf49be12
--- /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 0000000000000000000000000000000000000000..0d0c49a9d8f6893f31b2deb1d6dc3be7c1eacb46
--- /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 0000000000000000000000000000000000000000..ceb45e7096c794318dc5a84db3d365fddf6fd5d1
--- /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 0000000000000000000000000000000000000000..ce268a4b1c8783f36439e10c0180938c737102c3
--- /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 0000000000000000000000000000000000000000..fa5c87197d356b8e837aa0e39473f1ac54c8f2ad
--- /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 0000000000000000000000000000000000000000..5865fbd43919a21e69deb932d704038afac4c9c1
--- /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 0000000000000000000000000000000000000000..82ac6d6629087bd71c9aa7311f471e5300973c2a
--- /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 0000000000000000000000000000000000000000..bfbd8bca2dbc25aa3c13e58d78e137abd74833f3
--- /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 0000000000000000000000000000000000000000..6d7cd6945c3ea0172630fcb72724e2c4b1caa6b9
--- /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 0000000000000000000000000000000000000000..bbee1550e1981ddd3956fe7ee4c7d220b96ce50c
--- /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 0000000000000000000000000000000000000000..b3c09c8ba1a1ee8d5187e7b1dd4d04357a41ed83
--- /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 4070e1621e48a312bb8658e05375138b5ca277aa..b834c5119e3a06c7c97d38b2cd30cb797f42e326 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 0000000000000000000000000000000000000000..5bf7d8d24edda497158b1f6b5b9920294f51e7bb
--- /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 0000000000000000000000000000000000000000..d703eba4c3a82d04c6c9bd032f6dcb97b98b1e31
--- /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 0000000000000000000000000000000000000000..62cd96c4b320800baf1174a99b372bc62b0133fa
--- /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 0000000000000000000000000000000000000000..53d97011fbb587a769f07045b5c9707db5436800
--- /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 0000000000000000000000000000000000000000..cf81d0703e94650f29f244332a64fcdfa08c2212
--- /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 0000000000000000000000000000000000000000..61dbcecbae6809164b56d88c6644f896b79e457a
--- /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 0000000000000000000000000000000000000000..a2aaa61c628aa8104ed030d00fb22d87028c2582
--- /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 0000000000000000000000000000000000000000..599c7468b4e51baa828353255a7e3feb622cc6bf
--- /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 0000000000000000000000000000000000000000..f969fbe530581957810b912af36bb86c868936dd
--- /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 0000000000000000000000000000000000000000..57b8ad59b14922df00da096afc32a6c2ff255f66
--- /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 0000000000000000000000000000000000000000..471627dbe2af3501c35980b8c378d3d05267ed99
--- /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 0000000000000000000000000000000000000000..1752cdc13f743095af9e68691666568d7bb9389a
--- /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 0000000000000000000000000000000000000000..591a77187d584d2267e24acd7531d983330f7351
--- /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 0000000000000000000000000000000000000000..599c7468b4e51baa828353255a7e3feb622cc6bf
--- /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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
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
Binary files /dev/null and b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/image.jpg differ
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
Binary files /dev/null and b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.bmp.jpg differ
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
Binary files /dev/null and b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.jpg.jpg differ
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 0000000000000000000000000000000000000000..da4a98d54c1071d6734712b1b906a52c74fe869b
--- /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
Binary files /dev/null and b/dev/tests/integration/testsuite/Mage/Catalog/Model/Product/Api/_files/_data/files/images/test.png.jpg differ
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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
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 0000000000000000000000000000000000000000..77e2760d43973af6e4a566c20e3ac6c4ee79236e
--- /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 0000000000000000000000000000000000000000..a08752ada3a514e8573a36fac36d022063aef562
--- /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 0000000000000000000000000000000000000000..c51ef75ab5ae50304d6aac6b7890bc70e0e5a383
--- /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 0000000000000000000000000000000000000000..2497818c49eac52cc8d08a03dc5c0d4881f40f5a
--- /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 0000000000000000000000000000000000000000..1a350b9be4c4223839d15a7fe2eaa9af58dbb637
--- /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 0000000000000000000000000000000000000000..8c0f08a63a77bf3e80f501d15668e26ed948f940
--- /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 0000000000000000000000000000000000000000..1264f891ed6df2886a21ce9b395a72e2344546c4
--- /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 0000000000000000000000000000000000000000..94849ef8abe46b3ec9670409e2ccdbff53845fab
--- /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 0000000000000000000000000000000000000000..b4d8961fd3a2a659d0769d5e846a2f0f898f6b08
--- /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 0000000000000000000000000000000000000000..3c8461c576b84af591c6b3cf439c5090497831e6
--- /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 0000000000000000000000000000000000000000..30b854f93b8d5c9c188d0b9b20126c03fa07968a
--- /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 0000000000000000000000000000000000000000..7ea2bb2b3320be13ac37934a08dc48b7901c9cbb
--- /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 0000000000000000000000000000000000000000..fb82f993d4adc5bc8b184d149d9bee71f65d105d
--- /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 0000000000000000000000000000000000000000..af79574338f0e9fb0f79e6f35c913814aa78bae1
--- /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 0000000000000000000000000000000000000000..00bcf6de816f18acf5760204cfe381feac7f8093
--- /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 0000000000000000000000000000000000000000..a6b4c2c580127e49b1268f35743065f0f83359b5
--- /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 0000000000000000000000000000000000000000..04a67f9466358999b90e4c269f36d92a2f5a3d5d
--- /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 0000000000000000000000000000000000000000..996e4cd2f346533e0a95333677d89ac20035a3b5
--- /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 9f405eecb9649bf7a4ad3be0d7277f5669dfea56..e07a5d6922175165f7ddc50031a3689ae7624663 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 0000000000000000000000000000000000000000..10dc22865f040e003baf98a45f5210ee6c1de761
--- /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 0000000000000000000000000000000000000000..fbcc8b53921aacd0d8ec0afff654f59c767c1f70
--- /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 0000000000000000000000000000000000000000..3bf9a21046f9d183358dde6d2e7f194c4be7bc3d
--- /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 0000000000000000000000000000000000000000..e02ee451fb47f6e20ad249d95e3436311c21e060
--- /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 0000000000000000000000000000000000000000..749d2262ea30612479d0a9d53500b7743c95667e
--- /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 0000000000000000000000000000000000000000..e5c70c11fc68f0096b5de034e88edec876fa7285
--- /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 0000000000000000000000000000000000000000..90663482448147af81027ed0f90beba863756634
--- /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 81b9e237d301bef0d1fe1d7bcc40a05a56e5e98b..1f3f62ecdfc0d92f8cde14cbea2b544657e06622 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 6d468eb3466d8f5cd0ca522624a756dd21e579fa..cfcb75336eb10b3a0f43803693ab6b4f06aefca0 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 3346813b313619e3d0efaafa6ea904932491bddd..a5321101b074955267b59f4dc5e8cfcb3f8847fa 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 118200afc08802ae3903ed4104579e59d51206e4..d79842026b3ca0061a29925269303548752e0662 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 3d1476a02be798fcd738df3b6b306c50655d4099..ea22b15b484610cc9f5b922381b362fbaac5ef94 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 0000000000000000000000000000000000000000..4b8a911376d45002672a2d2c4175a83ded55e9c6
--- /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 b45f3e28d304ca9589bee95279de18a6390245da..0b2b6941ca391a512d4328d4e3f2df3d06507451 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 0000000000000000000000000000000000000000..80f8debd833da6856ad3e1973861986f652f52d1
--- /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 0000000000000000000000000000000000000000..8f86488487d59bd02701c993f9a38812590aa1bf
--- /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 0000000000000000000000000000000000000000..52871420909974c753e372477ac4c01555e4f16a
--- /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 0000000000000000000000000000000000000000..89f3cbc743898a2cbd58a06898a7b2216a552eba
--- /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 0000000000000000000000000000000000000000..e26ed7e4e3a2c5ec34681fceba14d3d1ef6fb244
--- /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 0000000000000000000000000000000000000000..cbe942177e42d93bee9e23519a0dbe7da337d8b7
--- /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 0000000000000000000000000000000000000000..c637eb372375b38d4dc941b7648c2ba60ee5847c
--- /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 0000000000000000000000000000000000000000..d6167a2c0977d8e55ef7effd346cdd908fead08c
--- /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 0000000000000000000000000000000000000000..6fe060ac454a514021ba42dedfa9b84bc3e5e501
--- /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 0000000000000000000000000000000000000000..f22b6c2f60a1e6214c90b7f457bb3ab8939a6ff1
--- /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 0000000000000000000000000000000000000000..6ce6910e6602787a2674da7ca40d166be97afdbe
--- /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 0000000000000000000000000000000000000000..c8ebe691aff2dd6b9b09982c3a8d34440d7f2a9d
--- /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 0000000000000000000000000000000000000000..aa4ce46a90c27be195a8edc46a001f408dc96385
--- /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 0000000000000000000000000000000000000000..530f7f4f8a1f5ef66c64c7dbe8e667e0b1406977
--- /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 f08d18c79e0d2b60221d4c22cbc3c60daf0fa7e1..ee4e5738b19b522bc3fdd5a59075fefb14ca38bb 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 0000000000000000000000000000000000000000..f86f67588693ec2fa723018f9655f9d2307be226
--- /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 38f91035eb65ef2e26a2a5de7e4e967ca0193005..0b48561e6aef7a3effad27501857e5e12d0dc0cd 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 a35eadadb08311b3c14272e06dd9004f7c13808d..43508972b1fd9ac25fc037319707ed040e8a68c5 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 d467916cd9e2e2a0feb85a60187f844d1c5e783e..858e287fb0bed1c6d73620f7f94626d99ff99726 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 af7170b7de1e628a474b9bc4b3b56c1fcd9858c1..06d50829979541c8db0532d7c8d9c2b5f7a17505 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 9a9fbde137b208ba0131b4d3ea176332d09f10c7..0418d124ad5b6fab5fdd4eb2155d88e0067efc87 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 9eb4c5facdc47c58050dfdb12099317dff715110..1a8700ecedf0b66e9c855c7052a9049a04d2ffb5 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 394cd9a1e8ada2dcd7562b368676b1790097b1cf..ffa98abf3074625c50b1aaf896d4fdd0db9ce5e1 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 eb0b2b8c92a044aefab6c9562f27eb44d1eab90b..0000000000000000000000000000000000000000
--- 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 a61dbfb6cc720322f29c449708fb34c1ec518e70..77afd5eaad2eab42652fbfe1af09248f54cf679d 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 8241dc7adf884be4e3fd534ceec1e7e558db1d7f..27a6830eba6d25e173c2787a252338fc537e4e88 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 1b146602498a20825a99b2c2793bdc77e354205a..0970a81696f24fa885c5807d21c485b207aa56f8 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 66d9b67199d1629541a87f2cb76de34a11a52b34..09099bcc2ee2cd7b975d82cf82165924728d9954 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 e5eaf439f447cfeb6b6711381adef34b9f3db4da..f3d9e53f36070bc822cc5e3c12abc64c59937c21 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 47c25d82fffe6f673860a3ed818d30f16b26e2ad..d3ac6c4df5ba7d644565b5e8f6594bd5e027f598 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 4942ea526c7a27500046d05aa1c0cde46036930b..a910db073ebc46a3f2c713ce66776e7870c6a4da 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 a3722622e66d4142820f029019373047b38f319f..950d5ff288ecda7fd231f58c78bc4181e74fb7ec 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 ababfcca6e8077358bc99d8250785b8cebcca95f..1cbede5ed7b8b4fe97d7060688515fd378b06c94 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 0000000000000000000000000000000000000000..bfcc7910940f2d6aaa0f96a01b0c87eadae2d475
--- /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 8f8c2df0b0458b1a111ac33f594ff352e46e4ec2..004485100efcce685f776e8e67e59b37dd3d9daa 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 4472b384276fadb54f93d7f713afdf7c22b5ec00..0000000000000000000000000000000000000000
--- 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 0000000000000000000000000000000000000000..dd484b1a97dabc3a9e0de4cf7391ba845bcb4cf0
--- /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 c2b7f5503530d2bc1ea4eb932746636cf5a90b30..d3a8d537206aa657ce25a11e2b18753bdebe01b5 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 0000000000000000000000000000000000000000..15f69d4c7cb8dc20025e5fde50d31d1c79a0f5fd
--- /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 4d0332d312854036a7e1142a3f3bad730c13a29f..c50b12dedc47b8407f3a1d681c78f479ceb0ff15 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 0000000000000000000000000000000000000000..c72af0f9566e9d3e6a7a339e8f0bfabefef847be
--- /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 70967b43f7392a79985ab452c4fce96e9c9cdddf..96a086c6e78c584366479e98c8d14ca3bd013ec2 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 379a1b038cf964b1e39abf2120824d8f562970da..7504294c377a60db623089ca4840eb6d86511c50 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 7bde809519253c04e73e6c8751151207c6488214..cb8d54c4f7e0376911c40e4628137f12c4e89180 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 67b1d204fc8734772d8d9c6705ced0abfe7ae5fe..40cf31279d7658e0b2b30d566a72c20cd0ea2fa6 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 d2a16de7ec3bb9921eba0615479f4b1a37c69e11..3dcc3bdf304289e7345920aabbdda7ed3b692470 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 16875f3bfc6ae042bd916a311af3a51f7f6eeec8..54f6e843a717518f3366dfc357274c4078e4c965 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 992c4c873b3b2dc4d756fe5d8408072c8ca1d99d..708bcd7549e082aed28351a8b9172b04c9c74f95 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 0000000000000000000000000000000000000000..c0082d1d77e3d4c435322ec40756e39180833177
--- /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 781197f9e2a865e8747c0b1d1acd8ac9164b9a18..cdbf362522a5bd33d02d7b2fbfe11b2da507432d 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 0000000000000000000000000000000000000000..1e6ae71360a51e5f2aa589e0fc4583c03db38c4e
--- /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 0000000000000000000000000000000000000000..29b414bb28c3644ec1ef92e56d52ca0649609839
--- /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 0000000000000000000000000000000000000000..d49fd067c168a83d5db5ef6012fce5bf00097f5f
--- /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 0000000000000000000000000000000000000000..97d3821ee0f1816cf2e49c8d45667a55414a7c10
--- /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 0000000000000000000000000000000000000000..a266b64bb1a0f0a1205623e2b604db0ec991bb21
--- /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 1430dc32c059e5c8ea20f258ce64f5f300ce3302..c5e0fc2dd491a5638b8646b62d7f3b346df9600f 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 0000000000000000000000000000000000000000..fcf3c2319cd0ff682eb68e0e44c0fb18276dfa22
--- /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 0000000000000000000000000000000000000000..272df53b9544d96884a17939ecd9f88ec49c7264
--- /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 0000000000000000000000000000000000000000..f8b7252018b432eaf1886ddd2267184108ac55e6
--- /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 648546d88c13eabd7b4d4daeed15542367584c14..0024fd3d4e9498f1b1a0421b6fe0274fc3d62a97 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 0000000000000000000000000000000000000000..50aa2e0b0e43c676625a41f173074f9e086e419c
--- /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 0000000000000000000000000000000000000000..349d77c0c34a34c1f1963859aa4957edab59c3b4
--- /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 0000000000000000000000000000000000000000..2fc0f35048b0475887eb2022d4c179fb9e3a1430
--- /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 0000000000000000000000000000000000000000..65244c241ba13b9479af27811107698965a225f1
--- /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 0000000000000000000000000000000000000000..acae298c2514cf5110ab3c7497ea2e53882fde88
--- /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 0000000000000000000000000000000000000000..8e26cf42f4c095d8b012f13bd17daf2f34fe5571
--- /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 0000000000000000000000000000000000000000..361a8bb63fc5bee0c3bce7a9154e5e838f9c4280
--- /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 0000000000000000000000000000000000000000..b8c63968053975189456e2ffcad7229a15eeb959
--- /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 0000000000000000000000000000000000000000..7dc8ed80e2291177e322e91f43f10edaedf2faa2
--- /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 648546d88c13eabd7b4d4daeed15542367584c14..d0dbcd3f5386209b3daa19d8a47806217ae7cff1 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 0000000000000000000000000000000000000000..12bcb4b28dd01cda2ef6c8d7bf4fbe7029ac20cb
--- /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 ddf145258c08fa65f3946587ad703b18d860b2ea..c6d0fea06022dbc10571340233bc541a6477b053 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 ef72118fde4a9bea5a5977d86365d72205f5d315..d01f67dedc6e6507669bf57a57ec1570959d9646 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 64c1d4b50d43ef8f9212ae647d893fb5f74680fc..9a1523b665f9ee97b5daa801ce038cd8f06fc20e 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 27130671a08eb068275df07ca500839a45dabe2c..12376c1e65300f0847c125bb3d5e2268bed63ea4 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 0000000000000000000000000000000000000000..d0dbcd3f5386209b3daa19d8a47806217ae7cff1
--- /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 1430dc32c059e5c8ea20f258ce64f5f300ce3302..0000000000000000000000000000000000000000
--- 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 4829969301fc4709e7e1e7913e6e96d6b521238c..0000000000000000000000000000000000000000
--- 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 90693d68ad3d55dd32cc5d02281779fb55d7208a..0000000000000000000000000000000000000000
--- 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 28f449b2d6eb703b071d2bc1fbb6c6b7b56b4e56..0000000000000000000000000000000000000000
--- 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 ec8e60fa7cc2d9e4dfd6389cf6b1a93115a2ef0c..a658ac04edd84123ebaead65715d739a49694def 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 0000000000000000000000000000000000000000..ba8bf37418ab15bf4c8d3c419453572888d3bcf4
--- /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 0000000000000000000000000000000000000000..1531f1a021dea37519dcd8f13b8fbfbf6dff5464
--- /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 0000000000000000000000000000000000000000..b07e4f8c085ff753f47938042f1bca1b86ad3723
--- /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 0000000000000000000000000000000000000000..1c89ba13d656869b9cedbcc5ad4623f1fbf78e9d
--- /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 0202e67f88a1a544343f759b409f5a1ce45a7db1..f48cb6ec0e956c4420cebf1e2e517787695d41db 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 e25d22008eafbb728ad9717a50cbbdc38b84a880..f442029147d10748d65da06511a21f3eccc32d48 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 0000000000000000000000000000000000000000..85194571644615624e88c2648a041926ed357dd9
--- /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 0000000000000000000000000000000000000000..89f8dcef17ab1e2d899b096c1e74a9999092ec33
--- /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 0000000000000000000000000000000000000000..906da30f39df8a5b9d8f003ad7a49097102bca48
--- /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 17bb6ebd4da974e8c0210157fddea8975ad6649b..477d27ce120df2c01d53afa1fb5b801a8fccae75 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 0000000000000000000000000000000000000000..24de10e28aecf211053b56a20ebf012c9f7ff80a
--- /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 90f3cd1da10425cc9523ac736f1f3851f787c162..ab1f0ee49fe7943043d0799e23baa827b8e4d6d3 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 3c993f0710d24e5cc7c463e9f744ae50bc1e291a..e786cfb11390c5e8206b0f2e993d9e45b7caf385 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 0000000000000000000000000000000000000000..f731b954c248f00e2c1170531d3b33503c204983
--- /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 0000000000000000000000000000000000000000..fe5a40f947f2307751f2677b8b89be07b053f4bf
--- /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 aaae218c7ed66c0f1d575e5e7243df5764b58cc2..bc7771d6842e53abb79b96b4199ddbbc2c494bb0 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 8fb652ca4c2f7a9161a2c577fffca8bb56f45660..6cbb315ac0ee1d9066e499639aaabd434315db78 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 0000000000000000000000000000000000000000..7eda712c0f0ff47f45aa8268db9482cd0d1b34ed
--- /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 0000000000000000000000000000000000000000..d2729f76afda2944702121c783337edc160c3d8e
--- /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 0000000000000000000000000000000000000000..1420b3057a19c38b3fe381ab7eea90f6b2803477
--- /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 0000000000000000000000000000000000000000..97cded705ab685a87fafd262f7f3d6256af1b1bf
--- /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 0000000000000000000000000000000000000000..0b0a82e14d6dbb1b7546b95497144685978ecfb0
--- /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 0000000000000000000000000000000000000000..a48ea09a9081413c55dcd573c6719cd08aa2fc3e
--- /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 0000000000000000000000000000000000000000..524f94394516b68ef4d11d6fdabe7679f612388d
--- /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 0000000000000000000000000000000000000000..f84998f168a35abeffe610490ba8799e83e0ab99
--- /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 0000000000000000000000000000000000000000..b2ff2ba6d1898091db1c53b9e6bd264f218e60da
--- /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 0000000000000000000000000000000000000000..04a70899b26e0b1e26417bfb911cb700cad24c42
--- /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 0000000000000000000000000000000000000000..e2696eca8f9289fc93b6aa157f831e677cac1589
--- /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 0000000000000000000000000000000000000000..de2ce774043e6f512c181c491223521af10c6951
--- /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 0000000000000000000000000000000000000000..b34f865fafd4f4e12fa7440a6363036281b3f8c2
--- /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 0000000000000000000000000000000000000000..01041a2778004eb3620686ff5b32a9e8597759ab
--- /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 0000000000000000000000000000000000000000..cc17167bae144d9a4ac9521131e7948427ede209
--- /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 0000000000000000000000000000000000000000..ad6bd240bc576aeac5052d42fc29917cfdce2f78
--- /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 0000000000000000000000000000000000000000..16074db5ed9875da7054910ee132a43f2510e4c3
--- /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 0000000000000000000000000000000000000000..87d6411318aa2ac6f244d5c1d28ca7a44bcda77f
--- /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 0000000000000000000000000000000000000000..c3ed61fe52afb63414bd16816ae8d70f40283b7d
--- /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 a061b1a909a28eb72eb92609e8105d6a0ca70150..98c69769eb8c6769f793cd9cd3a253978c9278e0 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 0000000000000000000000000000000000000000..c6da08418baf925da4a6dbe58531aa0e39be8425
--- /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 d3e741bb3e8285aa3ea90323788801c7a48db205..f0e82db4d90595f6a5b196adb521d9a42b3ddcb0 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 3ac5092563125b50ff1187b2260c9f22a922bce7..22171182e7ac69ac3a928739600b3fd512cea5b4 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 0000000000000000000000000000000000000000..f6e72eef0568087b1659d6a0bbbe412cc3fb8c9f
--- /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 f1a5823b9f59c01953ac6bcf4408e32e0382a997..e86b076a52cee8e3e446f95fa86fdf1ed74fc126 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 0000000000000000000000000000000000000000..70881cf68c4e68aa9864184416db6bc1908f1169
--- /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 0000000000000000000000000000000000000000..a38c3eef184cc6cb937fee8c2a24d46833ce0fc2
--- /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 25460f62ab057979cd23c4c9a5a3660b40c7b7ee..30bd4bd363c34763531899e124f72a8d09a8636a 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 122fbb88acd12c162c7f6110b3d375ae527dacfd..efac2a414ea5f323f417e53acfdf39ffba57ed51 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 0000000000000000000000000000000000000000..e91c9feedfbaa5e2482ec8202dd52d4985ad348a
--- /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 0000000000000000000000000000000000000000..9312b2493b01b098749f44cd2f0ea149b13e0896
--- /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 0000000000000000000000000000000000000000..552e6cf4f5755b97d73c09ca100570a21e92a544
--- /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 e8d011c797ff21b0b84cdfe8c7d74ac8afefd2d4..4422ea3538490f91027ef278dfa828872ab781d1 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 a3b86fa4304c73edab3608ee0b85a44f19310532..4cecb1c70a6b14b7fe87bb51ecc646833d8b4f87 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 0efee579d1c9673acb99d8464ea56127245cb941..4af05990574bb0ac30cdc669973e2220dbc61db9 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 d392f5f7bb76374cc1ee69b2883490615308e3fd..76d918f3ea21d0a3f36e42207e40af13ce8de232 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 aa29ac04c837d3132930f4708e2bcdd906bda4b2..d2c222801abf62770169f79fbd9d8f79110bf976 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 ac50ebd6857b5e3f4abcaf9d1d11d8933f9a0a06..0df9ce33c94dc7d38e59dc074ec8b0236c933096 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 c582c9d0053b022bda1b071bde3e00f2bd318eaf..d07cb7f778c659af01f6850affa29347e12a54c8 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 4179520f747a6693da5f859d45a02bf2165b4e3c..a98babbaa951be7917d0779fa25ec2b07e36304f 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 5b9399fefa759fe1e0a9acaf14339fe7380cd961..049cb051766e816358bd539cdeb9e8ddb2d8d733 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 dd878c4534ec47649f8fe112edf2acff233889ba..6def23b3b88cf3bb5aa70803731cbd9f53c56c8a 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 76a426447fac18310b2cea84d400a25197943603..a491dd257cee71e20ae5bfac86f6a7f7db401e32 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 ffbc421e4029f3bcba56cf567543cbfb837b4e08..b10fb7f3cd0ca1d9008b6ab227b1f5caafc8c923 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 c5cc69f88ae9574b01dd1f0e8e7abcfb14b99345..c347ebb66c554f79cf5d2f3b5e6d6eae7e9f44cd 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 a3abc195eed4365cf96971c5220a1a360925873d..5f88e81087a91bd7b60004dce3ffce4a47fe9c5e 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 a6e389e4a63621e460ac1f9881d8e6f18caaddfb..473e39df3923932e113eed560e7855ebb1c2f621 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 c2ea7457eec8aa53e9f02d1ea36c5c9fe07fec10..b6c65bcf2e0366333ac97a8e89002f9ef6cdbf69 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 07d0d2e50dfe7394b3a0c9766730c1d6c1eaa9ee..a53f1e51f91a9135321225288372a8a2eec22461 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 93d8aa38aef357168c8235472fa8df0072f1e57f..d40957ab062a77754807e04b2bb304367f67a23f 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 c01442b937f76aa4d4295c2ce9d319fd23734dc3..d16419e7e657cb4323ba4ed4f4a0ec66315c6213 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 35863f1542b03f452636ad6535c13039c7d2d3f4..032f01ae7fc659922dc10d65a0a12d189121bf67 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 df1184f2a082f9df2229353d3239dbca9bf3ee94..112cfe7bb6e209713283cb6d299c74a92099cc9e 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 928bfe7f8bdc9702b2614818e47837798c886725..091d243b9f303d2df5fbf9b0f7b298f077a2d9a3 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 c19be66f84189f4ae0378dcbcb494942eae766e6..552532e7a0cc17b0d2eeb76cc30975265758407a 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 d0ea0828715e502c2e7ba82c0ffe0a5ae7081904..ce5da5bc2ed1f946f332278c29261a9dda3e423c 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 116005c9984df3ff266c1b8e36c46d7a63b32f3e..822511c2dd381f9c39a622255cb2ee370e27a3db 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 d9183b141a6b3a57a8cdd54d1094a6c4e1807e9d..50267f1e169bb905d8957cc9958f0fdddea06703 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 7d542a29406f5a929be62488f0194be434275651..e41d59948141f3038bdec3473928d3a4f3a27e98 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 d0da23c5f475c1011a86497d8cd3f53848c49162..69557f436f0142c309c6fadb0063e87ac381cd1a 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 99c823a51f7905520792e12ac8462aae01dd2029..29c7ed4e2108135167a510bf72027cffc5d47aea 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 f9fc68ea3f1f4abd8795a39f6aee4e91a8ed0ca1..3c010c776938f914afc413d6818fcc5c7000051e 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 2eeb636d0f019e9c52133d6e46354d1e76b33df9..320154f5bff2deb52dbbdbd42350fc20123796e5 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 4d73f963e32585a78b44c3a05a2827980b9b8d0e..819215a9309c3a7723079a104443afb461726c3e 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 0000000000000000000000000000000000000000..947fbd4ff83f9966271af3070eb7b194f90baf3d
--- /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 95a608042c314115f2de5985d08d1b62fcdf9762..d2ff23e03d88591789f053330bbe0c46a15ea5b2 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 971b60ea01e52a6e5602c7c64f0da272bfffc703..da42f8feb9a09ec260deb2ce7b1170c120d9f7d0 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 029feab6d87f5f2cc0b3e19e14188857a96fce67..1bccb1871ed3306c48b269f0183f8b6da7513d3b 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 0000000000000000000000000000000000000000..92b80dfade938f040054b61b6f8d6621320eaf4d
--- /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 79877153058c47885f173abfd6293c212d82d2e3..0036e5e65ed967d0ee2a991e6b0080706dccba02 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 01cc27f9474bbcbc36d03af88c399b6e420000b0..68e2c2857066d24754f82fd97a50d257675d5a67 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 4e69671d377bc4782c5fb2da5ad4fd0a5d671832..6ef04333c321b649c100f8c861608327e42b80d6 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 762a3d49d30cc7200bda1e811f0852876f836b7c..4df52e3ad6d66e2abb3ad3417fdf82837d7b3d93 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 0c98de2a57b3e0715e8e2c030167eb0c9459190c..fce5308b7abe6d59424970c31b9414f742470639 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 a2d11e997c3c745abb904e5179cd98ffae73e3b8..13780feaecdf7eae723db38ec3a1e70503760b32 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 baa50c33e45974d751e23005cf43e35d323cf19a..47b475b5b2b41c812e678a25005d21e4ab50eef6 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 373ec3a9d98137916e2a8ba627892be8745a8ca7..0000000000000000000000000000000000000000
--- 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 7de62090a3cc5379ffc5887389e2a13f8bbcfd59..9490ff3602dabc222946c1ba4470b113fe305f6b 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 65bda42b5c9ef9992871c5f0051f9a00c63f2997..de5241a5b863d9df248bd9a0d248ef525d6e3761 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 c1b3f9807345b8ed6e017a61a56353541554c193..d469ed1197f1bf0778fb1419966bd21aa6424984 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 b602d5168d734e0ef288573d81ecdef89ed95364..1a6fd978b7caf70deb68ad4eb8ff49665de055b1 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 b5116d51b4452bcda62012981bd7e78768c5ac30..b8d72cb763ad9f3132b4c66a0e241c91537b323c 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 1d241ab1d251456852937947530e0f27512b5276..be48adab35af3bc50933994d92b7f4d2c6f4222e 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 82e82106bcf47373bec7325adf9397eb2bd5a39b..7112523adc11a575fe77dded8e3f41936c579599 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 fae1c41ad0d5177c7633c43dceacc2995a0adbd5..d914ac1a50817d2b163c41b5531402ac989daca3 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 1042f311ed21165cbdbc0bbaf4cc8ae4505fc8d9..22e6bd4d1002fe066061787462ca7ab40eeeeb4e 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 d868f37e8e7d37c8aa5b2d2e8e1f5db60b5077c0..32b11a7aa5b308a15e9d7104a36f16c43782d465 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 5176569fb7f6909c71b1bfd00719ee217d370249..02b867447c3592c9e735f41125fb11c1e8d16e98 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 0002d2b805f91abcba7d528104a50c40fb2b1fc8..fd9c398bc5abf298095dab95e748aa13a0f4551b 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 124d474a7c2f441ce0f76207825e512878c007e8..339d7620651cbf60b8f6d293cbade0dc991ebd65 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 c6f027fc61ced7d3d08fa473be3fa99b04e2f107..74b11836bc6f17b106b46baefd0999500787918f 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 2342464b7549cb71a7c3435910bdb59bbb6b4854..bce1e24d08fac168607e2fc8f0903da87c4a0749 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 009d906738b0ace2b47f61cdff011fe4f5206c32..7bf7e81c9de2e71680168a7ee1064960318fafd6 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 fef92dcda2d700b1a048dfccca4c2dac96539b3e..1b926a9463b26d4a5f60b8b13b9dd48c241f399a 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 6bbe7a3a2c52df07ee8bccddf10c54d1bd6273d7..32c82982cb94a71c4398dbdd5eaf506c05fcaee7 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 015ca69670b85a2b0d481de9625915243777224d..dd938996bf0e72a2322f0c0d824fbe3f8ae153ce 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 0000000000000000000000000000000000000000..c247e195aa1494549732b0df6e426ca00ea71820
--- /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 c64f82e2a4816ad7f7eb8613d51d57810819d3c2..456da5eede2560244c9944c4b4dd3eacb47d6199 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 5a04e56fa3ca74ccba1fab543cc4008378f23630..0000000000000000000000000000000000000000
--- 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 02eeca38643d64f522342e2c4f3f6796cea3c8cc..6119e5324adb85f14b2feb2ed4bd78c7a68d9239 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 4f0bc940d7c71c25034d5a179195e5a1f994b8f3..60b4a3afb3c33496ffcfc17db36843bc64e1bf43 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 62b07ed2f83f55a2ebfe11c59a722df19f63d1bc..0000000000000000000000000000000000000000
--- 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 00b88f53a277b791214def9e1f1d9b83c01118f7..cd899c38aaffeacbd05c54dee3002106786c5f1d 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 ee88abafba3410af467a86a730e66cf52c5f7cbe..2ca8873f2bd65a15b36bd396c93463c19b095212 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 0000000000000000000000000000000000000000..8e90493146b3c27aee91e043ad6b0fdee36c93ad
--- /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 0000000000000000000000000000000000000000..cf39cb6648a26cf2ddba17eb1d2de140ed6e71fc
--- /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 44626919808d33b05680a445031f535fea706125..d0c6e4a987b4e1def1fd049e1173c913f7e30cf0 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 bcfe1d759e87198e8e248b1f49ae22227741c171..a7369feda35a8329e6776b6cfa3e5b5b622bb2ae 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 b13b90ae1f80eb63cc8acacacd44785280c13ebd..a91d18ec3853c150966de0e1149874d6f4c9a328 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 d3ea390aca7d969ea5725624e13f965a5b625b1f..1c73911e1f09d360a64a5bcf003d22d43c0af451 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 4f11e30e20be456eb96475a59f2d50655c97eacf..d1c71b1a352bf829320d1144ef78938af2a8c00c 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 203f27499d41a43062cf4af5c68eada8c29497e7..136cf2d14f0211fd7c42cf6ffb6414b5744694c9 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 b335bb2d68c184ca26a04b005ad09debe4d83a96..251b67fb5b18e1eb36bf474a49f18a132d08ba10 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 9a8958abc667a8ff8062808174ac1fa9e6c50fee..0552c3c827a521a14a534c8fade5b7ff001d5358 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 b1bc38ea13c7c1762a611167dbb8c86c4b55dff6..1fc1582ac251788a54a2006d7a3d2ec8d14e691c 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 ea20048df2bb43948619fb35a2500ea7f1f15a69..761bd99ac6cc23bd9a33cee1b41f0e1f606e5a14 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 9cd6f2a7e1e76021ae91b3710b15e0db7594ee3c..54a45d8be4b56830c5013a6ef0f29783e4da2e17 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 d7cc0295cadd43000fb9eff1aefa55963f077284..d3bdf778433976cd0639cb44ed69f6c45e7c693f 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 096db188f9e6189c5c9103bcee5dcb1ae65d5de7..3ee5bb31c4d550b7fc4edf59294d1022e862eea8 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 381d6974edef7bf0e868d3c22c38712372094513..bc713579956a81692ca531f4d2acaa0625adab3e 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 4c0136fc6f7b6c5e29a8d828672746da9fedb0ee..edcf32a7bb9f6fc7f4df894e1ba0050d025e7368 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 554232b28651dd7f1139632927c3dddc44cd1495..c54c21f2cdd8577851db131653020f1b712dc227 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 7c78ae3ab7edce925553b87a855112a0efcd86e6..f53360ff3f3d7028d3050af2c75003606bd5e354 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 e4b61f9c70dc22d0779ce8aa57710be0a2446f0c..5f32756fc34884aec562d73bbe84a68b70e5a23f 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 3e76f082a6300d40fb840c7ccf13ef2402787bbb..3437990cf5a4b90160da61497c2936eff5cc465e 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 89b3af6026650e310e5d3e253ed44f677611009c..66a758c94a7cc45e2c637e57b8aafb576c6cf309 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 64371705a4a4c6cc60f5f33466b164c71bc7b795..8f444ef4b0ec1afd90a33dec2fe9d60949ecfd4f 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 4588d164aebae42ff59b258cada846efe9e4df3f..2d34455a7e38221e1cab429dbd2a18e30940b9ac 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 8a25cf1e806aea17a04f8017baabc73ef10e98af..11391373c5fd6f5f090e499743ba22995b43bcf1 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 d4f8e4a45a7ca8af82ac9040a9f07f6bf3fee3aa..89ff95abc6e18c06f1cc49ab69420ec8ff890a20 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 0a65d90d599cbe7a0f639a04f2bb2540253becf2..85524bcda48387085dfc710ab0d67127c67362e2 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 496b9ff98363e2a75343ae153dc599a30ff787ad..70189fd5a2b893e95c6d09871f1d12c0ab0dd75c 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 2e4313d5121a7272c6078cd56a8882774909238d..4a2afa1f19b555a3c131410227c4a9d47fd742dd 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 5102307865ad91091d9366d4139350cbc3b6f7eb..ce67726aea4d1d8480b5e83d92cd85d9cc3269d7 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 f49d0718c31c75887834f0ea32c96edafd3530a0..be76536c9a0ee61003dd5f61fb3352ab8c5da318 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 303f29f07ad45ee334816cb216f0302e63de1060..e276db7b7146b84e76f249066ed8c24a891fe2f2 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 186f852018eea9abeb4b6b66192b4473c153dce7..40efbdbc707190700f6ee30b2fe072db368c50d0 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 58c8b331d818b7705019485ce6cd4628008c13d3..44f4d5d9921ae484b725bd30ec12e6a38432b716 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 a84868ecaafe8998a5c13550ea0190346759a1cb..b86e93ea7fd7a1d9b7c7ba7c32a413bf96d5ed1e 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 8243e10e3ec59c56e09e86f4fa5543a005f6afc7..77184718fd239edfa7af49658a27397c53388a8d 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 885d38fc4104329a8ec58013296c34b7127e777e..223cd2d48e84ee220088179d1c9cd51088450c6a 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 329f8141184566fb1674824f76082ff02627aba6..d3040ea4200973ec3e97a4e5c4d2d114a8244f05 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 e5ffbe455f91c397ee8e5d86fb1af3be0f3e6d46..742016a500c1e7927b4a4c721738f1daaedfbafc 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 0c9a2fb783d3c294cece930829aec0f9272fda28..b5528f2bd342eead648afa2e4adfa577fdd17138 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 f1258d3906df8be0440dce7863d67eaa367b5eb6..b3e97f539642ff0c15d73e1776f0803b8cf87a98 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 3c80c106904882950b86a767a68476bfa79a0bd4..9006aecb4e5c1a6838a674166ead35481935d5d5 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 bb75a1490aedbbd4f78aefc80e06ed017f40a761..c85263a87b2b06d6d23a9b0800d6fb2388a05282 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 cba83036b1472293da2e8f3aa0b066436c682b6d..b67d2dbbbed9e3663b36742679327e6d59f3181f 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 62217937fc3f69c91d5cbfca35bff492517f7f9a..8f95375b4b773c8bfca699fe11f85b3b64f3f6bd 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 8f04a84accb3fdcb0ed42cf5275a5025416dd2b3..c63127754a0e1b60b638f2c7c5368d217b8154a2 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 d4124a66d5698b813948c923d57c5a96964e908d..e9621c509b120e3033377accc0d0d4174daa8001 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 c0108298a672968d97be22f337a3dd79a4e5079f..0e194f91a3381339d3128645568b7e8ac5b4247c 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 30003fdd3eae715f00d6c0ae068c5855617e19be..e49ecdf06039c1db715a0a9f011f4a49f374d678 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 22ed8a882454f06c535ed3663ee7fc109cf1e2c8..e01a6b9d5e5e292d97dabab6ebecfed145bb3669 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 1b58c2199a2055a09db7bd59c215d884a865db04..cb0e50207102495e515a58787c86986b9e4022cb 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 b2d146ab456b7434d95cb9ead1b13e6e7491d74b..ff742cce49036318803e7cd954b1d5b7880c4fe1 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 dd072623f379fe9e66b9b7524b60460780a864ae..007d2324c94ee69aa70df59c906ba492f0694045 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 2f9441f02b2db61fba848457a68864dcb57058f2..ab29dd0c2238ff746e4833f8d6aaa4000670e739 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 5012207f26261d51bac06241d5dbfc763c2d4c43..0525cfa307cc604ca3cd5d8d7812bac4a2bfffd4 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 cf131431b583eef8a007449323f90ba62164451e..f31c97ca8d23eb67d5884ea823910251fb26ef1d 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 f4f8e78c819605a89df44f9a75b70abe220cc8f4..88788b34e1d36d6667806839c184ff5263abb551 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 3c539f7b347275ccca57dd356ba5073cbf94476e..ced5562a0566b075a748943854d79092130ee7f3 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 176a89978e5b90c37b2f589ecabbd173232841cd..74f189e5c3ac6b60cb1029da3968510af3d25074 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 6f28e52e3a4060dfbb1a49aa38e0897bd6b68b14..130fc7bda041077df53433891f0a8f06f0ed3222 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 175c38181a5e9f2f80a65bc9ee9c0dac84e8bbe6..bf31706cfd7dd276b754c81d9f08a1df82f7f0b3 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 5178fbf56aeed34ccaa7b733cc450a908d0e4497..da00b74644fd993b64644c631afd2aecf7991663 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 51fde249567862173a96581ab99d6b19f96fdb28..518d6c87420fe7f039927596913ac48e6097eceb 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 2e2c763d1fbf18ed1ccaec05c45e6c7c1f8fddbe..050d2eb26d22d0cfe76ed1aaa8dedd833ac8c641 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 64099054a49a596545fac937519eeaa5548518c9..15c5b4a46740faadbace24b8417317ef92fa6f1f 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 0000000000000000000000000000000000000000..0932cbcce433120f132364bfd6a0a5078ff625d0
--- /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 0000000000000000000000000000000000000000..fbd71c71ec7ceed73a06f0e9447e46bc48b4e5e4
--- /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 1797ec04d875ce0090295e072cb433c53516ca61..9cc58f2012adba71b87566bb4d5063daf4b22168 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 821c7d4c7cddcdc4cb149d034993a86759cbf216..7fe481f9fc6bceb1f12332d9e27588cfc3f74b9f 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 0000000000000000000000000000000000000000..9044d15df6170eb3f8dd69cf23d9ed02d4a3f5f5
--- /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 d4d7f2cdc5540d9bbf0dd0a764b5b464abc5169c..bd099ce43388cd43232b6368f72525600c4eebac 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 0000000000000000000000000000000000000000..2153a69606177bb85f5560e9727572bb7f563da7
--- /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 a4ec587480fc4fe7b5944fb4c1c93b453318dfd2..bf6f6a56f73589032dec435e3c0e6d2b4dd53d15 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 8906c55a4afdca9d3d722b40256510b7d41de4cf..5cb77cb5a6d5fcd112e748c5a36484ca7ad146a3 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);