diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55f2cc4ad577caae061841c5f08074f8b1413a90..f08223e7f01d382f5bea8dad0c8958ffd59753d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,67 @@
+2.0.0.0-dev79
+=============
+* Tax calculation updates:
+ * Fixed issues in tax calculation rounding with discount applied
+ * Fixed an issue with extra penny  when exact tax amount ended with 0.5 cent
+ * Fixed an issue where there were tax calculation errors when customer tax rate was different from store tax rate
+ * Added support to round tax at individual tax rate
+ * Fixed price inconsistencies between catalog and shopping cart
+ * Added support for maintaining consistent price including tax for customers with different tax rates
+ * Added support for applying tax rules with different priorities to subtotal only
+* Fixed bugs:
+  * Removed the extra '%' sign in the error\notice message on Gift Card Accounts page on the backend
+  * Fixed an issue with image uploading functionality in the Catalog configuration
+  * Fixed an issue where a customer could not navigate the store when downloading the downloadable product
+  * Fixed an issue where adding CMS block Catalog Events Lister caused an error
+  * Fixed an issue where the price was displayed twice on the Product page on the frontend
+  * Fixed an issue where an admin could not open search results on the backend
+  * Fixed an issue where the Rule Based Product Relations functionality was generating incorrect SQL when product category attribute was set through "is one of" or "contains" operator by constant value
+  * Fixed an issue where it was impossible to add a product to the Compare list for  categories with three-column page layout
+  * Fixed an issue where a blank page opened when changing store view on a product page on the frontend
+  * Fixed an issue where the  "Please specify at least one search term." error message was not displayed if search is performed without search data specified on the frontend
+  * Fixed a Google Chrome specific issue where page layout was broken when updating status for reviews on the backend
+  * Fixed admin look and feel issues
+  * Fixed an issue where the order notices and error messages were not red
+  * Fixed a UI issue which appeared during custom attribute creation
+  * Fixed an issue where the popup did not open after clicking What's this? next to the Remember Me check box  when persistent shopping cart was enabled
+  * Fixed an issue where the options of the Add Product split dropdown did not fit the page
+  * Fixed an issue where the default theme preview image sample link was missing
+  * Fixed a Safari and Internet Explorer 9 specific issue where the backend menu is not displayed for users with custom admin roles
+  * Fixed an issue where  the price of bundle products was not  displayed correctly on the product page on the frontend
+  * Fixed a UI issue in the debug mode configuration
+  * Fixed minor issues with page layout
+  * Fixed an issue where the mini shopping cart loaded data from cache
+  * Fixed an issue where there was an incorrect value in the Grand Total (Base) column in the Orders grid if Catalog Price Scope was set to Website
+  * Fixed an issue where the Entity Generator tool did not accept the "class" parameter
+  * Fixed an issue where the default email template was not applied when the custom template in use was deleted
+  * Fixed an issue where shipping price for flat rate was set to 0 in the side block during checkout of a product with a configured recurring profile
+  * Fixed an issue where it was possible to create more Shipping Labels than there were products in the shipment
+  * Fixed an issue where data about "SHA-IN Pass Phrase" was missing after changing "Payment Action" in the Ogone payment method configuration
+  * Fixed performance issues with reindexing of the Price indexer
+  * Fixed an issue where importing tax rates with postal code = * led to incorrect data entered into database
+  * Fixed an issue where incorrect link to reset password was sent if secure URL was used on the frontend
+  * Fixed an issue where the Links section was absent while editing downloadable products from the Wishlist
+  * Fixed an issue where specified details for composite products were lost after adding to Gift Card and Downloadable products to the Wishlist
+  * Fixed and issue where the Date widget was set to incorrect date when creating a new customer
+  * Fixed an issue where a customer was redirected to Dashboard if the Redirect user to dashboard after login option was set to ‘No’
+  * Fixed an issue where a customer was not able to register during checkout if Guest Checkout was not allowed
+  * Fixed an issue where System logs were not generated properly in integration tests
+  * Fixed benchmarking script
+  * Fixed an issue where it was impossible to put store to the maintenance mode during backup
+  * Fixed insecure use of mt_rand()
+  * Fixed an issue where Quoted price was displayed incorrectly from the shopping cart in the backend
+* Functional tests:
+  * Tax Rule Creation
+  * Admin User Roe Creation
+  * Simple Product Creation
+  * Customer Group Creation
+  * Update Backend Customer
+  * Newsletter Creation
+* Updated composer.json.dist to download and install MTF from Public GitHub repository
+* GitHub requests:
+  * [#542] (https://github.com/magento/magento2/pull/542) Fix ImportExport bug which occurs while importing multiple rows per entity
+  * [#507] (https://github.com/magento/magento2/issues/507) "Insert Image" window is overlapped on menu
+
 2.0.0.0-dev78
 =============
 * Fixed bugs:
@@ -158,7 +222,7 @@
       * `lib/Magento/Framework/Data/Form/Element/Submit.php`
       * `lib/Magento/Framework/Data/Form/Element/Text.php`
       * `lib/Magento/Framework/Data/Form/Element/Textarea.php`
-  
+
 2.0.0.0-dev75
 =============
 * Modularity improvements:
@@ -2678,4 +2742,3 @@ Deprecated code & minor fixes update:
 2.0.0.0-dev01
 =============
 * Added initial version of Magento 2.x CE to public repository
-
diff --git a/app/bootstrap.php b/app/bootstrap.php
index ecc668e5d2d19fbfa2f96796564f3b6672df746c..202866a451bedace45b4348a6ecd5923f6e4d2a1 100644
--- a/app/bootstrap.php
+++ b/app/bootstrap.php
@@ -72,9 +72,10 @@ if (file_exists($classMapPath)) {
 }
 
 if (!defined('BARE_BOOTSTRAP')) {
-    if (file_exists(BP . '/maintenance.flag')) {
-
-        if (!in_array($_SERVER['REMOTE_ADDR'], explode(",", file_get_contents(BP . '/maintenance.flag')))) {
+    $maintenanceFlag = BP . '/' . \Magento\Framework\App\State\MaintenanceMode::FLAG_DIR . '/'
+        . \Magento\Framework\App\State\MaintenanceMode::FLAG_FILENAME;
+    if (file_exists($maintenanceFlag)) {
+        if (!in_array($_SERVER['REMOTE_ADDR'], explode(",", file_get_contents($maintenanceFlag)))) {
             if (PHP_SAPI == 'cli') {
                 echo 'Service temporarily unavailable due to maintenance downtime.';
             } else {
diff --git a/app/code/Magento/Backend/Block/System/Config/Form/Field/Image.php b/app/code/Magento/Backend/Block/System/Config/Form/Field/Image.php
index 2d49f5d0a043fbaae9da9b55bfc0a6802f2f464f..bfac382917cbaf9fdcc9111b8b5233db2e245367 100644
--- a/app/code/Magento/Backend/Block/System/Config/Form/Field/Image.php
+++ b/app/code/Magento/Backend/Block/System/Config/Form/Field/Image.php
@@ -27,6 +27,11 @@
  */
 namespace Magento\Backend\Block\System\Config\Form\Field;
 
+/**
+ * Class Image Field
+ * @method getFieldConfig()
+ * @method setFieldConfig()
+ */
 class Image extends \Magento\Framework\Data\Form\Element\Image
 {
     /**
@@ -39,10 +44,10 @@ class Image extends \Magento\Framework\Data\Form\Element\Image
         $url = parent::_getUrl();
         $config = $this->getFieldConfig();
         /* @var $config array */
-        if (array_key_exists('base_url', $config)) {
+        if (isset($config['base_url'])) {
             $element = $config['base_url'];
             $urlType = empty($element['type']) ? 'link' : (string)$element['type'];
-            $url = $this->_urlBuilder->getBaseUrl($urlType) . $element['value'] . '/' . $url;
+            $url = $this->_urlBuilder->getBaseUrl(['_type' => $urlType]) . $element['value'] . '/' . $url;
         }
         return $url;
     }
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
index 94981c4764024ba5b82aedddf1c6659a187624a4..d2bf0763a08335035ceae65254fd7f2545c558d1 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Column/Renderer/Currency.php
@@ -57,7 +57,7 @@ class Currency extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Abstra
     /**
      * @var \Magento\Directory\Model\Currency
      */
-    protected $_baseCurrency;
+    protected $_defaultBaseCurrency;
 
     /**
      * @var \Magento\Framework\Locale\CurrencyInterface
@@ -84,11 +84,11 @@ class Currency extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Abstra
         $this->_storeManager = $storeManager;
         $this->_currencyLocator = $currencyLocator;
         $this->_localeCurrency = $localeCurrency;
-        $baseCurrencyCode = $this->_scopeConfig->getValue(
+        $defaultBaseCurrencyCode = $this->_scopeConfig->getValue(
             \Magento\Directory\Model\Currency::XML_PATH_CURRENCY_BASE,
             'default'
         );
-        $this->_baseCurrency = $currencyFactory->create()->load($baseCurrencyCode);
+        $this->_defaultBaseCurrency = $currencyFactory->create()->load($defaultBaseCurrencyCode);
     }
 
     /**
@@ -142,7 +142,7 @@ class Currency extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Abstra
         if ($rate = $row->getData($this->getColumn()->getRateField())) {
             return floatval($rate);
         }
-        return $this->_baseCurrency->getRate($this->_getCurrencyCode($row));
+        return $this->_defaultBaseCurrency->getRate($this->_getCurrencyCode($row));
     }
 
     /**
diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml
index 056b8a58b9c1abf8482120388e2e6d1c1c115c4f..55d4bff058eb324d21723cd4e8d708aca9654d09 100644
--- a/app/code/Magento/Backend/etc/adminhtml/di.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/di.xml
@@ -51,40 +51,8 @@
             <argument name="sessionName" xsi:type="string">adminhtml</argument>
         </arguments>
     </type>
-    <type name="Magento\Backend\Model\Config\Structure\Data">
-        <arguments>
-            <argument name="cacheId" xsi:type="string">backend_system_configuration_structure</argument>
-        </arguments>
-    </type>
     <type name="Magento\Backend\Model\Config\Structure\Element\Iterator\Tab" shared="false" />
     <type name="Magento\Backend\Model\Config\Structure\Element\Iterator\Section" shared="false" />
-    <type name="Magento\Backend\Model\Config\Structure\Element\Iterator\Group" shared="false" />
-    <type name="Magento\Backend\Model\Config\Structure\Element\Iterator\Field" shared="false">
-        <arguments>
-            <argument name="groupFlyweight" xsi:type="object">Magento\Backend\Model\Config\Structure\Element\Group\Proxy</argument>
-        </arguments>
-    </type>
-    <type name="Magento\Backend\Model\Config\Structure\Element\Dependency\Mapper" shared="false">
-        <arguments>
-            <argument name="fieldLocator" xsi:type="object">Magento\Backend\Model\Config\Structure\Search\Proxy</argument>
-        </arguments>
-    </type>
-    <type name="Magento\Backend\Model\Config\Structure\Element\Tab" shared="false">
-        <arguments>
-            <argument name="childrenIterator" xsi:type="object">Magento\Backend\Model\Config\Structure\Element\Iterator\Section</argument>
-        </arguments>
-    </type>
-    <type name="Magento\Backend\Model\Config\Structure\Element\Section" shared="false">
-        <arguments>
-            <argument name="childrenIterator" xsi:type="object">Magento\Backend\Model\Config\Structure\Element\Iterator\Group</argument>
-        </arguments>
-    </type>
-    <type name="Magento\Backend\Model\Config\Structure\Element\Group" shared="false">
-        <arguments>
-            <argument name="childrenIterator" xsi:type="object">Magento\Backend\Model\Config\Structure\Element\Iterator\Field</argument>
-        </arguments>
-    </type>
-    <type name="Magento\Backend\Model\Config\Structure\Element\Group\Proxy" shared="false" />
     <type name="Magento\Framework\View\Layout">
         <arguments>
             <argument name="area" xsi:type="string">adminhtml</argument>
diff --git a/app/code/Magento/Backend/etc/di.xml b/app/code/Magento/Backend/etc/di.xml
index 85f461366af5ffe2905afa7eefcf0e6897964a49..cd6813917a314eddfca4cc01d4b60d6da228bbe6 100644
--- a/app/code/Magento/Backend/etc/di.xml
+++ b/app/code/Magento/Backend/etc/di.xml
@@ -183,4 +183,38 @@
             <argument name="storage" xsi:type="object">Magento\Backend\Model\Session\Quote\Storage</argument>
         </arguments>
     </type>
+
+    <type name="Magento\Backend\Model\Config\Structure\Element\Iterator\Group" shared="false" />
+    <type name="Magento\Backend\Model\Config\Structure\Element\Group\Proxy" shared="false" />
+    
+    <type name="Magento\Backend\Model\Config\Structure\Element\Dependency\Mapper" shared="false">
+        <arguments>
+            <argument name="fieldLocator" xsi:type="object">Magento\Backend\Model\Config\Structure\Search\Proxy</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Backend\Model\Config\Structure\Data">
+        <arguments>
+            <argument name="cacheId" xsi:type="string">backend_system_configuration_structure</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Backend\Model\Config\Structure\Element\Tab" shared="false">
+        <arguments>
+            <argument name="childrenIterator" xsi:type="object">Magento\Backend\Model\Config\Structure\Element\Iterator\Section</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Backend\Model\Config\Structure\Element\Section" shared="false">
+        <arguments>
+            <argument name="childrenIterator" xsi:type="object">Magento\Backend\Model\Config\Structure\Element\Iterator\Group</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Backend\Model\Config\Structure\Element\Iterator\Field" shared="false">
+        <arguments>
+            <argument name="groupFlyweight" xsi:type="object">Magento\Backend\Model\Config\Structure\Element\Group\Proxy</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Backend\Model\Config\Structure\Element\Group" shared="false">
+        <arguments>
+            <argument name="childrenIterator" xsi:type="object">Magento\Backend\Model\Config\Structure\Element\Iterator\Field</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Backend/view/adminhtml/page/js/calendar.phtml b/app/code/Magento/Backend/view/adminhtml/page/js/calendar.phtml
index 91f134d95ff6eff59c59b7106588747c86fc2911..0b0c8c0b660f2be6a36c6805b4def7182a8f35f6 100644
--- a/app/code/Magento/Backend/view/adminhtml/page/js/calendar.phtml
+++ b/app/code/Magento/Backend/view/adminhtml/page/js/calendar.phtml
@@ -64,7 +64,8 @@
             showHour: false,
             showMinute: false,
             localTimezone: <?php echo $this->getTimezoneOffsetSeconds() ?>,
-            serverTimezoneSeconds:<?php echo $this->getStoreTimestamp() ?>
+            serverTimezoneSeconds:<?php echo $this->getStoreTimestamp() ?>,
+            yearRange: '<?php echo $this->getYearRange() ?>'
         }
     });
 })(jQuery);
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php
index 0447af34ced79ce31b993d036bebce62e63314f0..0bee25a18940e32bf3cf26742ed6aec59e824362 100644
--- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php
@@ -52,24 +52,32 @@ class Index extends \Magento\Backend\App\Action
      */
     protected $_backupModelFactory;
 
+    /**
+     * @var \Magento\Framework\App\State\MaintenanceMode
+     */
+    protected $maintenanceMode;
+
     /**
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Framework\Backup\Factory $backupFactory
      * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
      * @param \Magento\Backup\Model\BackupFactory $backupModelFactory
+     * @param \Magento\Framework\App\State\MaintenanceMode $maintenanceMode
      */
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
         \Magento\Framework\Registry $coreRegistry,
         \Magento\Framework\Backup\Factory $backupFactory,
         \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
-        \Magento\Backup\Model\BackupFactory $backupModelFactory
+        \Magento\Backup\Model\BackupFactory $backupModelFactory,
+        \Magento\Framework\App\State\MaintenanceMode $maintenanceMode
     ) {
         $this->_coreRegistry = $coreRegistry;
         $this->_backupFactory = $backupFactory;
         $this->_fileFactory = $fileFactory;
         $this->_backupModelFactory = $backupModelFactory;
+        $this->maintenanceMode = $maintenanceMode;
         parent::__construct($context);
     }
 
@@ -150,9 +158,7 @@ class Index extends \Magento\Backend\App\Action
             $this->_coreRegistry->register('backup_manager', $backupManager);
 
             if ($this->getRequest()->getParam('maintenance_mode')) {
-                $turnedOn = $helper->turnOnMaintenanceMode();
-
-                if (!$turnedOn) {
+                if (!$this->maintenanceMode->turnOn()) {
                     $response->setError(
                         __(
                             'You need more permissions to activate maintenance mode right now.'
@@ -202,7 +208,7 @@ class Index extends \Magento\Backend\App\Action
         }
 
         if ($this->getRequest()->getParam('maintenance_mode')) {
-            $helper->turnOffMaintenanceMode();
+            $this->maintenanceMode->turnOff();
         }
 
         $this->getResponse()->setBody($response->toJson());
@@ -306,9 +312,7 @@ class Index extends \Magento\Backend\App\Action
             }
 
             if ($this->getRequest()->getParam('maintenance_mode')) {
-                $turnedOn = $helper->turnOnMaintenanceMode();
-
-                if (!$turnedOn) {
+                if (!$this->maintenanceMode->turnOn()) {
                     $response->setError(
                         __(
                             'You need more permissions to activate maintenance mode right now.'
@@ -373,7 +377,7 @@ class Index extends \Magento\Backend\App\Action
         }
 
         if ($this->getRequest()->getParam('maintenance_mode')) {
-            $helper->turnOffMaintenanceMode();
+            $this->maintenanceMode->turnOff();
         }
 
         $this->getResponse()->setBody($response->toJson());
diff --git a/app/code/Magento/Backup/Helper/Data.php b/app/code/Magento/Backup/Helper/Data.php
index f0811f751ee7c75a6fbb6456bf802ed42bf5f8f4..faa0625d4794ac6d7fe9d2726b0c46d1c40c0fd3 100644
--- a/app/code/Magento/Backup/Helper/Data.php
+++ b/app/code/Magento/Backup/Helper/Data.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\Backup\Helper;
 
+use Magento\Framework\App\State\MaintenanceMode;
+
 /**
  * Backup data helper
  */
@@ -191,7 +193,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return array(
             '.git',
             '.svn',
-            'maintenance.flag',
+            $this->_filesystem->getPath(MaintenanceMode::FLAG_DIR) . '/' . MaintenanceMode::FLAG_FILENAME,
             $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::SESSION_DIR),
             $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::CACHE_DIR),
             $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::LOG_DIR),
@@ -211,7 +213,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return array(
             '.svn',
             '.git',
-            'maintenance.flag',
+            $this->_filesystem->getPath(MaintenanceMode::FLAG_DIR) . '/' . MaintenanceMode::FLAG_FILENAME,
             $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::SESSION_DIR),
             $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::LOG_DIR),
             $this->_filesystem->getPath(\Magento\Framework\App\Filesystem::VAR_DIR) . '/locks',
@@ -221,35 +223,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         );
     }
 
-    /**
-     * Put store into maintenance mode
-     *
-     * @return bool
-     */
-    public function turnOnMaintenanceMode()
-    {
-        $maintenanceFlagFile = $this->getMaintenanceFlagFilePath();
-        $result = $this->_filesystem->getDirectoryWrite(
-            \Magento\Framework\App\Filesystem::ROOT_DIR
-        )->writeFile(
-            $maintenanceFlagFile,
-            'maintenance'
-        );
-
-        return $result !== false;
-    }
-
-    /**
-     * Turn off store maintenance mode
-     *
-     * @return void
-     */
-    public function turnOffMaintenanceMode()
-    {
-        $maintenanceFlagFile = $this->getMaintenanceFlagFilePath();
-        $this->_filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem::ROOT_DIR)->delete($maintenanceFlagFile);
-    }
-
     /**
      * Get backup create success message by backup type
      *
@@ -274,16 +247,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $messagesMap[$type];
     }
 
-    /**
-     * Get path to maintenance flag file
-     *
-     * @return string
-     */
-    protected function getMaintenanceFlagFilePath()
-    {
-        return 'maintenance.flag';
-    }
-
     /**
      * Invalidate Cache
      *
diff --git a/app/code/Magento/Backup/Model/Observer.php b/app/code/Magento/Backup/Model/Observer.php
index 71af7b60dd733ee8b9d67c130974034afad2464a..afc884990cf8256c90ef4a923998595d3d5b0ac8 100644
--- a/app/code/Magento/Backup/Model/Observer.php
+++ b/app/code/Magento/Backup/Model/Observer.php
@@ -84,6 +84,11 @@ class Observer
      */
     protected $_backupFactory;
 
+    /**
+     * @var \Magento\Framework\App\State\MaintenanceMode
+     */
+    protected $maintenanceMode;
+
     /**
      * @param \Magento\Backup\Helper\Data $backupData
      * @param \Magento\Framework\Registry $coreRegistry
@@ -91,6 +96,7 @@ class Observer
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Framework\App\Filesystem $filesystem
      * @param \Magento\Framework\Backup\Factory $backupFactory
+     * @param \Magento\Framework\App\State\MaintenanceMode $maintenanceMode
      */
     public function __construct(
         \Magento\Backup\Helper\Data $backupData,
@@ -98,7 +104,8 @@ class Observer
         \Magento\Framework\Logger $logger,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Framework\App\Filesystem $filesystem,
-        \Magento\Framework\Backup\Factory $backupFactory
+        \Magento\Framework\Backup\Factory $backupFactory,
+        \Magento\Framework\App\State\MaintenanceMode $maintenanceMode
     ) {
         $this->_backupData = $backupData;
         $this->_coreRegistry = $coreRegistry;
@@ -106,6 +113,7 @@ class Observer
         $this->_scopeConfig = $scopeConfig;
         $this->_filesystem = $filesystem;
         $this->_backupFactory = $backupFactory;
+        $this->maintenanceMode = $maintenanceMode;
     }
 
     /**
@@ -120,7 +128,7 @@ class Observer
         }
 
         if ($this->_scopeConfig->isSetFlag(self::XML_PATH_BACKUP_MAINTENANCE_MODE, ScopeInterface::SCOPE_STORE)) {
-            $this->_backupData->turnOnMaintenanceMode();
+            $this->maintenanceMode->turnOn();
         }
 
         $type = $this->_scopeConfig->getValue(self::XML_PATH_BACKUP_TYPE, ScopeInterface::SCOPE_STORE);
@@ -158,7 +166,7 @@ class Observer
         }
 
         if ($this->_scopeConfig->isSetFlag(self::XML_PATH_BACKUP_MAINTENANCE_MODE, ScopeInterface::SCOPE_STORE)) {
-            $this->_backupData->turnOffMaintenanceMode();
+            $this->maintenanceMode->turnOff();
         }
 
         return $this;
diff --git a/app/code/Magento/Backup/view/adminhtml/backup/dialogs.phtml b/app/code/Magento/Backup/view/adminhtml/backup/dialogs.phtml
index 65c6f0d90a2433b5abf39d1d27d0b34eb4e31db4..a3d7602ce28f93f5410c281f2319625a6e3f2989 100644
--- a/app/code/Magento/Backup/view/adminhtml/backup/dialogs.phtml
+++ b/app/code/Magento/Backup/view/adminhtml/backup/dialogs.phtml
@@ -65,7 +65,7 @@
                 <h2 class="popup-title"><?php echo __('Backup options') ?></h2>
             </header>
             <div class="popup-content">
-                <div style="display: none;"><div class="messages"></div></div>
+                <div class="backup-messages" style="display: none;"><div class="messages"></div></div>
                 <p class="message-text"><?php echo __('Please specify backup creation option.')?></p>
                 <form action="" method="post" id="backup-form">
                     <div class="form-list question">
diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php
index 6251ba4dd2335fa7936255cd3fa38107e7e74dab..511001916c643ede7e24bb613cf7ee2a31b1100a 100644
--- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php
+++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle.php
@@ -264,8 +264,12 @@ class Bundle extends \Magento\Catalog\Block\Product\View\AbstractView
             'bundleId' => $currentProduct->getId(),
             'priceFormat' => $this->_localeFormat->getPriceFormat(),
             'basePrice' => $this->priceCurrency->convert($baseProductAmount->getValue()),
-            'finalBasePriceInclTax' => $this->priceCurrency->convert($productAmount->getValue()),
-            'finalBasePriceExclTax' => $this->priceCurrency->convert($productAmount->getBaseAmount()),
+            'finalBasePriceInclTax' => $isFixedPrice
+                ? $this->priceCurrency->convert($productAmount->getValue())
+                : 0,
+            'finalBasePriceExclTax' => $isFixedPrice
+                ? $this->priceCurrency->convert($productAmount->getBaseAmount())
+                : 0,
             'priceType' => $currentProduct->getPriceType(),
             'specialPrice' => $currentProduct
                 ->getPriceInfo()
diff --git a/app/code/Magento/Bundle/Model/Resource/Indexer/Price.php b/app/code/Magento/Bundle/Model/Resource/Indexer/Price.php
index 886e6e706793345ba704843c20e6cb1302ac5c39..c4f420b261a7f9801ab6d14106d96d6fc95fa978 100644
--- a/app/code/Magento/Bundle/Model/Resource/Indexer/Price.php
+++ b/app/code/Magento/Bundle/Model/Resource/Indexer/Price.php
@@ -537,6 +537,9 @@ class Price extends \Magento\Catalog\Model\Resource\Product\Indexer\Price\Defaul
      */
     protected function _prepareBundlePrice($entityIds = null)
     {
+        if (!$this->hasEntity() && empty($entityIds)) {
+            return $this;
+        }
         $this->_prepareTierPriceIndex($entityIds);
         $this->_prepareGroupPriceIndex($entityIds);
         $this->_prepareBundlePriceTable();
diff --git a/app/code/Magento/Bundle/view/frontend/catalog/product/view/type/bundle.phtml b/app/code/Magento/Bundle/view/frontend/catalog/product/view/type/bundle.phtml
index 8ade7b2e0e3e343974678f7fee342af3833f967a..c6fcace245b5db528c00c5d53c455ad3e6b1074a 100644
--- a/app/code/Magento/Bundle/view/frontend/catalog/product/view/type/bundle.phtml
+++ b/app/code/Magento/Bundle/view/frontend/catalog/product/view/type/bundle.phtml
@@ -37,8 +37,8 @@
                     "priceSelectors": {
                         "product-price": "#product-price-<?php echo $_product->getId()?>",
                         "bundle-price": "#bundle-price-<?php echo $_product->getId()?>",
-                        "price-including-tax": "#price-including-tax-<?php echo $_product->getId()?>",
-                        "price-excluding-tax": "#price-excluding-tax-<?php echo $_product->getId()?>"
+                        "price-including-tax": "#price-including-tax-product-price-<?php echo $_product->getId()?>",
+                        "price-excluding-tax": "#price-excluding-tax-product-price-<?php echo $_product->getId()?>"
                     }
                 });
             });
diff --git a/app/code/Magento/Captcha/Model/DefaultModel.php b/app/code/Magento/Captcha/Model/DefaultModel.php
index ffee8b1eae8ac30eb3340cdbf4d66e20ca9d6f25..c421b1a601e1f3d2c9edaeabef0f79cd6d943a51 100644
--- a/app/code/Magento/Captcha/Model/DefaultModel.php
+++ b/app/code/Magento/Captcha/Model/DefaultModel.php
@@ -408,7 +408,7 @@ class DefaultModel extends \Zend_Captcha_Image implements \Magento\Captcha\Model
             $to = self::DEFAULT_WORD_LENGTH_TO;
         }
 
-        return mt_rand($from, $to);
+        return \Magento\Framework\Math\Random::getRandomNumber($from, $to);
     }
 
     /**
@@ -509,7 +509,7 @@ class DefaultModel extends \Zend_Captcha_Image implements \Magento\Captcha\Model
      */
     protected function _randomSize()
     {
-        return mt_rand(280, 300) / 100;
+        return \Magento\Framework\Math\Random::getRandomNumber(280, 300) / 100;
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/DefaultPrice.php b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/DefaultPrice.php
index b16662ac4817a23387a47208f3b7134b370d38d3..a20e8e47f7dab41cfe8fc5f06bf7582bf2d1dad9 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/DefaultPrice.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Price/DefaultPrice.php
@@ -145,9 +145,7 @@ class DefaultPrice extends \Magento\Catalog\Model\Resource\Product\Indexer\Abstr
         $this->useIdxTable(true);
         $this->beginTransaction();
         try {
-            $this->_prepareFinalPriceData();
-            $this->_applyCustomOption();
-            $this->_movePriceDataToIndexTable();
+            $this->reindex();
             $this->commit();
         } catch (\Exception $e) {
             $this->rollBack();
@@ -160,13 +158,25 @@ class DefaultPrice extends \Magento\Catalog\Model\Resource\Product\Indexer\Abstr
      * Reindex temporary (price result data) for defined product(s)
      *
      * @param int|array $entityIds
-     * @return $this
+     * @return \Magento\Catalog\Model\Resource\Product\Indexer\Price\DefaultPrice
      */
     public function reindexEntity($entityIds)
     {
-        $this->_prepareFinalPriceData($entityIds);
-        $this->_applyCustomOption();
-        $this->_movePriceDataToIndexTable();
+        $this->reindex($entityIds);
+        return $this;
+    }
+
+    /**
+     * @param null|int|array $entityIds
+     * @return \Magento\Catalog\Model\Resource\Product\Indexer\Price\DefaultPrice
+     */
+    protected function reindex($entityIds = null)
+    {
+        if ($this->hasEntity() || !empty($entityIds)) {
+            $this->_prepareFinalPriceData($entityIds);
+            $this->_applyCustomOption();
+            $this->_movePriceDataToIndexTable();
+        }
         return $this;
     }
 
@@ -667,4 +677,22 @@ class DefaultPrice extends \Magento\Catalog\Model\Resource\Product\Indexer\Abstr
         }
         return $this->getTable('catalog_product_index_price_tmp');
     }
+
+    /**
+     * @return bool
+     */
+    protected function hasEntity()
+    {
+        $reader = $this->_getReadAdapter();
+
+        $select = $reader->select()->from(
+            array($this->getTable('catalog_product_entity')),
+            array('count(entity_id)')
+        )->where(
+            'type_id=?',
+            $this->getTypeId()
+        );
+
+        return (int)$reader->fetchOne($select) > 0;
+    }
 }
diff --git a/app/code/Magento/Catalog/Model/Url.php b/app/code/Magento/Catalog/Model/Url.php
index 8f460c3a89a2de0a50fc59568d76145d53a76a18..2e45f495e765e2d38be558499f7052462bd6f63b 100644
--- a/app/code/Magento/Catalog/Model/Url.php
+++ b/app/code/Magento/Catalog/Model/Url.php
@@ -998,7 +998,7 @@ class Url
      */
     public function generateUniqueIdPath()
     {
-        return str_replace('.', '_', uniqid(mt_rand(), true));
+        return str_replace('.', '_', uniqid(\Magento\Framework\Math\Random::getRandomNumber(), true));
     }
 
     /**
diff --git a/app/code/Magento/Catalog/view/base/product/price/configured_price.phtml b/app/code/Magento/Catalog/view/base/product/price/configured_price.phtml
index 28645127641b1bc72089797710d268a28ac284bb..56937eac033e301edfa174e944b2e17d165c53a2 100644
--- a/app/code/Magento/Catalog/view/base/product/price/configured_price.phtml
+++ b/app/code/Magento/Catalog/view/base/product/price/configured_price.phtml
@@ -30,6 +30,7 @@ $configuredPrice = $this->getPrice();
 <p class="price-as-configured">
     <?php echo $this->renderAmount($configuredPrice->getAmount(), [
         'display_label'     => __('Price as configured:'),
+        'price_id'          => $this->getPriceId('product-price-'),
         'include_container' => false
     ]); ?>
 </p>
diff --git a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml
index af981d307000f1b8fa438c72f022f9b6633329c4..c276ef78834bf631ddfc3b7931a7df3e220e0c7e 100644
--- a/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml
+++ b/app/code/Magento/Catalog/view/frontend/layout/catalog_product_view.xml
@@ -97,7 +97,6 @@
                     </block>
                     <block class="Magento\Catalog\Block\Product\View" name="product.info.options.wrapper.bottom" as="product_options_wrapper_bottom" template="product/view/options/wrapper/bottom.phtml">
                         <block class="Magento\Catalog\Block\Product\View" name="product.info.addtocart.additional" as="product.info.addtocart" template="product/view/addtocart.phtml"/>
-                        <block class="Magento\Catalog\Block\Product\View" name="product.clone_prices" as="prices" template="product/view/price_clone.phtml"/>
                     </block>
                 </block>
             </block>
diff --git a/app/code/Magento/CatalogSearch/view/frontend/form-mini.js b/app/code/Magento/CatalogSearch/view/frontend/form-mini.js
index 47d165efa9b3236c58842a075ec2042d780206ca..d7be25c798b5821c62364b0d44320333218e8ee2 100644
--- a/app/code/Magento/CatalogSearch/view/frontend/form-mini.js
+++ b/app/code/Magento/CatalogSearch/view/frontend/form-mini.js
@@ -99,6 +99,8 @@
          */
         _onSubmit: function(e) {
             if (this.element.val() === this.options.placeholder || this.element.val() === '') {
+                this.options.placeholder = jQuery.mage.__('Please specify at least one search term.');
+                this.element.val(this.options.placeholder);
                 e.preventDefault();
             }
             if (this.responseList.selected) {
diff --git a/app/code/Magento/Checkout/Block/Onepage/Progress.php b/app/code/Magento/Checkout/Block/Onepage/Progress.php
index b87f262605f183f910c9af12207998b38293743f..203705e6386f92e3b157cc09e4a36c7ceecaa828 100644
--- a/app/code/Magento/Checkout/Block/Onepage/Progress.php
+++ b/app/code/Magento/Checkout/Block/Onepage/Progress.php
@@ -23,6 +23,9 @@
  */
 namespace Magento\Checkout\Block\Onepage;
 
+use Magento\Customer\Model\Address\Config as AddressConfig;
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface as CustomerAccountService;
+use Magento\Customer\Service\V1\CustomerAddressServiceInterface as CustomerAddressService;
 use Magento\Sales\Model\Quote\Address;
 
 /**
@@ -32,6 +35,59 @@ use Magento\Sales\Model\Quote\Address;
  */
 class Progress extends \Magento\Checkout\Block\Onepage\AbstractOnepage
 {
+    /**
+     * @var \Magento\Tax\Helper\Data
+     */
+    protected $_taxData;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Core\Helper\Data $coreData
+     * @param \Magento\Framework\App\Cache\Type\Config $configCacheType
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Checkout\Model\Session $resourceSession
+     * @param \Magento\Directory\Model\Resource\Country\CollectionFactory $countryCollectionFactory
+     * @param \Magento\Directory\Model\Resource\Region\CollectionFactory $regionCollectionFactory
+     * @param CustomerAccountService $customerAccountService
+     * @param CustomerAddressService $customerAddressService
+     * @param AddressConfig $addressConfig
+     * @param \Magento\Framework\App\Http\Context $httpContext
+     * @param \Magento\Tax\Helper\Data $taxData
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Core\Helper\Data $coreData,
+        \Magento\Framework\App\Cache\Type\Config $configCacheType,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Checkout\Model\Session $resourceSession,
+        \Magento\Directory\Model\Resource\Country\CollectionFactory $countryCollectionFactory,
+        \Magento\Directory\Model\Resource\Region\CollectionFactory $regionCollectionFactory,
+        CustomerAccountService $customerAccountService,
+        CustomerAddressService $customerAddressService,
+        AddressConfig $addressConfig,
+        \Magento\Framework\App\Http\Context $httpContext,
+        \Magento\Tax\Helper\Data $taxData,
+        array $data = array()
+    ) {
+        parent::__construct(
+            $context,
+            $coreData,
+            $configCacheType,
+            $customerSession,
+            $resourceSession,
+            $countryCollectionFactory,
+            $regionCollectionFactory,
+            $customerAccountService,
+            $customerAddressService,
+            $addressConfig,
+            $httpContext,
+            $data
+        );
+        $this->_taxData = $taxData;
+    }
+
+
     /**
      * @return Address
      */
@@ -105,6 +161,19 @@ class Progress extends \Magento\Checkout\Block\Onepage\AbstractOnepage
         return $this->getCheckout()->getStepData($currentStep, 'complete');
     }
 
+    /**
+     * Get selected shipping method price
+     *
+     * @param bool $inclTax
+     * @return string
+     */
+    protected function _getShippingPrice($inclTax)
+    {
+        $address = $this->getQuote()->getShippingAddress();
+        $rate = $address->getShippingRateByCode($address->getShippingMethod());
+        return $this->formatPrice($this->_taxData->getShippingPrice($rate->getPrice(), $inclTax, $address));
+    }
+
     /**
      * Get quote shipping price including tax
      *
@@ -112,8 +181,7 @@ class Progress extends \Magento\Checkout\Block\Onepage\AbstractOnepage
      */
     public function getShippingPriceInclTax()
     {
-        $inclTax = $this->getQuote()->getShippingAddress()->getShippingInclTax();
-        return $this->formatPrice($inclTax);
+        return $this->_getShippingPrice(true);
     }
 
     /**
@@ -121,7 +189,7 @@ class Progress extends \Magento\Checkout\Block\Onepage\AbstractOnepage
      */
     public function getShippingPriceExclTax()
     {
-        return $this->formatPrice($this->getQuote()->getShippingAddress()->getShippingAmount());
+        return $this->_getShippingPrice(false);
     }
 
     /**
diff --git a/app/code/Magento/Checkout/view/frontend/js/opcheckout.js b/app/code/Magento/Checkout/view/frontend/js/opcheckout.js
index 6cbf17ea205f1ac41a63de7577e042bb7207752e..67e28df2a6ec9db06b5a29e5f8eb6f286d2a4f09 100644
--- a/app/code/Magento/Checkout/view/frontend/js/opcheckout.js
+++ b/app/code/Magento/Checkout/view/frontend/js/opcheckout.js
@@ -136,6 +136,10 @@
                     alert($.mage.__('Please choose to register or to checkout as a guest.'));
                     return false;
                 }
+            } else {
+                if (json.registrationUrl) {
+                    window.location.href = json.registrationUrl;
+                }
             }
             this.element.trigger('login');
         },
diff --git a/app/code/Magento/Checkout/view/frontend/layout/default.xml b/app/code/Magento/Checkout/view/frontend/layout/default.xml
index 9c37284180336acb44e2e0189608e1e669185d87..dbb29a3360efea2f365672ad06fdf0f745162e3c 100644
--- a/app/code/Magento/Checkout/view/frontend/layout/default.xml
+++ b/app/code/Magento/Checkout/view/frontend/layout/default.xml
@@ -29,7 +29,7 @@
         <block class="Magento\Framework\View\Element\Js\Components" name="checkout_page_head_components" template="Magento_Checkout::js/components.phtml"/>
     </referenceBlock>
     <referenceContainer name="header-wrapper">
-        <block class="Magento\Checkout\Block\Cart\Sidebar" name="minicart" as="minicart" after="logo" template="cart/minicart.phtml">
+        <block class="Magento\Checkout\Block\Cart\Sidebar" name="minicart" as="minicart" after="logo" template="cart/minicart.phtml" cacheable="false">
             <block class="Magento\Framework\View\Element\RendererList" name="checkout.cart.sidebar.item.renderers" as="renderer.list" />
             <container name="minicart.extra.info" as="minicart_info" label="My Cart Extra info"/>
             <container name="topCart.extra_actions" as="extra_actions" label="My Cart Extra Actions">
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Indexer/Price/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Indexer/Price/Configurable.php
index a212ebfaf0207735215666f5c7662a29a6ff5c3b..e76573e8f783913cf85f04a3f94dafd21e434ceb 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Indexer/Price/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Indexer/Price/Configurable.php
@@ -38,10 +38,7 @@ class Configurable extends \Magento\Catalog\Model\Resource\Product\Indexer\Price
         $this->useIdxTable(true);
         $this->beginTransaction();
         try {
-            $this->_prepareFinalPriceData();
-            $this->_applyCustomOption();
-            $this->_applyConfigurableOption();
-            $this->_movePriceDataToIndexTable();
+            $this->reindex();
             $this->commit();
         } catch (\Exception $e) {
             $this->rollBack();
@@ -58,11 +55,22 @@ class Configurable extends \Magento\Catalog\Model\Resource\Product\Indexer\Price
      */
     public function reindexEntity($entityIds)
     {
-        $this->_prepareFinalPriceData($entityIds);
-        $this->_applyCustomOption();
-        $this->_applyConfigurableOption();
-        $this->_movePriceDataToIndexTable();
+        $this->reindex($entityIds);
+        return $this;
+    }
 
+    /**
+     * @param null|int|array $entityIds
+     * @return \Magento\ConfigurableProduct\Model\Resource\Product\Indexer\Price\Configurable
+     */
+    protected function reindex($entityIds = null)
+    {
+        if ($this->hasEntity() || !empty($entityIds)) {
+            $this->_prepareFinalPriceData($entityIds);
+            $this->_applyCustomOption();
+            $this->_applyConfigurableOption();
+            $this->_movePriceDataToIndexTable();
+        }
         return $this;
     }
 
diff --git a/app/code/Magento/Core/Model/TemplateEngine/Decorator/DebugHints.php b/app/code/Magento/Core/Model/TemplateEngine/Decorator/DebugHints.php
index fef7a79f0f93ea3d8265328d113053149cfa3e0a..bcdf4988d40b713c94211d7b4904ccf6982c2e7a 100644
--- a/app/code/Magento/Core/Model/TemplateEngine/Decorator/DebugHints.php
+++ b/app/code/Magento/Core/Model/TemplateEngine/Decorator/DebugHints.php
@@ -72,10 +72,8 @@ class DebugHints implements \Magento\Framework\View\TemplateEngineInterface
     protected function _renderTemplateHints($blockHtml, $templateFile)
     {
         return <<<HTML
-<div style="position:relative; border:1px dotted red; margin:6px 2px; padding:18px 2px 2px 2px; zoom:1;">
-<div style="position:absolute; left:0; top:0; padding:2px 5px; background:red; color:white; font:normal 11px Arial;
-text-align:left !important; z-index:998;" onmouseover="this.style.zIndex='999'"
-onmouseout="this.style.zIndex='998'" title="{$templateFile}">{$templateFile}</div>
+<div class="debugging-hints" style="position: relative; border: 1px dotted red; margin: 6px 2px; padding: 18px 2px 2px 2px;">
+<div class="debugging-hint-template-file" style="position: absolute; top: 0; padding: 2px 5px; font: normal 11px Arial; background: red; left: 0; color: white;" onmouseover="this.style.zIndex = 999;" onmouseout="this.style.zIndex = 'auto';" title="{$templateFile}">{$templateFile}</div>
 {$blockHtml}
 </div>
 HTML;
@@ -92,9 +90,7 @@ HTML;
     {
         $blockClass = get_class($block);
         return <<<HTML
-<div style="position:absolute; right:0; top:0; padding:2px 5px; background:red; color:blue; font:normal 11px Arial;
-text-align:left !important; z-index:998;" onmouseover="this.style.zIndex='999'" onmouseout="this.style.zIndex='998'"
-title="{$blockClass}">{$blockClass}</div>
+<div class="debugging-hint-block-class" style="position: absolute; top: 0; padding: 2px 5px; font: normal 11px Arial; background: red; right: 0; color: blue;" onmouseover="this.style.zIndex = 999;" onmouseout="this.style.zIndex = 'auto';" title="{$blockClass}">{$blockClass}</div>
 {$blockHtml}
 HTML;
     }
diff --git a/app/code/Magento/Customer/Block/Account/AuthorizationLink.php b/app/code/Magento/Customer/Block/Account/AuthorizationLink.php
index 75a0caf77595cd20809bcd075a301c1640bf6a69..76e7b9422dcd79e8c4a4e8de6f6653be925d51d3 100644
--- a/app/code/Magento/Customer/Block/Account/AuthorizationLink.php
+++ b/app/code/Magento/Customer/Block/Account/AuthorizationLink.php
@@ -62,7 +62,6 @@ class AuthorizationLink extends \Magento\Framework\View\Element\Html\Link
         parent::__construct($context, $data);
         $this->httpContext = $httpContext;
         $this->_customerHelper = $customerHelper;
-        $this->_isScopePrivate = true;
         $this->_postDataHelper = $postDataHelper;
     }
 
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Cart.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Cart.php
index 1c0405df23b264a29dd958b88d333d9ba334cd13..b1c1f9f35957b8391d04f573e3e973d7404c3427 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Cart.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Cart.php
@@ -51,6 +51,11 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     protected $_quoteFactory;
 
+    /**
+     * @var \Magento\Sales\Model\Quote
+     */
+    protected $quote = null;
+
     /**
      * @var string
      */
@@ -70,7 +75,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
         \Magento\Sales\Model\QuoteFactory $quoteFactory,
         \Magento\Framework\Data\CollectionFactory $dataCollectionFactory,
         \Magento\Framework\Registry $coreRegistry,
-        array $data = array()
+        array $data = []
     ) {
         $this->_dataCollectionFactory = $dataCollectionFactory;
         $this->_coreRegistry = $coreRegistry;
@@ -107,10 +112,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     protected function _prepareCollection()
     {
-        $customerId = $this->getCustomerId();
-        $storeIds = $this->_storeManager->getWebsite($this->getWebsiteId())->getStoreIds();
-
-        $quote = $this->_quoteFactory->create()->setSharedStoreIds($storeIds)->loadByCustomer($customerId);
+        $quote = $this->getQuote();
 
         if ($quote) {
             $collection = $quote->getItemsCollection(false);
@@ -118,7 +120,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
             $collection = $this->_dataCollectionFactory->create();
         }
 
-        $collection->addFieldToFilter('parent_item_id', array('null' => true));
+        $collection->addFieldToFilter('parent_item_id', ['null' => true]);
 
         $this->setCollection($collection);
 
@@ -130,72 +132,68 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     protected function _prepareColumns()
     {
-        $this->addColumn('product_id', array('header' => __('ID'), 'index' => 'product_id', 'width' => '100px'));
+        $this->addColumn('product_id', ['header' => __('ID'), 'index' => 'product_id', 'width' => '100px']);
 
         $this->addColumn(
             'name',
-            array(
+            [
                 'header' => __('Product'),
                 'index' => 'name',
                 'renderer' => 'Magento\Customer\Block\Adminhtml\Edit\Tab\View\Grid\Renderer\Item'
-            )
+            ]
         );
 
-        $this->addColumn('sku', array('header' => __('SKU'), 'index' => 'sku', 'width' => '100px'));
+        $this->addColumn('sku', ['header' => __('SKU'), 'index' => 'sku', 'width' => '100px']);
 
         $this->addColumn(
             'qty',
-            array('header' => __('Quantity'), 'index' => 'qty', 'type' => 'number', 'width' => '60px')
+            ['header' => __('Quantity'), 'index' => 'qty', 'type' => 'number', 'width' => '60px']
         );
 
         $this->addColumn(
             'price',
-            array(
+            [
                 'header' => __('Price'),
                 'index' => 'price',
                 'type' => 'currency',
-                'currency_code' => (string)$this->_scopeConfig->getValue(
-                    Currency::XML_PATH_CURRENCY_BASE,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                )
-            )
+                'currency_code' => $this->getQuote()->getQuoteCurrencyCode(),
+                'rate' => $this->getQuote()->getBaseToQuoteRate(),
+            ]
         );
 
         $this->addColumn(
             'total',
-            array(
+            [
                 'header' => __('Total'),
                 'index' => 'row_total',
                 'type' => 'currency',
-                'currency_code' => (string)$this->_scopeConfig->getValue(
-                    Currency::XML_PATH_CURRENCY_BASE,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                )
-            )
+                'currency_code' => $this->getQuote()->getQuoteCurrencyCode(),
+                'rate' => 1,
+            ]
         );
 
         $this->addColumn(
             'action',
-            array(
+            [
                 'header' => __('Action'),
                 'index' => 'quote_item_id',
                 'renderer' => 'Magento\Customer\Block\Adminhtml\Grid\Renderer\Multiaction',
                 'filter' => false,
                 'sortable' => false,
-                'actions' => array(
-                    array(
+                'actions' => [
+                    [
                         'caption' => __('Configure'),
                         'url' => 'javascript:void(0)',
                         'process' => 'configurable',
                         'control_object' => $this->getJsObjectName() . 'cartControl'
-                    ),
-                    array(
+                    ],
+                    [
                         'caption' => __('Delete'),
                         'url' => '#',
                         'onclick' => 'return ' . $this->getJsObjectName() . 'cartControl.removeItem($item_id);'
-                    )
-                )
-            )
+                    ]
+                ]
+            ]
         );
 
         return parent::_prepareColumns();
@@ -216,7 +214,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     public function getGridUrl()
     {
-        return $this->getUrl('customer/*/cart', array('_current' => true, 'website_id' => $this->getWebsiteId()));
+        return $this->getUrl('customer/*/cart', ['_current' => true, 'website_id' => $this->getWebsiteId()]);
     }
 
     /**
@@ -226,7 +224,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     public function getGridParentHtml()
     {
-        $templateName = $this->_viewFileSystem->getFilename($this->_parentTemplate, array('_relative' => true));
+        $templateName = $this->_viewFileSystem->getFilename($this->_parentTemplate, ['_relative' => true]);
         return $this->fetchView($templateName);
     }
 
@@ -235,6 +233,22 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     public function getRowUrl($row)
     {
-        return $this->getUrl('catalog/product/edit', array('id' => $row->getProductId()));
+        return $this->getUrl('catalog/product/edit', ['id' => $row->getProductId()]);
+    }
+
+    /**
+     * Get the quote of the cart
+     *
+     * @return \Magento\Sales\Model\Quote
+     */
+    protected function getQuote()
+    {
+        if (null === $this->quote) {
+            $customerId = $this->getCustomerId();
+            $storeIds = $this->_storeManager->getWebsite($this->getWebsiteId())->getStoreIds();
+
+            $this->quote = $this->_quoteFactory->create()->setSharedStoreIds($storeIds)->loadByCustomer($customerId);
+        }
+        return $this->quote;
     }
 }
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php
index eb016530c3793f0c722c6792470d702c008b402c..508e396ff906357c674b50cf699afee1744a4d04 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/View/Cart.php
@@ -50,6 +50,11 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     protected $_quoteFactory;
 
+    /**
+     * @var \Magento\Sales\Model\Quote
+     */
+    protected $quote = null;
+
     /**
      * Constructor
      *
@@ -66,7 +71,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
         \Magento\Sales\Model\QuoteFactory $quoteFactory,
         \Magento\Framework\Data\CollectionFactory $dataCollectionFactory,
         \Magento\Framework\Registry $coreRegistry,
-        array $data = array()
+        array $data = []
     ) {
         $this->_dataCollectionFactory = $dataCollectionFactory;
         $this->_coreRegistry = $coreRegistry;
@@ -95,16 +100,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     protected function _prepareCollection()
     {
-        $quote = $this->_quoteFactory->create();
-        // set website to quote, if any
-        if ($this->getWebsiteId()) {
-            $quote->setWebsite($this->_storeManager->getWebsite($this->getWebsiteId()));
-        }
-
-        $currentCustomerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
-        if (!empty($currentCustomerId)) {
-            $quote->loadByCustomer($currentCustomerId);
-        }
+        $quote = $this->getQuote();
 
         if ($quote) {
             $collection = $quote->getItemsCollection(false);
@@ -112,7 +108,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
             $collection = $this->_dataCollectionFactory->create();
         }
 
-        $collection->addFieldToFilter('parent_item_id', array('null' => true));
+        $collection->addFieldToFilter('parent_item_id', ['null' => true]);
         $this->setCollection($collection);
 
         return parent::_prepareCollection();
@@ -123,38 +119,34 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     protected function _prepareColumns()
     {
-        $this->addColumn('product_id', array('header' => __('ID'), 'index' => 'product_id', 'width' => '100px'));
+        $this->addColumn('product_id', ['header' => __('ID'), 'index' => 'product_id', 'width' => '100px']);
 
-        $this->addColumn('name', array('header' => __('Product'), 'index' => 'name'));
+        $this->addColumn('name', ['header' => __('Product'), 'index' => 'name']);
 
-        $this->addColumn('sku', array('header' => __('SKU'), 'index' => 'sku', 'width' => '100px'));
+        $this->addColumn('sku', ['header' => __('SKU'), 'index' => 'sku', 'width' => '100px']);
 
-        $this->addColumn('qty', array('header' => __('Qty'), 'index' => 'qty', 'type' => 'number', 'width' => '60px'));
+        $this->addColumn('qty', ['header' => __('Qty'), 'index' => 'qty', 'type' => 'number', 'width' => '60px']);
 
         $this->addColumn(
             'price',
-            array(
+            [
                 'header' => __('Price'),
                 'index' => 'price',
                 'type' => 'currency',
-                'currency_code' => (string)$this->_scopeConfig->getValue(
-                    Currency::XML_PATH_CURRENCY_BASE,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                )
-            )
+                'currency_code' => $this->getQuote()->getQuoteCurrencyCode(),
+                'rate' => $this->getQuote()->getBaseToQuoteRate(),
+            ]
         );
 
         $this->addColumn(
             'total',
-            array(
+            [
                 'header' => __('Total'),
                 'index' => 'row_total',
                 'type' => 'currency',
-                'currency_code' => (string)$this->_scopeConfig->getValue(
-                    Currency::XML_PATH_CURRENCY_BASE,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                )
-            )
+                'currency_code' => $this->getQuote()->getQuoteCurrencyCode(),
+                'rate' => 1,
+            ]
         );
 
         return parent::_prepareColumns();
@@ -165,7 +157,7 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
      */
     public function getRowUrl($row)
     {
-        return $this->getUrl('catalog/product/edit', array('id' => $row->getProductId()));
+        return $this->getUrl('catalog/product/edit', ['id' => $row->getProductId()]);
     }
 
     /**
@@ -175,4 +167,23 @@ class Cart extends \Magento\Backend\Block\Widget\Grid\Extended
     {
         return $this->getCollection()->getSize() >= 0;
     }
+
+    /**
+     * Get quote
+     *
+     * @return \Magento\Sales\Model\Quote
+     */
+    protected function getQuote()
+    {
+        if (null == $this->quote) {
+            $storeIds = $this->_storeManager->getWebsite($this->getWebsiteId())->getStoreIds();
+            $this->quote = $this->_quoteFactory->create()->setSharedStoreIds($storeIds);
+
+            $currentCustomerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
+            if (!empty($currentCustomerId)) {
+                $this->quote->loadByCustomer($currentCustomerId);
+            }
+        }
+        return $this->quote;
+    }
 }
diff --git a/app/code/Magento/Customer/etc/adminhtml/di.xml b/app/code/Magento/Customer/etc/adminhtml/di.xml
index aa627b839c7fee9a95f782d4a1af8cfabba54529..7417e1ccfdafc9e9b3b48a8ee12fadfa17e4699e 100644
--- a/app/code/Magento/Customer/etc/adminhtml/di.xml
+++ b/app/code/Magento/Customer/etc/adminhtml/di.xml
@@ -35,4 +35,11 @@
             <argument name="modelName" xsi:type="string">Magento\Customer\Model\Backend\Customer</argument>
         </arguments>
     </type>
+    <type name="Magento\Core\Model\Url\SecurityInfo">
+        <arguments>
+            <argument name="secureUrlList" xsi:type="array">
+                <item name="customer" xsi:type="string">/customer/</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Downloadable/Helper/Download.php b/app/code/Magento/Downloadable/Helper/Download.php
index d648d70fe51b8a7ff674e187a6a895af36bc251b..e93c41183f01fbe2ba383c01cc719ec0497af12f 100644
--- a/app/code/Magento/Downloadable/Helper/Download.php
+++ b/app/code/Magento/Downloadable/Helper/Download.php
@@ -127,6 +127,11 @@ class Download extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_workingDirectory;
 
+    /**
+     * @var \Magento\Framework\Session\SessionManagerInterface
+     */
+    protected $_session;
+
     /**
      * @param \Magento\Framework\App\Helper\Context $context
      * @param \Magento\Core\Helper\Data $coreData
@@ -134,6 +139,7 @@ class Download extends \Magento\Framework\App\Helper\AbstractHelper
      * @param \Magento\Core\Helper\File\Storage\Database $coreFileStorageDb
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Framework\App\Filesystem $filesystem
+     * @param \Magento\Framework\Session\SessionManagerInterface $session
      */
     public function __construct(
         \Magento\Framework\App\Helper\Context $context,
@@ -141,13 +147,15 @@ class Download extends \Magento\Framework\App\Helper\AbstractHelper
         \Magento\Downloadable\Helper\File $downloadableFile,
         \Magento\Core\Helper\File\Storage\Database $coreFileStorageDb,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\App\Filesystem $filesystem
+        \Magento\Framework\App\Filesystem $filesystem,
+        \Magento\Framework\Session\SessionManagerInterface $session
     ) {
         $this->_coreData = $coreData;
         $this->_downloadableFile = $downloadableFile;
         $this->_coreFileStorageDb = $coreFileStorageDb;
         $this->_scopeConfig = $scopeConfig;
         $this->_filesystem = $filesystem;
+        $this->_session = $session;
 
         parent::__construct($context);
     }
@@ -281,6 +289,7 @@ class Download extends \Magento\Framework\App\Helper\AbstractHelper
     public function output()
     {
         $handle = $this->_getHandle();
+        $this->_session->writeClose();
         while (true == ($buffer = $handle->read(1024))) {
             echo $buffer;
         }
diff --git a/app/code/Magento/Downloadable/Model/Resource/Indexer/Price.php b/app/code/Magento/Downloadable/Model/Resource/Indexer/Price.php
index 543bc9111857b1265d6cc4d3477ee212257d8e07..517310353cd9d9ca09ae12f2560bcfdc89cd6d82 100644
--- a/app/code/Magento/Downloadable/Model/Resource/Indexer/Price.php
+++ b/app/code/Magento/Downloadable/Model/Resource/Indexer/Price.php
@@ -33,6 +33,7 @@ class Price extends \Magento\Catalog\Model\Resource\Product\Indexer\Price\Defaul
     /**
      * Reindex temporary (price result data) for all products
      *
+     * @throws \Exception
      * @return $this
      */
     public function reindexAll()
@@ -40,10 +41,7 @@ class Price extends \Magento\Catalog\Model\Resource\Product\Indexer\Price\Defaul
         $this->useIdxTable(true);
         $this->beginTransaction();
         try {
-            $this->_prepareFinalPriceData();
-            $this->_applyCustomOption();
-            $this->_applyDownloadableLink();
-            $this->_movePriceDataToIndexTable();
+            $this->reindex();
             $this->commit();
         } catch (\Exception $e) {
             $this->rollBack();
@@ -60,10 +58,21 @@ class Price extends \Magento\Catalog\Model\Resource\Product\Indexer\Price\Defaul
      */
     public function reindexEntity($entityIds)
     {
-        $this->_prepareFinalPriceData($entityIds);
-        $this->_applyCustomOption();
-        $this->_applyDownloadableLink();
-        $this->_movePriceDataToIndexTable();
+        return $this->reindex($entityIds);
+    }
+
+    /**
+     * @param null|int|array $entityIds
+     * @return \Magento\Catalog\Model\Resource\Product\Indexer\Price\DefaultPrice
+     */
+    protected function reindex($entityIds = null)
+    {
+        if ($this->hasEntity() || !empty($entityIds)) {
+            $this->_prepareFinalPriceData($entityIds);
+            $this->_applyCustomOption();
+            $this->_applyDownloadableLink();
+            $this->_movePriceDataToIndexTable();
+        }
 
         return $this;
     }
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php
index 537c22011abcdb0faff55e455582d3b58b0e2394..6f9f80768f503b49584a672c0e155d3d8fab0a1c 100644
--- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php
@@ -188,11 +188,20 @@ class Template extends \Magento\Backend\App\Action
         $template = $this->_initTemplate('id');
         if ($template->getId()) {
             try {
-                $template->delete();
-                // display success message
-                $this->messageManager->addSuccess(__('The email template has been deleted.'));
-                // go to grid
-                $this->_redirect('adminhtml/*/');
+                // check if the template is currently used
+                if (count($template->getSystemConfigPathsWhereUsedCurrently()) == 0) {
+                    $template->delete();
+                    // display success message
+                    $this->messageManager->addSuccess(__('The email template has been deleted.'));
+                    $this->_objectManager->get('Magento\Framework\App\ReinitableConfig')->reinit();
+                    // go to grid
+                    $this->_redirect('adminhtml/*/');
+                    return;
+                }
+                // display error  message
+                $this->messageManager->addError(__('The email template is currently being used.'));
+                // redirect to edit form
+                $this->_redirect('adminhtml/*/edit', array('id' => $template->getId()));
                 return;
             } catch (\Magento\Framework\Model\Exception $e) {
                 $this->messageManager->addError($e->getMessage());
diff --git a/app/code/Magento/Email/Model/Template/Filter.php b/app/code/Magento/Email/Model/Template/Filter.php
index 99228b3472ab2068276e3fbdbe6e96c9a31d31cf..2844c2e671e7650736cb5a3f42d8372c9606ecc2 100644
--- a/app/code/Magento/Email/Model/Template/Filter.php
+++ b/app/code/Magento/Email/Model/Template/Filter.php
@@ -244,12 +244,12 @@ class Filter extends \Magento\Framework\Filter\Template
      */
     public function blockDirective($construction)
     {
-        $skipParams = array('type', 'id', 'output');
+        $skipParams = array('class', 'id', 'output');
         $blockParameters = $this->_getIncludeParameters($construction[2]);
+        $block = null;
 
-        if (isset($blockParameters['type'])) {
-            $type = $blockParameters['type'];
-            $block = $this->_layout->createBlock($type, null, array('data' => $blockParameters));
+        if (isset($blockParameters['class'])) {
+            $block = $this->_layout->createBlock($blockParameters['class'], null, array('data' => $blockParameters));
         } elseif (isset($blockParameters['id'])) {
             $block = $this->_layout->createBlock('Magento\Cms\Block\Block');
             if ($block) {
@@ -257,19 +257,19 @@ class Filter extends \Magento\Framework\Filter\Template
             }
         }
 
-        if ($block) {
-            $block->setBlockParams($blockParameters);
-            foreach ($blockParameters as $k => $v) {
-                if (in_array($k, $skipParams)) {
-                    continue;
-                }
-                $block->setDataUsingMethod($k, $v);
-            }
-        }
-
         if (!$block) {
             return '';
         }
+
+        $block->setBlockParams($blockParameters);
+        foreach ($blockParameters as $k => $v) {
+            if (in_array($k, $skipParams)) {
+                continue;
+            }
+            $block->setDataUsingMethod($k, $v);
+        }
+
+
         if (isset($blockParameters['output'])) {
             $method = $blockParameters['output'];
         }
diff --git a/app/code/Magento/GroupedProduct/Model/Resource/Product/Indexer/Price/Grouped.php b/app/code/Magento/GroupedProduct/Model/Resource/Product/Indexer/Price/Grouped.php
index 01d49e41fa0436a89618a9814afd9a2e31206b32..fc97f57c21fd37bd0389e271e267cea985d8b23a 100644
--- a/app/code/Magento/GroupedProduct/Model/Resource/Product/Indexer/Price/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Model/Resource/Product/Indexer/Price/Grouped.php
@@ -30,6 +30,7 @@ class Grouped extends \Magento\Catalog\Model\Resource\Product\Indexer\Price\Defa
     /**
      * Reindex temporary (price result data) for all products
      *
+     * @throws \Exception
      * @return \Magento\GroupedProduct\Model\Resource\Product\Indexer\Price\Grouped
      */
     public function reindexAll()
@@ -68,6 +69,9 @@ class Grouped extends \Magento\Catalog\Model\Resource\Product\Indexer\Price\Defa
      */
     protected function _prepareGroupedProductPriceData($entityIds = null)
     {
+        if (!$this->hasEntity() && empty($entityIds)) {
+            return $this;
+        }
         $write = $this->_getWriteAdapter();
         $table = $this->getIdxTable();
 
diff --git a/app/code/Magento/Integration/Helper/Oauth/Data.php b/app/code/Magento/Integration/Helper/Oauth/Data.php
index 5057c88ca6a280d52da9a799bbde31e8dd136e13..0b0930e82f72dce3078f825ffc963d1dbb5eee97 100644
--- a/app/code/Magento/Integration/Helper/Oauth/Data.php
+++ b/app/code/Magento/Integration/Helper/Oauth/Data.php
@@ -85,7 +85,7 @@ class Data
             self::XML_PATH_CLEANUP_PROBABILITY,
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
         );
-        return $configValue > 0 ? 1 == mt_rand(1, $configValue) : false;
+        return $configValue > 0 ? 1 == \Magento\Framework\Math\Random::getRandomNumber(1, $configValue) : false;
     }
 
     /**
diff --git a/app/code/Magento/Newsletter/Model/Subscriber.php b/app/code/Magento/Newsletter/Model/Subscriber.php
index 7959382d1e8164479052d6fb8615e405b8aad3fa..ed26646c3fa58c48e1fcfa5d7d5006c70140b5a2 100644
--- a/app/code/Magento/Newsletter/Model/Subscriber.php
+++ b/app/code/Magento/Newsletter/Model/Subscriber.php
@@ -383,7 +383,7 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
         $char = array_merge(range('a', 'z'), range(0, 9));
         $charLen = count($char) - 1;
         for ($i = 0; $i < $length; $i++) {
-            $disc = mt_rand(0, $charLen);
+            $disc = \Magento\Framework\Math\Random::getRandomNumber(0, $charLen);
             $par[$i] = $char[$disc];
             $id = $id . $char[$disc];
         }
diff --git a/app/code/Magento/Ogone/Model/Config.php b/app/code/Magento/Ogone/Model/Config.php
index 82f71d6919d434d7babd50887f244091f5b4ae67..3454c8269656e5b32c693c944453a2179101e215 100644
--- a/app/code/Magento/Ogone/Model/Config.php
+++ b/app/code/Magento/Ogone/Model/Config.php
@@ -42,7 +42,6 @@ class Config extends \Magento\Payment\Model\Config
 
     /**
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig
      * @param \Magento\Payment\Model\Method\Factory $paymentMethodFactory
      * @param \Magento\Framework\Locale\ListsInterface $localeLists
      * @param \Magento\Framework\Config\DataInterface $dataStorage
@@ -51,14 +50,13 @@ class Config extends \Magento\Payment\Model\Config
      */
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig,
         \Magento\Payment\Model\Method\Factory $paymentMethodFactory,
         \Magento\Framework\Locale\ListsInterface $localeLists,
         \Magento\Framework\Config\DataInterface $dataStorage,
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Framework\Encryption\EncryptorInterface $encryptor
     ) {
-        parent::__construct($scopeConfig, $coreConfig, $paymentMethodFactory, $localeLists, $dataStorage);
+        parent::__construct($scopeConfig, $paymentMethodFactory, $localeLists, $dataStorage);
         $this->_urlBuilder = $urlBuilder;
         $this->_encryptor = $encryptor;
     }
@@ -73,7 +71,11 @@ class Config extends \Magento\Payment\Model\Config
     public function getConfigData($path, $storeId = null)
     {
         if (!empty($path)) {
-            return $this->_scopeConfig->getValue(self::OGONE_PAYMENT_PATH . $path, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId);
+            return $this->_scopeConfig->getValue(
+                self::OGONE_PAYMENT_PATH . $path,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                $storeId
+            );
         }
         return false;
     }
@@ -86,7 +88,7 @@ class Config extends \Magento\Payment\Model\Config
      */
     public function getShaInCode($storeId = null)
     {
-        return $this->_encryptor->decrypt($this->getConfigData('secret_key_in', $storeId));
+        return $this->getConfigData('secret_key_in', $storeId);
     }
 
     /**
@@ -96,7 +98,7 @@ class Config extends \Magento\Payment\Model\Config
      */
     public function getShaOutCode($storeId = null)
     {
-        return $this->_encryptor->decrypt($this->getConfigData('secret_key_out', $storeId));
+        return $this->getConfigData('secret_key_out', $storeId);
     }
 
     /**
diff --git a/app/code/Magento/Ogone/etc/config.xml b/app/code/Magento/Ogone/etc/config.xml
index 4cb2fa3949969f479f9696dfa7f40caa87fc3615..5de0a47cc9cf31516673fd25b0ace9828e13f98e 100644
--- a/app/code/Magento/Ogone/etc/config.xml
+++ b/app/code/Magento/Ogone/etc/config.xml
@@ -29,7 +29,8 @@
             <ogone>
                 <model>Magento\Ogone\Model\Api</model>
                 <title>Ogone</title>
-                <secret_key backend_model="Magento\Backend\Model\Config\Backend\Encrypted" />
+                <secret_key_in backend_model="Magento\Backend\Model\Config\Backend\Encrypted" />
+                <secret_key_out backend_model="Magento\Backend\Model\Config\Backend\Encrypted" />
                 <payment_action>authorize</payment_action>
                 <hashing_algorithm>sha256</hashing_algorithm>
                 <template>ogone</template>
diff --git a/app/code/Magento/PageCache/view/frontend/js/form-key.js b/app/code/Magento/PageCache/view/frontend/js/form-key.js
index f9d98aa1ce73e54217f093a04b6f5dd2c0013ca6..c2910a8c9088f421e9fe4d9fd7c623b51456025a 100644
--- a/app/code/Magento/PageCache/view/frontend/js/form-key.js
+++ b/app/code/Magento/PageCache/view/frontend/js/form-key.js
@@ -50,5 +50,7 @@
             return result;
         }
     });
-    $('body').formKey();
+    $(function() {
+        $('body').formKey();
+    });
 })(jQuery);
\ No newline at end of file
diff --git a/app/code/Magento/Payment/Model/Config.php b/app/code/Magento/Payment/Model/Config.php
index f0d92b9ae804a385c6a4a677d27bd06eb6ae715e..d1fe2bda8defb6bb840c16c3234faab132ddebf3 100644
--- a/app/code/Magento/Payment/Model/Config.php
+++ b/app/code/Magento/Payment/Model/Config.php
@@ -68,21 +68,18 @@ class Config
      * Construct
      *
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig
      * @param \Magento\Payment\Model\Method\Factory $paymentMethodFactory
      * @param \Magento\Framework\Locale\ListsInterface $localeLists
      * @param \Magento\Framework\Config\DataInterface $dataStorage
      */
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Framework\App\Config\ScopeConfigInterface $coreConfig,
         \Magento\Payment\Model\Method\Factory $paymentMethodFactory,
         \Magento\Framework\Locale\ListsInterface $localeLists,
         \Magento\Framework\Config\DataInterface $dataStorage
     ) {
         $this->_scopeConfig = $scopeConfig;
         $this->_dataStorage = $dataStorage;
-        $this->_coreConfig = $coreConfig;
         $this->_methodFactory = $paymentMethodFactory;
         $this->_localeLists = $localeLists;
     }
diff --git a/app/code/Magento/Paypal/Model/Report/Settlement.php b/app/code/Magento/Paypal/Model/Report/Settlement.php
index a2d65af7f5e75f98c5ad4438fe89411f8dbc34cd..c5f84e716051569245c1d83ca3d22780c9d0c303 100644
--- a/app/code/Magento/Paypal/Model/Report/Settlement.php
+++ b/app/code/Magento/Paypal/Model/Report/Settlement.php
@@ -238,7 +238,7 @@ class Settlement extends \Magento\Framework\Model\AbstractModel
         $listing = $this->_filterReportsList($connection->rawls());
         foreach ($listing as $filename => $attributes) {
 
-            $localCsv = 'PayPal_STL_' . uniqid(mt_rand()) . time() . '.csv';
+            $localCsv = 'PayPal_STL_' . uniqid(\Magento\Framework\Math\Random::getRandomNumber()) . time() . '.csv';
             if ($connection->read($filename, $this->_tmpDirectory->getAbsolutePath($localCsv))) {
                 if (!$this->_tmpDirectory->isWritable($localCsv)) {
                     throw new \Magento\Framework\Model\Exception(__('We cannot create a target file for reading reports.'));
diff --git a/app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_index.xml b/app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_index.xml
index 5835257bfd2797b73f9aa2067e86769ebb580bc0..e132249e513d694b39d6c5b24b94cb75c72759c5 100644
--- a/app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_index.xml
+++ b/app/code/Magento/Persistent/view/frontend/layout/checkout_onepage_index.xml
@@ -24,15 +24,10 @@
  */
 -->
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
-    <referenceBlock name="head.components">
-        <block class="Magento\Framework\View\Element\Js\Components" name="persistent_onepage_head_components" template="Magento_Persistent::js/components.phtml"/>
-    </referenceBlock>
     <referenceContainer name="form.login.additional.info">
         <block class="Magento\Persistent\Block\Form\Remember" name="persistent.remember.me" template="remember_me.phtml" before="-"/>
-        <block class="Magento\Framework\View\Element\Template" name="persistent.remember.me.tooltip" template="Magento_Persistent::remember_me_tooltip.phtml"/>
     </referenceContainer>
     <referenceContainer name="form.billing.additional.info">
         <block class="Magento\Persistent\Block\Form\Remember" name="persistent.remember.me.billing" template="remember_me.phtml" before="-"/>
-        <block class="Magento\Framework\View\Element\Template" name="persistent.remember.me.tooltip.billing" template="Magento_Persistent::remember_me_tooltip.phtml"/>
     </referenceContainer>
 </layout>
diff --git a/app/code/Magento/Persistent/view/frontend/layout/customer_account_create.xml b/app/code/Magento/Persistent/view/frontend/layout/customer_account_create.xml
index 1347bd0811b578d722806876edc291d84216e1d5..9283d79d8a4b6c471cc05c571c1a6b3518896b5d 100644
--- a/app/code/Magento/Persistent/view/frontend/layout/customer_account_create.xml
+++ b/app/code/Magento/Persistent/view/frontend/layout/customer_account_create.xml
@@ -24,11 +24,7 @@
  */
 -->
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
-    <referenceBlock name="head.components">
-        <block class="Magento\Framework\View\Element\Js\Components" name="persistent_customer_create_head_components" template="Magento_Persistent::js/components.phtml"/>
-    </referenceBlock>
     <referenceContainer name="form.additional.info">
         <block class="Magento\Persistent\Block\Form\Remember" name="persistent.remember.me" template="remember_me.phtml" before="-"/>
-        <block class="Magento\Framework\View\Element\Template" name="persistent.remember.me.tooltip" template="Magento_Persistent::remember_me_tooltip.phtml"/>
     </referenceContainer>
 </layout>
diff --git a/app/code/Magento/Persistent/view/frontend/layout/customer_account_login.xml b/app/code/Magento/Persistent/view/frontend/layout/customer_account_login.xml
index 389517c16ecf3692dba58073338acce406577517..9283d79d8a4b6c471cc05c571c1a6b3518896b5d 100644
--- a/app/code/Magento/Persistent/view/frontend/layout/customer_account_login.xml
+++ b/app/code/Magento/Persistent/view/frontend/layout/customer_account_login.xml
@@ -24,11 +24,7 @@
  */
 -->
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
-    <referenceBlock name="head.components">
-        <block class="Magento\Framework\View\Element\Js\Components" name="persistent_customer_login_head_components" template="Magento_Persistent::js/components.phtml"/>
-    </referenceBlock>
     <referenceContainer name="form.additional.info">
         <block class="Magento\Persistent\Block\Form\Remember" name="persistent.remember.me" template="remember_me.phtml" before="-"/>
-        <block class="Magento\Framework\View\Element\Template" name="persistent.remember.me.tooltip" template="Magento_Persistent::remember_me_tooltip.phtml"/>
     </referenceContainer>
 </layout>
diff --git a/app/code/Magento/Persistent/view/frontend/remember-me-popup.js b/app/code/Magento/Persistent/view/frontend/remember-me-popup.js
deleted file mode 100644
index 4b395fd9ed78161af132069281ed9adef6fa6dca..0000000000000000000000000000000000000000
--- a/app/code/Magento/Persistent/view/frontend/remember-me-popup.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Academic Free License (AFL 3.0)
- * that is bundled with this package in the file LICENSE_AFL.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/afl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-/*jshint browser:true jquery:true*/
-(function ($) {
-    $.widget('mage.rememberMePopup', {
-        options: {
-            closeBtn: '.action.close',
-            windowOverlayTemplate: '<div class="window overlay"></div>',
-            popupBlockTemplate: '<div class="popup block remember tip active">'  +
-                                '<span class="action close"></span>' +
-                                '<div class="title">' +
-                                    '<strong>${title}</strong>'+
-                                '</div>' +
-                                '<div class="content">' +
-                                    '<p>${content}</p>' +
-                                '</div>' +
-                            '</div>'
-        },
-
-        _create: function() {
-            this._renderWindowOverLay();
-            this._renderPopupBlock();
-            $('body').append(this.windowOverlay.hide());
-            $('body').append(this.popupBlock.hide());
-            this.element.find('a').on('click', $.proxy(this._showPopUp, this));
-        },
-
-        /**
-         * Add windowOverlay block to body
-         * If windowOverlay is not an option, use default template
-         * @private
-         */
-        _renderWindowOverLay: function() {
-            if (this.options.windowOverlay) {
-                this.windowOverlay = $(this.options.windowOverlay);
-            } else {
-                $.template('windowOverlayTemplate', this.options.windowOverlayTemplate);
-                this.windowOverlay = $.tmpl('windowOverlayTemplate').hide();
-            }
-            this.windowOverlay.height($('body').height());
-        },
-
-        /**
-         * Add popupBlock to body
-         * If popupBlock is not an option, use default template
-         * @private
-         */
-        _renderPopupBlock: function() {
-            if (this.options.popupBlock) {
-                this.popupBlock = $(this.options.popupBlock);
-            } else {
-                $.template('popupBlockTemplate', this.options.popupBlockTemplate);
-                this.popupBlock = $.tmpl('popupBlockTemplate',
-                    {title: this.options.title, content: this.options.content});
-            }
-            this.popupBlock.find(this.options.closeBtn).on('click', $.proxy(this._hidePopUp, this));
-        },
-
-        /**
-         * show windowOverlay and popupBlock
-         * @private
-         */
-        _showPopUp: function() {
-            this.windowOverlay.show();
-            this.popupBlock.show();
-            return false;
-        },
-
-        /**
-         * hide windowOverlay and popupBlock
-         * @private
-         */
-        _hidePopUp: function() {
-            this.windowOverlay.hide();
-            this.popupBlock.hide();
-        }
-    });
-})(jQuery);
\ No newline at end of file
diff --git a/app/code/Magento/Persistent/view/frontend/remember_me.phtml b/app/code/Magento/Persistent/view/frontend/remember_me.phtml
index 54efe69afdbf13294d2794925524638ec6b5600a..3d30e91cd1c39b0443a44de9bf66d3f5599e06ea 100644
--- a/app/code/Magento/Persistent/view/frontend/remember_me.phtml
+++ b/app/code/Magento/Persistent/view/frontend/remember_me.phtml
@@ -33,6 +33,10 @@
     <?php $rememberMeId = 'remember_me' . $this->getRandomString(10); ?>
     <input type="checkbox" name="persistent_remember_me" class="checkbox" id="<?php echo $rememberMeId; ?>"<?php if ($this->isRememberMeChecked()): ?> checked="checked"<?php endif; ?> title="<?php echo __('Remember Me') ?>" />
     <label for="<?php echo $rememberMeId; ?>" class="label"><span><?php echo __('Remember Me') ?></span></label>
-    <a class="link tip" href="#"><?php echo __('What\'s this?') ?></a>
+    <span class="tooltip wrapper">
+        <a class="link tooltip toggle" href="#"><?php echo __('What\'s this?') ?></a>
+        <span class="tooltip content">
+            <?php echo __('Check &quot;Remember Me&quot; to access your shopping cart on this computer when you are logged out')?>
+        </span>
+    </span>
 </div>
-
diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php
index 176dc4ca2d1fa85b70494641f4ad478913162b74..c9b48275f79028df25c4b752dc90db9d8271d6bc 100644
--- a/app/code/Magento/Sales/Model/Order.php
+++ b/app/code/Magento/Sales/Model/Order.php
@@ -2464,7 +2464,7 @@ class Order extends \Magento\Sales\Model\AbstractModel
             $this->unsShippingAddressId();
         }
 
-        $this->setData('protect_code', substr(md5(uniqid(mt_rand(), true) . ':' . microtime(true)), 5, 6));
+        $this->setData('protect_code', substr(md5(uniqid(\Magento\Framework\Math\Random::getRandomNumber(), true) . ':' . microtime(true)), 5, 6));
         return $this;
     }
 
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml
index 58ac6acc42c3035e3b0c19b08c5a5c5036319554..3e7e62cbc8f1d42a52e3dcbfa2820c71bff2b854 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_grid_block.xml
@@ -166,6 +166,7 @@
                         <argument name="header" xsi:type="string" translate="true">Grand Total (Base)</argument>
                         <argument name="type" xsi:type="string">currency</argument>
                         <argument name="currency" xsi:type="string">base_currency_code</argument>
+                        <argument name="rate" xsi:type="string">1</argument>
                         <argument name="index" xsi:type="string">base_grand_total</argument>
                         <argument name="header_css_class" xsi:type="string">col-gtbase</argument>
                         <argument name="column_css_class" xsi:type="string">col-gtbase</argument>
diff --git a/app/code/Magento/Sales/view/email/shipment_new.html b/app/code/Magento/Sales/view/email/shipment_new.html
index 68c65c5ebba018a867e9d4ec816c0abbd0793af2..4c0f8f332d606ba594dfced4827a97a3a583671b 100644
--- a/app/code/Magento/Sales/view/email/shipment_new.html
+++ b/app/code/Magento/Sales/view/email/shipment_new.html
@@ -96,7 +96,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif;
                     </table>
                     <br/>
                     {{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}}
-                    {{block type='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}}
+                    {{block class='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}}
                     <p style="font-size:12px; margin:0 10px 10px 0">{{var comment}}</p>
                 </td>
             </tr>
diff --git a/app/code/Magento/Sales/view/email/shipment_new_guest.html b/app/code/Magento/Sales/view/email/shipment_new_guest.html
index e4bf8b235a3b71108b73bf3c4e40a950468027cf..334bfe7504fd789c49564ee611426592dc70346e 100644
--- a/app/code/Magento/Sales/view/email/shipment_new_guest.html
+++ b/app/code/Magento/Sales/view/email/shipment_new_guest.html
@@ -94,7 +94,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif;
                     </table>
                     <br/>
                     {{layout handle="sales_email_order_shipment_items" shipment=$shipment order=$order}}
-                    {{block type='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}}
+                    {{block class='Magento\\Framework\\View\\Element\\Template' area='frontend' template='Magento_Sales::email/shipment/track.phtml' shipment=$shipment order=$order}}
                     <p style="font-size:12px; margin:0 10px 10px 0">{{var comment}}</p>
                 </td>
             </tr>
diff --git a/app/code/Magento/SalesRule/Model/Coupon/Massgenerator.php b/app/code/Magento/SalesRule/Model/Coupon/Massgenerator.php
index 292c6ac602a1e05267c9a6167562e18d94d39ac2..d47bb71a5afaa842d31533bbaebd683877a6a081 100644
--- a/app/code/Magento/SalesRule/Model/Coupon/Massgenerator.php
+++ b/app/code/Magento/SalesRule/Model/Coupon/Massgenerator.php
@@ -129,7 +129,7 @@ class Massgenerator extends \Magento\Framework\Model\AbstractModel implements
         $code = '';
         $charsetSize = count($charset);
         for ($i = 0; $i < $length; $i++) {
-            $char = $charset[mt_rand(0, $charsetSize - 1)];
+            $char = $charset[\Magento\Framework\Math\Random::getRandomNumber(0, $charsetSize - 1)];
             if ($split > 0 && $i % $split == 0 && $i != 0) {
                 $char = $splitChar . $char;
             }
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php
index 703c92391526d6503a38bd305af489999438e36d..89797072eaf91b6723c09ebbcd669cd8dc39ba82 100644
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php
@@ -740,7 +740,7 @@ class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShip
         $page = new \Zend_Pdf_Page($xSize, $ySize);
 
         imageinterlace($image, 0);
-        $tmpFileName = $directory->getAbsolutePath('shipping_labels_' . uniqid(mt_rand()) . time() . '.png');
+        $tmpFileName = $directory->getAbsolutePath('shipping_labels_' . uniqid(\Magento\Framework\Math\Random::getRandomNumber()) . time() . '.png');
         imagepng($image, $tmpFileName);
         $pdfImage = \Zend_Pdf_Image::imageWithPath($tmpFileName);
         $page->drawImage($pdfImage, 0, 0, $xSize, $ySize);
diff --git a/app/code/Magento/Shipping/view/adminhtml/create/items.phtml b/app/code/Magento/Shipping/view/adminhtml/create/items.phtml
index 4e11459c57ee9a6b21d36d8dd4f18c83e06ecba4..055d69d0a798dd4f9f752ada0c0bfa96b5ff6f24 100644
--- a/app/code/Magento/Shipping/view/adminhtml/create/items.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/create/items.phtml
@@ -96,18 +96,15 @@ if (sendEmailCheckbox) {
     Event.observe(sendEmailCheckbox, 'change', bindSendEmail);
     bindSendEmail();
 }
-function bindSendEmail()
-{
+function bindSendEmail() {
     if (sendEmailCheckbox.checked == true) {
         notifyCustomerCheckbox.disabled = false;
-        //shipmentCommentText.disabled = false;
     }
     else {
         notifyCustomerCheckbox.disabled = true;
-        //shipmentCommentText.disabled = true;
     }
 }
-function toggleCreateLabelCheckbox(){
+function toggleCreateLabelCheckbox() {
     var checkbox = $('create_shipping_label');
     var submitButton = checkbox.up('.order-totals').select('.submit-button span')[0];
     if (checkbox.checked) {
@@ -116,7 +113,11 @@ function toggleCreateLabelCheckbox(){
         submitButton.innerText = submitButton.innerText.replace(/\.\.\.$/, '');
     }
 }
-function submitShipment(btn){
+function submitShipment(btn) {
+    if (!validQtyItems()) {
+        alert('<?php echo __('Invalid value(s) for Qty to Ship') ?>');
+        return;
+    }
     var checkbox = $(btn).up('.order-totals').select('#create_shipping_label')[0];
     if (checkbox && checkbox.checked) {
         packaging.showWindow();
@@ -130,5 +131,15 @@ function submitShipment(btn){
         jQuery('#edit_form').triggerHandler('save');
     }
 }
+function validQtyItems() {
+    var valid = true;
+    $$('.qty-item').each(function(item) {
+        var val = parseFloat(item.value);
+        if (isNaN(val) || val < 0) {
+            valid = false;
+        }
+    });
+    return valid;
+}
 //]]>
 </script>
diff --git a/app/code/Magento/Shipping/view/adminhtml/create/items/renderer/default.phtml b/app/code/Magento/Shipping/view/adminhtml/create/items/renderer/default.phtml
index a46e9d55141e146043227736a052a653db2a2403..64d3910cbc163ae9620c67fd89a02d1630cb3755 100644
--- a/app/code/Magento/Shipping/view/adminhtml/create/items/renderer/default.phtml
+++ b/app/code/Magento/Shipping/view/adminhtml/create/items/renderer/default.phtml
@@ -28,7 +28,7 @@
     <td class="col-ordered-qty"><?php echo $this->getColumnHtml($_item, 'qty') ?></td>
     <td class="col-qty <?php if ($this->isShipmentRegular()): ?>last<?php endif; ?>">
         <?php if ($this->canShipPartiallyItem()): ?>
-            <input type="text" class="input-text" name="shipment[items][<?php echo $_item->getOrderItemId() ?>]" value="<?php echo $_item->getQty()*1 ?>" />
+            <input type="text" class="input-text qty-item" name="shipment[items][<?php echo $_item->getOrderItemId() ?>]" value="<?php echo $_item->getQty()*1 ?>" />
         <?php else: ?>
             <?php echo $_item->getQty()*1 ?>
         <?php endif; ?>
diff --git a/app/code/Magento/Tax/Helper/Data.php b/app/code/Magento/Tax/Helper/Data.php
index 63bd13db488cf32814b1b77db226f5f05d8bb040..c3c4371f52800af9bb27e62fb89a8e06b220660e 100644
--- a/app/code/Magento/Tax/Helper/Data.php
+++ b/app/code/Magento/Tax/Helper/Data.php
@@ -32,12 +32,24 @@ use Magento\Tax\Model\Config;
  */
 class Data extends \Magento\Framework\App\Helper\AbstractHelper
 {
+    /**
+     * Price conversion constant for positive
+     */
     const PRICE_CONVERSION_PLUS = 1;
 
+    /**
+     * Price conversion constant for negative
+     */
     const PRICE_CONVERSION_MINUS = 2;
 
+    /**
+     * Default tax class for customers
+     */
     const CONFIG_DEFAULT_CUSTOMER_TAX_CLASS = 'tax/classes/default_customer_tax_class';
 
+    /**
+     * Default tax class for products
+     */
     const CONFIG_DEFAULT_PRODUCT_TAX_CLASS = 'tax/classes/default_product_tax_class';
 
     /**
@@ -48,45 +60,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     protected $_config;
 
     /**
+     * Tax calculator
+     *
      * @var \Magento\Tax\Model\Calculation
      */
     protected $_calculation;
 
-    /**
-     * @var mixed
-     */
-    protected $_displayTaxColumn;
-
-    /**
-     * @var mixed
-     */
-    protected $_taxData;
-
-    /**
-     * @var mixed
-     */
-    protected $_priceIncludesTax;
-
-    /**
-     * @var mixed
-     */
-    protected $_shippingPriceIncludesTax;
-
-    /**
-     * @var mixed
-     */
-    protected $_applyTaxAfterDiscount;
-
-    /**
-     * @var int
-     */
-    protected $_priceDisplayType;
-
-    /**
-     * @var mixed
-     */
-    protected $_shippingPriceDisplayType;
-
     /**
      * Postcode cut to this length when creating search templates
      *
@@ -135,6 +114,11 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_taxItemFactory;
 
+    /**
+     * @var \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory
+     */
+    protected $_orderTaxCollectionFactory;
+
     /**
      * @var \Magento\Framework\Locale\ResolverInterface
      */
@@ -151,6 +135,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      * @param \Magento\Framework\Locale\FormatInterface $localeFormat
      * @param \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory
      * @param \Magento\Tax\Model\Resource\Sales\Order\Tax\ItemFactory $taxItemFactory
+     * @param \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory $orderTaxCollectionFactory
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
      */
     public function __construct(
@@ -164,6 +149,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         \Magento\Framework\Locale\FormatInterface $localeFormat,
         \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory,
         \Magento\Tax\Model\Resource\Sales\Order\Tax\ItemFactory $taxItemFactory,
+        \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory $orderTaxCollectionFactory,
         \Magento\Framework\Locale\ResolverInterface $localeResolver
     ) {
         parent::__construct($context);
@@ -176,6 +162,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         $this->_localeFormat = $localeFormat;
         $this->_attributeFactory = $attributeFactory;
         $this->_taxItemFactory = $taxItemFactory;
+        $this->_orderTaxCollectionFactory = $orderTaxCollectionFactory;
         $this->_localeResolver = $localeResolver;
     }
 
@@ -254,13 +241,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
-     * Output
+     * Retrieves the "including tax" or "excluding tax" label
      *
      * @param bool $flag
-     * @param null|int|string|Store $store
      * @return string
      */
-    public function getIncExcText($flag, $store = null)
+    public function getIncExcText($flag)
     {
         return $flag ? __('Incl. Tax') : __('Excl. Tax');
     }
@@ -314,7 +300,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         }
 
         if ($res === false) {
-            $res = $this->displayTaxColumn($store);
+            $res = $this->displayTaxColumn();
         }
         return $res;
     }
@@ -443,10 +429,9 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     /**
      * Check if need display tax column in for shopping cart/order items
      *
-     * @param null|string|bool|int|Store $store
      * @return bool
      */
-    public function displayTaxColumn($store = null)
+    public function displayTaxColumn()
     {
         return $this->_config->displayCartPricesBoth();
     }
@@ -488,8 +473,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     protected function _getAllRatesByProductClass($store = null)
     {
         $result = array();
-        $originRate = $this->_calculation->getRateOriginRequest($store);
-        $rates = $this->_calculation->getRatesForAllProductTaxClasses($originRate);
+        $defaultRate = $this->_calculation->getDefaultRateRequest($store);
+        $rates = $this->_calculation->getRatesForAllProductTaxClasses($defaultRate);
         foreach ($rates as $class => $rate) {
             $result["value_{$class}"] = $rate;
         }
@@ -507,6 +492,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      * @param   null|int $ctc customer tax class
      * @param   null|string|bool|int|Store $store
      * @param   bool $priceIncludesTax flag what price parameter contain tax
+     * @param   bool $roundPrice
      * @return  float
      */
     public function getPrice(
@@ -517,7 +503,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         $billingAddress = null,
         $ctc = null,
         $store = null,
-        $priceIncludesTax = null
+        $priceIncludesTax = null,
+        $roundPrice = true
     ) {
         if (!$price) {
             return $price;
@@ -541,8 +528,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
             }
         }
         if ($taxClassId && $priceIncludesTax) {
-            $request = $this->_calculation->getRateRequest(false, false, false, $store);
-            $includingPercent = $this->_calculation->getRate($request->setProductClassId($taxClassId));
+            if ($this->isCrossBorderTradeEnabled($store)) {
+                $includingPercent = $percent;
+            } else {
+                $request = $this->_calculation->getRateOriginRequest($store);
+                $includingPercent = $this->_calculation->getRate($request->setProductClassId($taxClassId));
+            }
         }
 
         if ($percent === false || is_null($percent)) {
@@ -552,39 +543,34 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         }
 
         $product->setTaxPercent($percent);
+        if ($product->getAppliedRates() == null) {
+            $request = $this->_calculation->getRateRequest($shippingAddress, $billingAddress, $ctc, $store);
+            $request->setProductClassId($taxClassId);
+            $appliedRates = $this->_calculation->getAppliedRates($request);
+            $product->setAppliedRates($appliedRates);
+        }
 
         if (!is_null($includingTax)) {
             if ($priceIncludesTax) {
                 if ($includingTax) {
                     /**
-                     * Recalculate price include tax in case of different rates
+                     * Recalculate price include tax in case of different rates.  Otherwise price remains the same.
                      */
                     if ($includingPercent != $percent) {
-                        $price = $this->_calculatePrice($price, $includingPercent, false);
-                        /**
-                         * Using regular rounding. Ex:
-                         * price incl tax   = 52.76
-                         * store tax rate   = 19.6%
-                         * customer tax rate= 19%
-                         *
-                         * price excl tax = 52.76 / 1.196 = 44.11371237 ~ 44.11
-                         * tax = 44.11371237 * 0.19 = 8.381605351 ~ 8.38
-                         * price incl tax = 52.49531773 ~ 52.50 != 52.49
-                         *
-                         * that why we need round prices excluding tax before applying tax
-                         * this calculation is used for showing prices on catalog pages
-                         */
-                        if ($percent != 0) {
-                            $price = $this->getCalculator()->round($price);
-                            $price = $this->_calculatePrice($price, $percent, true);
-                        }
+                        // determine the customer's price that includes tax
+                        $price = $this->_calculatePriceInclTax($price, $includingPercent, $percent, $store);
                     }
                 } else {
                     $price = $this->_calculatePrice($price, $includingPercent, false);
                 }
             } else {
                 if ($includingTax) {
-                    $price = $this->_calculatePrice($price, $percent, true);
+                    $appliedRates = $product->getAppliedRates();
+                    if (count($appliedRates) > 1) {
+                        $price = $this->_calculatePriceInclTaxWithMultipleRates($price, $appliedRates);
+                    } else {
+                        $price = $this->_calculatePrice($price, $percent, true);
+                    }
                 }
             }
         } else {
@@ -592,7 +578,18 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
                 switch ($this->getPriceDisplayType($store)) {
                     case Config::DISPLAY_TYPE_EXCLUDING_TAX:
                     case Config::DISPLAY_TYPE_BOTH:
-                        $price = $this->_calculatePrice($price, $includingPercent, false);
+                        if ($includingPercent != $percent) {
+                            // determine the customer's price that includes tax
+                            $taxablePrice = $this->_calculatePriceInclTax($price, $includingPercent, $percent, $store);
+                            // determine the customer's tax amount,
+                            // round tax unless $roundPrice is set explicitly to false
+                            $tax = $this->_calculation->calcTaxAmount($taxablePrice, $percent, true, $roundPrice);
+                            // determine the customer's price without taxes
+                            $price = $taxablePrice - $tax;
+                        } else {
+                            //round tax first unless $roundPrice is set to false explicitly
+                            $price = $this->_calculatePrice($price, $includingPercent, false, $roundPrice);
+                        }
                         break;
                     case Config::DISPLAY_TYPE_INCLUDING_TAX:
                         $price = $this->_calculatePrice($price, $includingPercent, false);
@@ -604,7 +601,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
             } else {
                 switch ($this->getPriceDisplayType($store)) {
                     case Config::DISPLAY_TYPE_INCLUDING_TAX:
-                        $price = $this->_calculatePrice($price, $percent, true);
+                        $appliedRates = $product->getAppliedRates();
+                        if (count($appliedRates) > 1) {
+                            $price = $this->_calculatePriceInclTaxWithMultipleRates($price, $appliedRates);
+                        } else {
+                            $price = $this->_calculatePrice($price, $percent, true);
+                        }
                         break;
                     case Config::DISPLAY_TYPE_BOTH:
                     case Config::DISPLAY_TYPE_EXCLUDING_TAX:
@@ -614,7 +616,29 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
                 }
             }
         }
-        return $store->roundPrice($price);
+        if ($roundPrice) {
+            return $store->roundPrice($price);
+        } else {
+            return $price;
+        }
+    }
+
+    /**
+     * Given a store price that includes tax at the store rate, this function will back out the store's tax, and add in
+     * the customer's tax.  Returns this new price which is the customer's price including tax.
+     *
+     * @param float $storePriceInclTax
+     * @param float $storePercent
+     * @param float $customerPercent
+     * @param null|int|string|Store $store
+     * @return float
+     */
+    protected function _calculatePriceInclTax($storePriceInclTax, $storePercent, $customerPercent, $store)
+    {
+        $priceExclTax         = $this->_calculatePrice($storePriceInclTax, $storePercent, false, false);
+        $customerTax          = $this->_calculation->calcTaxAmount($priceExclTax, $customerPercent, false, false);
+        $customerPriceInclTax = $store->roundPrice($priceExclTax + $customerTax);
+        return $customerPriceInclTax;
     }
 
     /**
@@ -640,34 +664,55 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     /**
      * Check if we have display in catalog prices including and excluding tax
      *
+     * @param  null|int|string|Store $store
      * @return bool
      */
-    public function displayBothPrices()
+    public function displayBothPrices($store = null)
     {
-        return $this->getPriceDisplayType() == Config::DISPLAY_TYPE_BOTH;
+        return $this->getPriceDisplayType($store) == Config::DISPLAY_TYPE_BOTH;
     }
 
     /**
-     * Calculate price including/excluding tax base on tax rate percent
+     * Calculate price including/excluding tax based on tax rate percent
      *
      * @param   float $price
      * @param   float $percent
-     * @param   bool $type true - for calculate price including tax and false if price excluding tax
+     * @param   bool  $type - true to calculate the price including tax or false if calculating price to exclude tax
+     * @param   bool  $roundTaxFirst
      * @return  float
      */
-    protected function _calculatePrice($price, $percent, $type)
+    protected function _calculatePrice($price, $percent, $type, $roundTaxFirst = false)
     {
         if ($type) {
-            $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, false, false);
+            $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, false, $roundTaxFirst);
             return $price + $taxAmount;
         } else {
-            $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, true, false);
+            $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, true, $roundTaxFirst);
             return $price - $taxAmount;
         }
     }
 
     /**
-     * @param bool $flag
+     * Calculate price including tax when multiple taxes is applied and rounded independently.
+     *
+     * @param  float $price
+     * @param  array $appliedRates
+     * @return float
+     */
+    protected function _calculatePriceInclTaxWithMultipleRates($price, $appliedRates)
+    {
+        $tax = 0;
+        foreach ($appliedRates as $appliedRate) {
+            $taxRate = $appliedRate['percent'];
+            $tax += $this->_calculation->round($price * $taxRate / 100);
+        }
+        return $tax + $price;
+    }
+
+    /**
+     * Returns the include / exclude tax label
+     *
+     * @param  bool $flag
      * @return string
      */
     public function getIncExcTaxLabel($flag)
@@ -677,6 +722,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
+     * Check if shipping prices include tax
+     *
      * @param null|string|bool|int|Store $store
      * @return bool
      */
@@ -686,6 +733,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
+     * Get shipping price display type
+     *
      * @param null|string|bool|int|Store $store
      * @return int
      */
@@ -695,6 +744,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
+     * Returns whether the shipping price should display with taxes included
+     *
      * @return bool
      */
     public function displayShippingPriceIncludingTax()
@@ -703,6 +754,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
+     * Returns whether the shipping price should display without taxes
+     *
      * @return bool
      */
     public function displayShippingPriceExcludingTax()
@@ -711,6 +764,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
+     * Returns whether the shipping price should display both with and without taxes
+     *
      * @return bool
      */
     public function displayShippingBothPrices()
@@ -719,6 +774,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
+     * Get tax class id specified for shipping tax estimation
+     *
      * @param null|string|bool|int|Store $store
      * @return int
      */
@@ -761,6 +818,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     }
 
     /**
+     * Returns the SQL for the price tax
+     *
      * @param string $priceField
      * @param string $taxClassField
      * @return string
@@ -771,7 +830,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
             return '';
         }
 
-        $request = $this->_calculation->getRateRequest(false, false, false);
+        $request = $this->_calculation->getDefaultRateRequest();
         $defaultTaxes = $this->_calculation->getRatesForAllProductTaxClasses($request);
 
         $request = $this->_calculation->getRateRequest();
@@ -779,7 +838,10 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
 
         $defaultTaxString = $currentTaxString = '';
 
-        $rateToVariable = array('defaultTaxString' => 'defaultTaxes', 'currentTaxString' => 'currentTaxes');
+        $rateToVariable = array(
+            'defaultTaxString' => 'defaultTaxes',
+            'currentTaxString' => 'currentTaxes',
+        );
         foreach ($rateToVariable as $rateVariable => $rateArray) {
             if (${$rateArray} && is_array(${$rateArray})) {
                 ${$rateVariable} = '';
@@ -944,8 +1006,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      *  $index => array(
      *      'tax_amount'        => $taxAmount,
      *      'base_tax_amount'   => $baseTaxAmount,
-     *      'hidden_tax_amount' => $hiddenTaxAmount
-     *      'title'             => $title
+     *      'hidden_tax_amount' => $hiddenTaxAmount,
+     *      'title'             => $title,
      *      'percent'           => $percent
      *  )
      * )
@@ -965,33 +1027,55 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
 
         $taxClassAmount = array();
         if ($current && $source) {
-            /** @var $item \Magento\Sales\Model\Order\Item */
-            foreach ($current->getItemsCollection() as $item) {
-                /** @var $taxCollection \Magento\Tax\Model\Resource\Sales\Order\Tax\Item */
-                $taxCollection = $this->_taxItemFactory->create();
-                $taxCollection->getTaxItemsByItemId(
-                    $item->getOrderItemId() ? $item->getOrderItemId() : $item->getItemId()
-                );
-
-                foreach ($taxCollection as $tax) {
-                    $taxClassId = $tax['tax_id'];
-                    $percent = $tax['tax_percent'];
-
-                    $price = $item->getRowTotal();
-                    $basePrice = $item->getBaseRowTotal();
-                    if ($this->applyTaxAfterDiscount($item->getStoreId())) {
-                        $price = $price - $item->getDiscountAmount() + $item->getHiddenTaxAmount();
-                        $basePrice = $basePrice - $item->getBaseDiscountAmount() + $item->getBaseHiddenTaxAmount();
-                    }
+            if ($current == $source) {
+                // use the actuals
+                $rates = $this->_getTaxRateSubtotals($source);
+                foreach ($rates['items'] as $rate) {
+                    $taxClassId = $rate['tax_id'];
+                    $taxClassAmount[$taxClassId]['tax_amount'] = $rate['amount'];
+                    $taxClassAmount[$taxClassId]['base_tax_amount'] = $rate['base_amount'];
+                    $taxClassAmount[$taxClassId]['title'] = $rate['title'];
+                    $taxClassAmount[$taxClassId]['percent'] = $rate['percent'];
+                }
+            } else {
+                // regenerate tax subtotals
+                // Calculate taxes for shipping
+                $shippingTaxAmount = $current->getShippingTaxAmount();
+                if ($shippingTaxAmount) {
+                    $shippingTax    = $this->getShippingTax($current);
+                    $taxClassAmount = array_merge($taxClassAmount, $shippingTax);
+                }
 
-                    if (isset($taxClassAmount[$taxClassId])) {
-                        $taxClassAmount[$taxClassId]['tax_amount'] += $price * $percent / 100;
-                        $taxClassAmount[$taxClassId]['base_tax_amount'] += $basePrice * $percent / 100;
-                    } else {
-                        $taxClassAmount[$taxClassId]['tax_amount'] = $price * $percent / 100;
-                        $taxClassAmount[$taxClassId]['base_tax_amount'] = $basePrice * $percent / 100;
-                        $taxClassAmount[$taxClassId]['title'] = $tax['title'];
-                        $taxClassAmount[$taxClassId]['percent'] = $tax['percent'];
+                /** @var $item \Magento\Sales\Model\Order\Item */
+                foreach ($current->getItemsCollection() as $item) {
+                    /** @var $taxCollection \Magento\Tax\Model\Resource\Sales\Order\Tax\Item */
+                    $taxCollection = $this->_taxItemFactory->create();
+                    $taxCollection->getTaxItemsByItemId(
+                        $item->getOrderItemId() ? $item->getOrderItemId() : $item->getItemId()
+                    );
+
+                    foreach ($taxCollection as $tax) {
+                        $taxClassId = $tax['tax_id'];
+                        $percent = $tax['tax_percent'];
+
+                        $price = $item->getRowTotal();
+                        $basePrice = $item->getBaseRowTotal();
+                        if ($this->applyTaxAfterDiscount($item->getStoreId())) {
+                            $price = $price - $item->getDiscountAmount() + $item->getHiddenTaxAmount();
+                            $basePrice = $basePrice - $item->getBaseDiscountAmount() + $item->getBaseHiddenTaxAmount();
+                        }
+                        $taxAmount = $price * $percent / 100;
+                        $baseTaxAmount = $basePrice * $percent / 100;
+
+                        if (isset($taxClassAmount[$taxClassId])) {
+                            $taxClassAmount[$taxClassId]['tax_amount'] += $taxAmount;
+                            $taxClassAmount[$taxClassId]['base_tax_amount'] += $baseTaxAmount;
+                        } else {
+                            $taxClassAmount[$taxClassId]['tax_amount'] = $taxAmount;
+                            $taxClassAmount[$taxClassId]['base_tax_amount'] = $baseTaxAmount;
+                            $taxClassAmount[$taxClassId]['title'] = $tax['title'];
+                            $taxClassAmount[$taxClassId]['percent'] = $tax['percent'];
+                        }
                     }
                 }
             }
@@ -1008,6 +1092,17 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $taxClassAmount;
     }
 
+    /**
+     * Returns the array of tax rates for the order
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return array
+     */
+    protected function _getTaxRateSubtotals($order)
+    {
+        return $this->_orderTaxCollectionFactory->create()->loadByOrder($order)->toArray();
+    }
+
     /**
      * Get calculated Shipping & Handling Tax
      *
@@ -1075,4 +1170,15 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
         );
     }
+
+    /**
+     * Return whether cross border trade is enabled or not
+     *
+     * @param   null|int|string|Store $store
+     * @return  bool
+     */
+    public function isCrossBorderTradeEnabled($store = null)
+    {
+        return (bool)$this->_config->crossBorderTradeEnabled($store);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Calculation.php b/app/code/Magento/Tax/Model/Calculation.php
index f9896b5168edf06b2c712e8abedb28212e42663d..8570082ea315b6167f3e1802eb1f68d8e393440f 100644
--- a/app/code/Magento/Tax/Model/Calculation.php
+++ b/app/code/Magento/Tax/Model/Calculation.php
@@ -31,52 +31,86 @@ use Magento\Customer\Service\V1\CustomerAddressServiceInterface as AddressServic
 use Magento\Customer\Service\V1\CustomerGroupServiceInterface as GroupServiceInterface;
 use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
 use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Tax\Model\Config;
 
 /**
  * Tax Calculation Model
  */
 class Calculation extends \Magento\Framework\Model\AbstractModel
 {
+    /**
+     * Identifier constant for Tax calculation before discount excluding TAX
+     */
     const CALC_TAX_BEFORE_DISCOUNT_ON_EXCL = '0_0';
 
+    /**
+     * Identifier constant for Tax calculation before discount including TAX
+     */
     const CALC_TAX_BEFORE_DISCOUNT_ON_INCL = '0_1';
 
+    /**
+     * Identifier constant for Tax calculation after discount excluding TAX
+     */
     const CALC_TAX_AFTER_DISCOUNT_ON_EXCL = '1_0';
 
+    /**
+     * Identifier constant for Tax calculation after discount including TAX
+     */
     const CALC_TAX_AFTER_DISCOUNT_ON_INCL = '1_1';
 
+    /**
+     * Identifier constant for unit based calculation
+     */
     const CALC_UNIT_BASE = 'UNIT_BASE_CALCULATION';
 
+    /**
+     * Identifier constant for row based calculation
+     */
     const CALC_ROW_BASE = 'ROW_BASE_CALCULATION';
 
+    /**
+     * Identifier constant for total based calculation
+     */
     const CALC_TOTAL_BASE = 'TOTAL_BASE_CALCULATION';
 
     /**
+     * Identifier constant for unit based calculation
+     *
      * @var array
      */
     protected $_rates = array();
 
     /**
+     * Identifier constant for row based calculation
+     *
      * @var array
      */
     protected $_ctc = array();
 
     /**
+     * Identifier constant for total based calculation
+     *
      * @var array
      */
     protected $_ptc = array();
 
     /**
+     * Cache to hold the rates
+     *
      * @var array
      */
     protected $_rateCache = array();
 
     /**
+     * Store the rate calculation process
+     *
      * @var array
      */
     protected $_rateCalculationProcess = array();
 
     /**
+     * Hold the customer
+     *
      * @var CustomerDataObject|bool
      */
     protected $_customer;
@@ -113,6 +147,13 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
      */
     protected $_classesFactory;
 
+    /**
+     * Tax configuration object
+     *
+     * @var Config
+     */
+    protected $_config;
+
     /**
      * @var GroupServiceInterface
      */
@@ -132,6 +173,7 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param Config $taxConfig
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Customer\Model\CustomerFactory $customerFactory
@@ -149,6 +191,7 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        Config $taxConfig,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Customer\Model\CustomerFactory $customerFactory,
@@ -162,6 +205,7 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
         array $data = array()
     ) {
         $this->_scopeConfig = $scopeConfig;
+        $this->_config = $taxConfig;
         $this->_storeManager = $storeManager;
         $this->_customerSession = $customerSession;
         $this->_customerFactory = $customerFactory;
@@ -402,6 +446,33 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
         return $request;
     }
 
+    /**
+     * Return the default rate request. It can be either based on store address or customer address
+     *
+     * @param null|int|string|Store $store
+     * @return \Magento\Framework\Object
+     */
+    public function getDefaultRateRequest($store = null)
+    {
+        if ($this->_isCrossBorderTradeEnabled($store)) {
+            //If cross border trade is enabled, we will use customer tax rate as store tax rate
+            return $this->getRateRequest(null, null, null, $store);
+        } else {
+            return $this->getRateOriginRequest($store);
+        }
+    }
+
+    /**
+     * Return whether cross border trade is enabled or not
+     *
+     * @param   null|int|string|Store $store
+     * @return  bool
+     */
+    protected function _isCrossBorderTradeEnabled($store = null)
+    {
+        return (bool)$this->_config->crossBorderTradeEnabled($store);
+    }
+
     /**
      * Get request object with information necessary for getting tax rate
      *
@@ -507,7 +578,7 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
         if (is_null($customerTaxClass) && $customerData->getId()) {
             $customerTaxClass = $this->_groupService->getGroup($customerData->getGroupId())->getTaxClassId();
         } elseif ($customerTaxClass === false || !$customerData->getId()) {
-            $customerTaxClass = $this->getDefaultCustomerTaxClass($store);
+            $customerTaxClass = $this->_groupService->getGroup(GroupServiceInterface::NOT_LOGGED_IN_ID)->getTaxClassId();
         }
 
         $request = new \Magento\Framework\Object();
@@ -589,6 +660,8 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
+     * Gets the tax rates by type
+     *
      * @param \Magento\Framework\Object $request
      * @param string|array $fieldName
      * @param string|array $type
@@ -608,6 +681,8 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
+     * Gets rates for all the product tax classes
+     *
      * @param \Magento\Framework\Object $request
      * @return array
      */
@@ -617,6 +692,8 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
+     * Gets rates for all the customer tax classes
+     *
      * @param \Magento\Framework\Object $request
      * @return array
      */
@@ -633,6 +710,10 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
      */
     public function getAppliedRates($request)
     {
+        if (!$request->getCountryId() || !$request->getCustomerClassId() || !$request->getProductClassId()) {
+            return array();
+        }
+
         $cacheKey = $this->_getRequestCacheKey($request);
         if (!isset($this->_rateCalculationProcess[$cacheKey])) {
             $this->_rateCalculationProcess[$cacheKey] = $this->_getResource()->getCalculationProcess($request);
@@ -641,6 +722,8 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
+     * Gets the calculation process
+     *
      * @param array $rates
      * @return array
      */
@@ -650,6 +733,8 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
+     * Get rates by customer tax class
+     *
      * @param int $customerTaxClass
      * @return array
      */
@@ -659,6 +744,8 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
+     * Get rates by customer and product classes
+     *
      * @param int $customerTaxClass
      * @param int $productTaxClass
      * @return array
diff --git a/app/code/Magento/Tax/Model/Calculation/Rate.php b/app/code/Magento/Tax/Model/Calculation/Rate.php
index 8a179c28e0bb635c1c3de2bea1277bae46812df1..fbb5f71e6241f89cf51f66c2c5e20e05f25ba37d 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rate.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rate.php
@@ -21,6 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Tax\Model\Calculation;
 
 /**
  * Tax Rate Model
@@ -44,17 +45,17 @@
  * @method int getZipTo()
  * @method \Magento\Tax\Model\Calculation\Rate setZipTo(int $value)
  */
-namespace Magento\Tax\Model\Calculation;
-
 class Rate extends \Magento\Framework\Model\AbstractModel
 {
     /**
-     * @var mixed
+     * List of tax titles
+     *
+     * @var array
      */
     protected $_titles = null;
 
     /**
-     * @var mixed
+     * @var \Magento\Tax\Model\Calculation\Rate\Title
      */
     protected $_titleModel = null;
 
@@ -104,7 +105,7 @@ class Rate extends \Magento\Framework\Model\AbstractModel
     /**
      * Prepare location settings and tax postcode before save rate
      *
-     * @return $this
+     * @return \Magento\Tax\Model\Calculation\Rate
      * @throws \Magento\Framework\Model\Exception
      */
     protected function _beforeSave()
@@ -120,7 +121,7 @@ class Rate extends \Magento\Framework\Model\AbstractModel
             throw new \Magento\Framework\Model\Exception(__('Please fill all required fields with valid information.'));
         }
 
-        if (!is_numeric($this->getRate()) || $this->getRate() <= 0) {
+        if (!is_numeric($this->getRate()) || $this->getRate() < 0) {
             throw new \Magento\Framework\Model\Exception(__('Rate Percent should be a positive number.'));
         }
 
@@ -166,7 +167,7 @@ class Rate extends \Magento\Framework\Model\AbstractModel
     /**
      * Save rate titles
      *
-     * @return $this
+     * @return \Magento\Tax\Model\Calculation\Rate
      */
     protected function _afterSave()
     {
@@ -178,7 +179,7 @@ class Rate extends \Magento\Framework\Model\AbstractModel
     /**
      * Processing object before delete data
      *
-     * @return $this
+     * @return \Magento\Tax\Model\Calculation\Rate
      * @throws \Magento\Framework\Model\Exception
      */
     protected function _beforeDelete()
@@ -193,7 +194,7 @@ class Rate extends \Magento\Framework\Model\AbstractModel
      * After rate delete
      * redeclared for dispatch tax_settings_change_after event
      *
-     * @return $this
+     * @return \Magento\Tax\Model\Calculation\Rate
      */
     protected function _afterDelete()
     {
@@ -202,6 +203,8 @@ class Rate extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
+     * Saves the tax titles
+     *
      * @param array|null $titles
      * @return void
      */
@@ -230,7 +233,9 @@ class Rate extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
-     * @return mixed
+     * Returns a tax title
+     *
+     * @return \Magento\Tax\Model\Calculation\Rate\Title
      */
     public function getTitleModel()
     {
@@ -241,7 +246,9 @@ class Rate extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
-     * @return mixed
+     * Returns the list of tax titles
+     *
+     * @return array
      */
     public function getTitles()
     {
@@ -252,7 +259,9 @@ class Rate extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
-     * @return $this
+     * Deletes all tax rates
+     *
+     * @return \Magento\Tax\Model\Calculation\Rate
      */
     public function deleteAllRates()
     {
@@ -265,7 +274,7 @@ class Rate extends \Magento\Framework\Model\AbstractModel
      * Load rate model by code
      *
      * @param  string $code
-     * @return $this
+     * @return \Magento\Tax\Model\Calculation\Rate
      */
     public function loadByCode($code)
     {
diff --git a/app/code/Magento/Tax/Model/Calculation/Rule.php b/app/code/Magento/Tax/Model/Calculation/Rule.php
index 0efad2bc0ff73f2363e05255047fbb928d882b30..86bd3f79decdacc2c9521c0d0643dc3a3617511c 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rule.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rule.php
@@ -21,6 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Tax\Model\Calculation;
 
 /**
  * Tax Rule Model
@@ -34,40 +35,8 @@
  * @method int getPosition()
  * @method \Magento\Tax\Model\Calculation\Rule setPosition(int $value)
  */
-namespace Magento\Tax\Model\Calculation;
-
 class Rule extends \Magento\Framework\Model\AbstractModel
 {
-    /**
-     * @var mixed
-     */
-    protected $_ctcs = null;
-
-    /**
-     * @var mixed
-     */
-    protected $_ptcs = null;
-
-    /**
-     * @var mixed
-     */
-    protected $_rates = null;
-
-    /**
-     * @var mixed
-     */
-    protected $_ctcModel = null;
-
-    /**
-     * @var mixed
-     */
-    protected $_ptcModel = null;
-
-    /**
-     * @var mixed
-     */
-    protected $_rateModel = null;
-
     /**
      * Prefix of model events names
      *
@@ -125,7 +94,7 @@ class Rule extends \Magento\Framework\Model\AbstractModel
 
     /**
      * After save rule
-     * Redeclared for populate rate calculations
+     * Re-declared for populate rate calculations
      *
      * @return $this
      */
@@ -139,7 +108,7 @@ class Rule extends \Magento\Framework\Model\AbstractModel
 
     /**
      * After rule delete
-     * re-declared for dispatch tax_settings_change_after event
+     * Re-declared for dispatch tax_settings_change_after event
      *
      * @return $this
      */
@@ -260,4 +229,18 @@ class Rule extends \Magento\Framework\Model\AbstractModel
 
         return $classes;
     }
+
+    /**
+     * Fetches rules by rate, customer tax class and product tax class
+     * and product tax class combination
+     *
+     * @param array $rateId
+     * @param array $customerTaxClassIds
+     * @param array $productTaxClassIds
+     * @return array
+     */
+    public function fetchRuleCodes($rateId, $customerTaxClassIds, $productTaxClassIds)
+    {
+        return $this->getResource()->fetchRuleCodes($rateId, $customerTaxClassIds, $productTaxClassIds);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Config.php b/app/code/Magento/Tax/Model/Config.php
index a660384ab1c128f5c9df9e1c7914653a493cbf68..83aae6075cfec2ec15499e13b9b70d97460dad6a 100644
--- a/app/code/Magento/Tax/Model/Config.php
+++ b/app/code/Magento/Tax/Model/Config.php
@@ -51,6 +51,8 @@ class Config
 
     const XML_PATH_ALGORITHM = 'tax/calculation/algorithm';
 
+    const CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED = 'tax/calculation/cross_border_trade_enabled';
+
     // tax defaults
     const CONFIG_XML_PATH_DEFAULT_COUNTRY = 'tax/defaults/country';
 
@@ -107,6 +109,15 @@ class Config
 
     const DISPLAY_TYPE_BOTH = 3;
 
+    /**
+     * Indexes for FPT Configuration Types
+     */
+    const FPT_NOT_TAXED = 0;
+
+    const FPT_TAXED = 1;
+
+    const FPT_LOADED_DISPLAY_WITH_TAX = 2;
+
     /**
      * @var bool|null
      */
@@ -732,4 +743,19 @@ class Config
             $store
         );
     }
+
+    /**
+     * Return the config value for self::CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED
+     *
+     * @param null|string|bool|int|Store $store
+     * @return bool
+     */
+    public function crossBorderTradeEnabled($store = null)
+    {
+        return (bool)$this->_scopeConfig->getValue(
+            self::CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            $store
+        );
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Rate/CsvImportHandler.php b/app/code/Magento/Tax/Model/Rate/CsvImportHandler.php
index 2bb5942d8079c86bf2aed0c751a89fef4e07f721..a2b63a019e519a2f4af00c7344f69ff652dcce29 100644
--- a/app/code/Magento/Tax/Model/Rate/CsvImportHandler.php
+++ b/app/code/Magento/Tax/Model/Rate/CsvImportHandler.php
@@ -252,7 +252,7 @@ class CsvImportHandler
         if (!empty($regionsCache[$countryCode][$regionCode])) {
             $regionId = $regionsCache[$countryCode][$regionCode] == '*' ? 0 : $regionsCache[$countryCode][$regionCode];
             // data with index 3 must represent postcode
-            $postCode = empty($rateData[3]) || $rateData[3] == '*' ? null : $rateData[3];
+            $postCode = empty($rateData[3]) ? null : $rateData[3];
             $modelData = array(
                 'code' => $rateData[0],
                 'tax_country_id' => $rateData[1],
diff --git a/app/code/Magento/Tax/Model/Resource/Calculation.php b/app/code/Magento/Tax/Model/Resource/Calculation.php
index 8dd4d4a9f13123153b2387accee92d65ad92d61e..46f270187aef17b8040912dc9020a61c4d883cfe 100644
--- a/app/code/Magento/Tax/Model/Resource/Calculation.php
+++ b/app/code/Magento/Tax/Model/Resource/Calculation.php
@@ -207,13 +207,18 @@ class Calculation extends \Magento\Framework\Model\Resource\Db\AbstractDb
                 $rates[$i + 1]['process']
             ) && $rates[$i + 1]['process'] != $rate['process']
             ) {
-                $row['percent'] = (100 + $totalPercent) * ($currentRate / 100);
+                if (!empty($rates[$i]['calculate_subtotal'])) {
+                    $row['percent'] = $currentRate;
+                    $totalPercent += $currentRate;
+                } else {
+                    $row['percent'] = $this->_collectPercent($totalPercent, $currentRate);
+                    $totalPercent += $row['percent'];
+                }
                 $row['id'] = implode($ids);
                 $result[] = $row;
                 $row = array();
                 $ids = array();
 
-                $totalPercent += (100 + $totalPercent) * ($currentRate / 100);
                 $currentRate = 0;
             }
         }
@@ -221,6 +226,18 @@ class Calculation extends \Magento\Framework\Model\Resource\Db\AbstractDb
         return $result;
     }
 
+    /**
+     * Return combined percent value
+     *
+     * @param float|int $percent
+     * @param float|int $rate
+     * @return float
+     */
+    protected function _collectPercent($percent, $rate)
+    {
+        return (100 + $percent) * ($rate / 100);
+    }
+
     /**
      * Create search templates for postcode
      *
@@ -236,7 +253,7 @@ class Calculation extends \Magento\Framework\Model\Resource\Db\AbstractDb
             $strlen = $len;
         }
 
-        $strArr = array($postcode, $postcode . '*');
+        $strArr = array((string)$postcode, $postcode . '*');
         if ($strlen > 1) {
             for ($i = 1; $i < $strlen; $i++) {
                 $strArr[] = sprintf('%s*', substr($postcode, 0, -$i));
@@ -305,7 +322,7 @@ class Calculation extends \Magento\Framework\Model\Resource\Db\AbstractDb
             $select->join(
                 array('rule' => $this->getTable('tax_calculation_rule')),
                 $ruleTableAliasName . ' = main_table.tax_calculation_rule_id',
-                array('rule.priority', 'rule.position')
+                array('rule.priority', 'rule.position', 'rule.calculate_subtotal')
             )->join(
                 array('rate' => $this->getTable('tax_calculation_rate')),
                 'rate.tax_calculation_rate_id = main_table.tax_calculation_rate_id',
@@ -417,7 +434,11 @@ class Calculation extends \Magento\Framework\Model\Resource\Db\AbstractDb
             $currentRate += $value;
 
             if (!isset($rates[$i + 1]) || $rates[$i + 1]['priority'] != $priority) {
-                $result += (100 + $result) * ($currentRate / 100);
+                if (!empty($rates[$i]['calculate_subtotal'])) {
+                    $result += $currentRate;
+                } else {
+                    $result += $this->_collectPercent($result, $currentRate);
+                }
                 $currentRate = 0;
             }
         }
diff --git a/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php b/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php
index e507eba83c0bd4ef27b795be41f1ffdbcd04c6f8..4392e219147952095e7375023b62c12771b2ece6 100644
--- a/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php
+++ b/app/code/Magento/Tax/Model/Resource/Calculation/Rate/Collection.php
@@ -30,6 +30,11 @@ namespace Magento\Tax\Model\Resource\Calculation\Rate;
 
 class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
 {
+    /**
+     * Value of fetched from DB of rules per cycle
+     */
+    const TAX_RULES_CHUNK_SIZE = 1000;
+
     /**
      * @var \Magento\Store\Model\StoreManagerInterface
      */
@@ -196,4 +201,32 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
         }
         return $result;
     }
+
+    /**
+     * Get rates array without memory leak
+     *
+     * @return array
+     */
+    public function getOptionRates()
+    {
+        $size = self::TAX_RULES_CHUNK_SIZE;
+        $page = 1;
+        $rates = array();
+        do {
+            $offset = $size * ($page - 1);
+            $this->getSelect()->reset();
+            $this->getSelect()
+                ->from(
+                    array('rates' => $this->getMainTable()),
+                    array('tax_calculation_rate_id', 'code')
+                )
+                ->limit($size, $offset);
+
+            $rates = array_merge($rates, $this->toOptionArray());
+            $this->clear();
+            $page++;
+        } while ($this->getSize() > $offset);
+
+        return $rates;
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Resource/Calculation/Rule.php b/app/code/Magento/Tax/Model/Resource/Calculation/Rule.php
index 9b3e0f94bba6dda887a058c5c4fd0efcf15180b9..b16cd4bec90701f436005262d45ea7767a2c14f4 100644
--- a/app/code/Magento/Tax/Model/Resource/Calculation/Rule.php
+++ b/app/code/Magento/Tax/Model/Resource/Calculation/Rule.php
@@ -50,4 +50,30 @@ class Rule extends \Magento\Framework\Model\Resource\Db\AbstractDb
         $this->_uniqueFields = array(array('field' => array('code'), 'title' => __('Code')));
         return $this;
     }
+
+    /**
+     * Fetches rules by rate, customer tax classes and product tax classes.  Returns array of rule codes.
+     *
+     * @param array $rateId
+     * @param array $customerTaxClassIds
+     * @param array $productTaxClassIds
+     * @return array
+     */
+    public function fetchRuleCodes($rateId, $customerTaxClassIds, $productTaxClassIds)
+    {
+        $adapter = $this->_getReadAdapter();
+        $select = $adapter->select()
+            ->from(array('main' => $this->getTable('tax_calculation')), null)
+            ->joinLeft(
+                array('d' => $this->getTable('tax_calculation_rule')),
+                'd.tax_calculation_rule_id = main.tax_calculation_rule_id',
+                array('d.code')
+            )
+            ->where('main.tax_calculation_rate_id in (?)', $rateId)
+            ->where('main.customer_tax_class_id in (?)', $customerTaxClassIds)
+            ->where('main.product_tax_class_id in (?)', $productTaxClassIds)
+            ->distinct(true);
+
+        return $adapter->fetchCol($select);
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
index fdbf31f0b8667e2119368cd6c19c7cca25b7aa37..7b1d6683e6f4a85579be5fc45ebf53fea14e7b90 100644
--- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
+++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
@@ -41,6 +41,13 @@ class Shipping extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
      */
     protected $_config = null;
 
+    /**
+     * Tax helper instance
+     *
+     * @var \Magento\Tax\Helper\Data|null
+     */
+    protected $_taxHelper = null;
+
     /**
      * Flag which is initialized when collect method is started and catalog prices include tax.
      * It is used for checking if store tax and customer tax requests are similar
@@ -61,12 +68,17 @@ class Shipping extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
      *
      * @param \Magento\Tax\Model\Calculation $calculation
      * @param \Magento\Tax\Model\Config $taxConfig
+     * @param \Magento\Tax\Helper\Data $taxHelper
      */
-    public function __construct(\Magento\Tax\Model\Calculation $calculation, \Magento\Tax\Model\Config $taxConfig)
-    {
+    public function __construct(
+        \Magento\Tax\Model\Calculation $calculation,
+        \Magento\Tax\Model\Config $taxConfig,
+        \Magento\Tax\Helper\Data $taxHelper
+    ) {
         $this->setCode('shipping');
         $this->_calculator = $calculation;
         $this->_config = $taxConfig;
+        $this->_taxHelper = $taxHelper;
     }
 
     /**
@@ -94,7 +106,12 @@ class Shipping extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
 
         $priceIncludesTax = $this->_config->shippingPriceIncludesTax($store);
         if ($priceIncludesTax) {
-            $this->_areTaxRequestsSimilar = $calc->compareRequests($addressTaxRequest, $storeTaxRequest);
+            if ($this->_taxHelper->isCrossBorderTradeEnabled($store)) {
+                $this->_areTaxRequestsSimilar = true;
+            } else {
+                $this->_areTaxRequestsSimilar =
+                    $this->_calculator->compareRequests($storeTaxRequest, $addressTaxRequest);
+            }
         }
 
         $shipping = $taxShipping = $address->getShippingAmount();
@@ -111,36 +128,54 @@ class Shipping extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
                 $taxable = $taxShipping;
                 $baseTaxable = $baseTaxShipping;
                 $isPriceInclTax = true;
+                $address->setTotalAmount('shipping', $shipping);
+                $address->setBaseTotalAmount('shipping', $baseShipping);
             } else {
                 $storeRate = $calc->getStoreRate($addressTaxRequest, $store);
                 $storeTax = $calc->calcTaxAmount($shipping, $storeRate, true, false);
                 $baseStoreTax = $calc->calcTaxAmount($baseShipping, $storeRate, true, false);
                 $shipping = $calc->round($shipping - $storeTax);
                 $baseShipping = $calc->round($baseShipping - $baseStoreTax);
-                $tax = $this->_round($calc->calcTaxAmount($shipping, $rate, false, false), $rate, false);
+                $tax = $this->_round($calc->calcTaxAmount($shipping, $rate, false, false), $rate, true);
                 $baseTax = $this->_round(
                     $calc->calcTaxAmount($baseShipping, $rate, false, false),
                     $rate,
-                    false,
+                    true,
                     'base'
                 );
                 $taxShipping = $shipping + $tax;
                 $baseTaxShipping = $baseShipping + $baseTax;
-                $taxable = $shipping;
-                $baseTaxable = $baseShipping;
-                $isPriceInclTax = false;
+                $taxable = $taxShipping;
+                $baseTaxable = $baseTaxShipping;
+                $isPriceInclTax = true;
+                $address->setTotalAmount('shipping', $shipping);
+                $address->setBaseTotalAmount('shipping', $baseShipping);
             }
         } else {
-            $tax = $this->_round($calc->calcTaxAmount($shipping, $rate, false, false), $rate, false);
-            $baseTax = $this->_round($calc->calcTaxAmount($baseShipping, $rate, false, false), $rate, false, 'base');
+            $appliedRates = $calc->getAppliedRates($addressTaxRequest);
+            $taxes = array();
+            $baseTaxes = array();
+            foreach ($appliedRates as $appliedRate) {
+                $taxRate = $appliedRate['percent'];
+                $taxId = $appliedRate['id'];
+                $taxes[] = $this->_round($calc->calcTaxAmount($shipping, $taxRate, false, false), $taxId, false);
+                $baseTaxes[] = $this->_round(
+                    $calc->calcTaxAmount($baseShipping, $taxRate, false, false),
+                    $taxId,
+                    false,
+                    'base'
+                );
+            }
+            $tax = array_sum($taxes);
+            $baseTax = array_sum($baseTaxes);
             $taxShipping = $shipping + $tax;
             $baseTaxShipping = $baseShipping + $baseTax;
             $taxable = $shipping;
             $baseTaxable = $baseShipping;
             $isPriceInclTax = false;
+            $address->setTotalAmount('shipping', $shipping);
+            $address->setBaseTotalAmount('shipping', $baseShipping);
         }
-        $address->setTotalAmount('shipping', $shipping);
-        $address->setBaseTotalAmount('shipping', $baseShipping);
         $address->setShippingInclTax($taxShipping);
         $address->setBaseShippingInclTax($baseTaxShipping);
         $address->setShippingTaxable($taxable);
diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php
index 25d3bfb0b5dde081d6029d8045e385cae3adb6e6..c3a32e2eec2f467890de667ca3cff2dbadafd5dc 100644
--- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php
+++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php
@@ -29,6 +29,7 @@ namespace Magento\Tax\Model\Sales\Total\Quote;
 
 use Magento\Sales\Model\Quote\Address;
 use Magento\Sales\Model\Quote\Item\AbstractItem;
+use Magento\Tax\Model\Calculation;
 
 class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
 {
@@ -47,30 +48,12 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
     protected $_config = null;
 
     /**
+     * Tax helper
+     *
      * @var \Magento\Tax\Helper\Data|null
      */
     protected $_helper = null;
 
-    /**
-     * @var int
-     */
-    protected $_subtotalInclTax = 0;
-
-    /**
-     * @var int
-     */
-    protected $_baseSubtotalInclTax = 0;
-
-    /**
-     * @var int
-     */
-    protected $_subtotal = 0;
-
-    /**
-     * @var int
-     */
-    protected $_baseSubtotal = 0;
-
     /**
      * Flag which is initialized when collect method is started and catalog prices include tax.
      * Is used for checking if store tax and customer tax requests are similar
@@ -100,13 +83,6 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
      */
     protected $_roundingDeltas = array();
 
-    /**
-     * Tax data
-     *
-     * @var \Magento\Tax\Helper\Data
-     */
-    protected $_taxData = null;
-
     /**
      * Class constructor
      *
@@ -119,9 +95,8 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
         \Magento\Tax\Model\Calculation $calculation,
         \Magento\Tax\Model\Config $taxConfig
     ) {
-        $this->_taxData = $taxData;
         $this->setCode('tax_subtotal');
-        $this->_helper = $this->_taxData;
+        $this->_helper = $taxData;
         $this->_calculator = $calculation;
         $this->_config = $taxConfig;
     }
@@ -139,10 +114,6 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
         $this->_store = $address->getQuote()->getStore();
         $this->_address = $address;
 
-        $this->_subtotalInclTax = 0;
-        $this->_baseSubtotalInclTax = 0;
-        $this->_subtotal = 0;
-        $this->_baseSubtotal = 0;
         $this->_roundingDeltas = array();
 
         $address->setSubtotalInclTax(0);
@@ -155,9 +126,10 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
             return $this;
         }
 
+        $this->_calculator->setCustomerData($address->getQuote()->getCustomerData());
+
         $addressRequest = $this->_getAddressTaxRequest($address);
         $storeRequest = $this->_getStoreTaxRequest($address);
-        $this->_calculator->setCustomerData($address->getQuote()->getCustomerData());
         if ($this->_config->priceIncludesTax($this->_store)) {
             $classIds = array();
             foreach ($items as $item) {
@@ -171,7 +143,11 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
             $classIds = array_unique($classIds);
             $storeRequest->setProductClassId($classIds);
             $addressRequest->setProductClassId($classIds);
-            $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests($storeRequest, $addressRequest);
+            if ($this->_helper->isCrossBorderTradeEnabled($this->_store)) {
+                $this->_areTaxRequestsSimilar = true;
+            } else {
+                $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests($storeRequest, $addressRequest);
+            }
         }
 
         foreach ($items as $item) {
@@ -193,7 +169,7 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
     }
 
     /**
-     * Caclulate item price and row total with customized rounding level
+     * Calculate item price and row total with customized rounding level
      *
      * @param AbstractItem $item
      * @param \Magento\Framework\Object $taxRequest
@@ -202,13 +178,13 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
     protected function _processItem($item, $taxRequest)
     {
         switch ($this->_config->getAlgorithm($this->_store)) {
-            case \Magento\Tax\Model\Calculation::CALC_UNIT_BASE:
+            case Calculation::CALC_UNIT_BASE:
                 $this->_unitBaseCalculation($item, $taxRequest);
                 break;
-            case \Magento\Tax\Model\Calculation::CALC_ROW_BASE:
+            case Calculation::CALC_ROW_BASE:
                 $this->_rowBaseCalculation($item, $taxRequest);
                 break;
-            case \Magento\Tax\Model\Calculation::CALC_TOTAL_BASE:
+            case Calculation::CALC_TOTAL_BASE:
                 $this->_totalBaseCalculation($item, $taxRequest);
                 break;
             default:
@@ -230,69 +206,78 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
         $rate = $this->_calculator->getRate($request);
         $qty = $item->getTotalQty();
 
-        $price = $taxPrice = $item->getCalculationPriceOriginal();
-        $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal();
-        $subtotal = $taxSubtotal = $item->getRowTotal();
-        $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal();
+        $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal());
+        $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal());
+        $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal());
+        $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal());
+
+        // if we have a custom price, determine if tax should be based on the original price
         $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
         if ($taxOnOrigPrice) {
             $origPrice = $item->getOriginalPrice();
             $baseOrigPrice = $item->getBaseOriginalPrice();
         }
 
-
         $item->setTaxPercent($rate);
         if ($this->_config->priceIncludesTax($this->_store)) {
             if ($this->_sameRateAsStore($request)) {
-                $tax = $this->_calculator->calcTaxAmount($price, $rate, true);
-                $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, true);
-                $taxPrice = $price;
-                $baseTaxPrice = $basePrice;
-                $taxSubtotal = $subtotal;
+                // determine which price to use when we calculate the tax
+                if ($taxOnOrigPrice) {
+                    $taxable        = $origPrice;
+                    $baseTaxable    = $baseOrigPrice;
+                } else {
+                    $taxable        = $price;
+                    $baseTaxable    = $basePrice;
+                }
+                $tax             = $this->_calculator->calcTaxAmount($taxable, $rate, true);
+                $baseTax         = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true);
+                $taxPrice        = $price;
+                $baseTaxPrice    = $basePrice;
+                $taxSubtotal     = $subtotal;
                 $baseTaxSubtotal = $baseSubtotal;
                 $price = $price - $tax;
                 $basePrice = $basePrice - $baseTax;
                 $subtotal = $price * $qty;
                 $baseSubtotal = $basePrice * $qty;
+                $isPriceInclTax  = true;
+
+                $item->setRowTax($tax * $qty);
+                $item->setBaseRowTax($baseTax * $qty);
+            } else {
+                $storeRate       = $this->_calculator->getStoreRate($request, $this->_store);
                 if ($taxOnOrigPrice) {
-                    $taxable = $origPrice;
-                    $baseTaxable = $baseOrigPrice;
+                    // the merchant already provided a customer's price that includes tax
+                    $taxPrice     = $price;
+                    $baseTaxPrice = $basePrice;
+                    // determine which price to use when we calculate the tax
+                    $taxable      = $this->_calculatePriceInclTax($origPrice, $storeRate, $rate);
+                    $baseTaxable  = $this->_calculatePriceInclTax($baseOrigPrice, $storeRate, $rate);
                 } else {
-                    $taxable = $taxPrice;
-                    $baseTaxable = $baseTaxPrice;
+                    // determine the customer's price that includes tax
+                    $taxPrice     = $this->_calculatePriceInclTax($price, $storeRate, $rate);
+                    $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate);
+                    // determine which price to use when we calculate the tax
+                    $taxable      = $taxPrice;
+                    $baseTaxable  = $baseTaxPrice;
                 }
-                $isPriceInclTax = true;
-            } else {
-                $storeRate = $this->_calculator->getStoreRate($request, $this->_store);
-                $storeTax = $this->_calculator->calcTaxAmount($price, $storeRate, true);
-                $baseStoreTax = $this->_calculator->calcTaxAmount($basePrice, $storeRate, true);
-                $price = $price - $storeTax;
-                $basePrice = $basePrice - $baseStoreTax;
+                // determine the customer's tax amount
+                $tax             = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
+                $baseTax         = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
+                // determine the customer's price without taxes
+                $price = $taxPrice - $tax;
+                $basePrice = $baseTaxPrice - $baseTax;
+                // determine subtotal amounts
+                $taxSubtotal = $taxPrice * $qty;
+                $baseTaxSubtotal = $baseTaxPrice * $qty;
                 $subtotal = $price * $qty;
                 $baseSubtotal = $basePrice * $qty;
+                $isPriceInclTax  = true;
 
-                $tax = $this->_calculator->calcTaxAmount($price, $rate, false);
-                $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, false);
-                $taxPrice = $price + $tax;
-                $baseTaxPrice = $basePrice + $baseTax;
-                $taxSubtotal = $taxPrice * $qty;
-                $baseTaxSubtotal = $baseTaxPrice * $qty;
-                if ($taxOnOrigPrice) {
-                    $taxable = $origPrice - $storeTax;
-                    $baseTaxable = $baseOrigPrice - $baseStoreTax;
-                } else {
-                    $taxable = $price;
-                    $baseTaxable = $basePrice;
-                }
-                $isPriceInclTax = false;
+                $item->setRowTax($tax * $qty);
+                $item->setBaseRowTax($baseTax * $qty);
             }
         } else {
-            $tax = $this->_calculator->calcTaxAmount($price, $rate, false);
-            $baseTax = $this->_calculator->calcTaxAmount($basePrice, $rate, false);
-            $taxPrice = $price + $tax;
-            $baseTaxPrice = $basePrice + $baseTax;
-            $taxSubtotal = $taxPrice * $qty;
-            $baseTaxSubtotal = $baseTaxPrice * $qty;
+            // determine which price to use when we calculate the tax
             if ($taxOnOrigPrice) {
                 $taxable = $origPrice;
                 $baseTaxable = $baseOrigPrice;
@@ -300,7 +285,21 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
                 $taxable = $price;
                 $baseTaxable = $basePrice;
             }
-            $isPriceInclTax = false;
+            $appliedRates = $this->_calculator->getAppliedRates($request);
+            $taxes = array();
+            $baseTaxes = array();
+            foreach ($appliedRates as $appliedRate) {
+                $taxRate = $appliedRate['percent'];
+                $taxes[] = $this->_calculator->calcTaxAmount($taxable, $taxRate, false);
+                $baseTaxes[] = $this->_calculator->calcTaxAmount($baseTaxable, $taxRate, false);
+            }
+            $tax             = array_sum($taxes);
+            $baseTax         = array_sum($baseTaxes);
+            $taxPrice        = $price + $tax;
+            $baseTaxPrice    = $basePrice + $baseTax;
+            $taxSubtotal     = $taxPrice * $qty;
+            $baseTaxSubtotal = $baseTaxPrice * $qty;
+            $isPriceInclTax  = false;
         }
 
         if ($item->hasCustomPrice()) {
@@ -342,10 +341,12 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
         $rate = $this->_calculator->getRate($request);
         $qty = $item->getTotalQty();
 
-        $price = $taxPrice = $item->getCalculationPriceOriginal();
-        $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal();
-        $subtotal = $taxSubtotal = $item->getRowTotal();
-        $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal();
+        $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal());
+        $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal());
+        $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal());
+        $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal());
+
+        // if we have a custom price, determine if tax should be based on the original price
         $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
         if ($taxOnOrigPrice) {
             $origSubtotal = $item->getOriginalPrice() * $qty;
@@ -355,55 +356,67 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
         $item->setTaxPercent($rate);
         if ($this->_config->priceIncludesTax($this->_store)) {
             if ($this->_sameRateAsStore($request)) {
-                $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, true, false);
-                $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, true, false);
-                $taxPrice = $price;
-                $baseTaxPrice = $basePrice;
-                $taxSubtotal = $subtotal;
-                $baseTaxSubtotal = $baseSubtotal;
-                $subtotal = $this->_calculator->round($subtotal - $rowTax);
-                $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseRowTax);
-                $price = $this->_calculator->round($subtotal / $qty);
-                $basePrice = $this->_calculator->round($baseSubtotal / $qty);
+                // determine which price to use when we calculate the tax
                 if ($taxOnOrigPrice) {
-                    $taxable = $origSubtotal;
-                    $baseTaxable = $baseOrigSubtotal;
+                    $taxable        = $origSubtotal;
+                    $baseTaxable    = $baseOrigSubtotal;
                 } else {
-                    $taxable = $taxSubtotal;
-                    $baseTaxable = $baseTaxSubtotal;
+                    $taxable        = $taxSubtotal;
+                    $baseTaxable    = $baseTaxSubtotal;
                 }
-                $isPriceInclTax = true;
-            } else {
-                $storeRate = $this->_calculator->getStoreRate($request, $this->_store);
-                $storeTax = $this->_calculator->calcTaxAmount($subtotal, $storeRate, true, false);
-                $baseStoreTax = $this->_calculator->calcTaxAmount($baseSubtotal, $storeRate, true, false);
-                $subtotal = $this->_calculator->round($subtotal - $storeTax);
-                $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseStoreTax);
+                $rowTax          = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
+                $baseRowTax      = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
+                $taxPrice        = $price;
+                $baseTaxPrice    = $basePrice;
+                $taxSubtotal     = $subtotal;
+                $baseTaxSubtotal = $baseSubtotal;
+                $subtotal = $this->_calculator->round($subtotal - $rowTax);
+                $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseRowTax);
                 $price = $this->_calculator->round($subtotal / $qty);
                 $basePrice = $this->_calculator->round($baseSubtotal / $qty);
+                $isPriceInclTax  = true;
 
-                $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, false, false);
-                $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, false, false);
-                $taxSubtotal = $subtotal + $rowTax;
-                $baseTaxSubtotal = $baseSubtotal + $baseRowTax;
-                $taxPrice = $this->_calculator->round($taxSubtotal / $qty);
-                $baseTaxPrice = $this->_calculator->round($baseTaxSubtotal / $qty);
+                $item->setRowTax($rowTax);
+                $item->setBaseRowTax($baseRowTax);
+            } else {
+                $storeRate       = $this->_calculator->getStoreRate($request, $this->_store);
                 if ($taxOnOrigPrice) {
-                    $taxable = $this->_calculator->round($origSubtotal - $storeTax);
-                    $baseTaxable = $this->_calculator->round($baseOrigSubtotal - $baseStoreTax);
+                    // the merchant already provided a customer's price that includes tax
+                    $taxPrice     = $price;
+                    $baseTaxPrice = $basePrice;
+                    // determine which price to use when we calculate the tax
+                    $taxable      = $this->_calculatePriceInclTax($item->getOriginalPrice(), $storeRate, $rate);
+                    $baseTaxable  = $this->_calculatePriceInclTax($item->getBaseOriginalPrice(), $storeRate, $rate);
                 } else {
-                    $taxable = $subtotal;
-                    $baseTaxable = $baseSubtotal;
+                    // determine the customer's price that includes tax
+                    $taxPrice     = $this->_calculatePriceInclTax($price, $storeRate, $rate);
+                    $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate);
+                    // determine which price to use when we calculate the tax
+                    $taxable      = $taxPrice;
+                    $baseTaxable  = $baseTaxPrice;
                 }
-                $isPriceInclTax = false;
+                // determine the customer's tax amount
+                $tax             = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
+                $baseTax         = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
+                // determine the customer's price without taxes
+                $price = $taxPrice - $tax;
+                $basePrice = $baseTaxPrice - $baseTax;
+                // determine subtotal amounts
+                $taxable        *= $qty;
+                $baseTaxable    *= $qty;
+                $taxSubtotal     = $taxPrice * $qty;
+                $baseTaxSubtotal = $baseTaxPrice * $qty;
+                $rowTax          = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
+                $baseRowTax      = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
+                $subtotal        = $taxSubtotal - $rowTax;
+                $baseSubtotal    = $baseTaxSubtotal - $baseRowTax;
+                $isPriceInclTax  = true;
+
+                $item->setRowTax($rowTax);
+                $item->setBaseRowTax($baseRowTax);
             }
         } else {
-            $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, false, false);
-            $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, false, false);
-            $taxSubtotal = $subtotal + $rowTax;
-            $baseTaxSubtotal = $baseSubtotal + $baseRowTax;
-            $taxPrice = $this->_calculator->round($taxSubtotal / $qty);
-            $baseTaxPrice = $this->_calculator->round($baseTaxSubtotal / $qty);
+            // determine which price to use when we calculate the tax
             if ($taxOnOrigPrice) {
                 $taxable = $origSubtotal;
                 $baseTaxable = $baseOrigSubtotal;
@@ -411,7 +424,22 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
                 $taxable = $subtotal;
                 $baseTaxable = $baseSubtotal;
             }
-            $isPriceInclTax = false;
+
+            $appliedRates = $this->_calculator->getAppliedRates($request);
+            $rowTaxes = array();
+            $baseRowTaxes = array();
+            foreach ($appliedRates as $appliedRate) {
+                $taxRate = $appliedRate['percent'];
+                $rowTaxes[] = $this->_calculator->calcTaxAmount($taxable, $taxRate, false, true);
+                $baseRowTaxes[] = $this->_calculator->calcTaxAmount($baseTaxable, $taxRate, false, true);
+            }
+            $rowTax          = array_sum($rowTaxes);
+            $baseRowTax      = array_sum($baseRowTaxes);
+            $taxSubtotal     = $subtotal + $rowTax;
+            $baseTaxSubtotal = $baseSubtotal + $baseRowTax;
+            $taxPrice        = $this->_calculator->round($taxSubtotal/$qty);
+            $baseTaxPrice    = $this->_calculator->round($baseTaxSubtotal/$qty);
+            $isPriceInclTax  = false;
         }
 
         if ($item->hasCustomPrice()) {
@@ -458,119 +486,119 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
         $rate = $calc->getRate($request);
         $qty = $item->getTotalQty();
 
-        $price = $taxPrice = $item->getCalculationPriceOriginal();
-        $basePrice = $baseTaxPrice = $item->getBaseCalculationPriceOriginal();
-        $subtotal = $taxSubtotal = $item->getRowTotal();
-        $baseSubtotal = $baseTaxSubtotal = $item->getBaseRowTotal();
+        $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal());
+        $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal());
+        $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal());
+        $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal());
 
+        // if we have a custom price, determine if tax should be based on the original price
         $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
         if ($taxOnOrigPrice) {
             $origSubtotal = $item->getOriginalPrice() * $qty;
             $baseOrigSubtotal = $item->getBaseOriginalPrice() * $qty;
         }
+
         $item->setTaxPercent($rate);
         if ($this->_config->priceIncludesTax($this->_store)) {
             if ($this->_sameRateAsStore($request)) {
+                // determine which price to use when we calculate the tax
                 if ($taxOnOrigPrice) {
-                    $rowTax = $this->_deltaRound($calc->calcTaxAmount($origSubtotal, $rate, true, false), $rate, true);
-                    $baseRowTax = $this->_deltaRound(
-                        $calc->calcTaxAmount($baseOrigSubtotal, $rate, true, false),
-                        $rate,
-                        true,
-                        'base'
-                    );
-
                     $taxable = $origSubtotal;
                     $baseTaxable = $baseOrigSubtotal;
                 } else {
-                    $rowTax = $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, true, false), $rate, true);
-                    $baseRowTax = $this->_deltaRound(
-                        $calc->calcTaxAmount($baseSubtotal, $rate, true, false),
-                        $rate,
-                        true,
-                        'base'
-                    );
-
                     $taxable = $subtotal;
                     $baseTaxable = $baseSubtotal;
                 }
-                $taxPrice = $price;
-                $baseTaxPrice = $basePrice;
+                $rowTaxExact     = $calc->calcTaxAmount($taxable, $rate, true, false);
+                $rowTax          = $this->_deltaRound($rowTaxExact, $rate, true);
+                $baseRowTaxExact = $calc->calcTaxAmount($baseTaxable, $rate, true, false);
+                $baseRowTax      = $this->_deltaRound($baseRowTaxExact, $rate, true, 'base');
 
+                $taxPrice        = $price;
+                $baseTaxPrice    = $basePrice;
                 $taxSubtotal = $subtotal;
                 $baseTaxSubtotal = $baseSubtotal;
 
-                $subtotal = $subtotal - $rowTax;
-                $baseSubtotal = $baseSubtotal - $baseRowTax;
+                $subtotal          = $subtotal - $rowTax;
+                $baseSubtotal      = $baseSubtotal - $baseRowTax;
 
                 $price = $calc->round($subtotal / $qty);
                 $basePrice = $calc->round($baseSubtotal / $qty);
 
-                $isPriceInclTax = true;
+                $isPriceInclTax  = true;
+
+                //Save the tax calculated
+                $item->setRowTax($rowTax);
+                $item->setBaseRowTax($baseRowTax);
             } else {
                 $storeRate = $calc->getStoreRate($request, $this->_store);
                 if ($taxOnOrigPrice) {
-                    $storeTax = $calc->calcTaxAmount($origSubtotal, $storeRate, true, false);
-                    $baseStoreTax = $calc->calcTaxAmount($baseOrigSubtotal, $storeRate, true, false);
+                    // the merchant already provided a customer's price that includes tax
+                    $taxPrice     = $price;
+                    $baseTaxPrice = $basePrice;
+                    // determine which price to use when we calculate the tax
+                    $taxable      = $this->_calculatePriceInclTax($item->getOriginalPrice(), $storeRate, $rate);
+                    $baseTaxable  = $this->_calculatePriceInclTax($item->getBaseOriginalPrice(), $storeRate, $rate);
                 } else {
-                    $storeTax = $calc->calcTaxAmount($subtotal, $storeRate, true, false);
-                    $baseStoreTax = $calc->calcTaxAmount($baseSubtotal, $storeRate, true, false);
+                    // determine the customer's price that includes tax
+                    $taxPrice     = $this->_calculatePriceInclTax($price, $storeRate, $rate);
+                    $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate);
+                    // determine which price to use when we calculate the tax
+                    $taxable      = $taxPrice;
+                    $baseTaxable  = $baseTaxPrice;
                 }
-                $subtotal = $calc->round($subtotal - $storeTax);
-                $baseSubtotal = $calc->round($baseSubtotal - $baseStoreTax);
-
-                $price = $calc->round($subtotal / $qty);
-                $basePrice = $calc->round($baseSubtotal / $qty);
-
-                $rowTax = $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, false, false), $rate, true);
-                $baseRowTax = $this->_deltaRound(
-                    $calc->calcTaxAmount($baseSubtotal, $rate, false, false),
-                    $rate,
-                    true,
-                    'base'
-                );
-
-                $taxSubtotal = $subtotal + $rowTax;
-                $baseTaxSubtotal = $baseSubtotal + $baseRowTax;
-
-                $taxPrice = $calc->round($taxSubtotal / $qty);
-                $baseTaxPrice = $calc->round($baseTaxSubtotal / $qty);
-
-                $taxable = $subtotal;
-                $baseTaxable = $baseSubtotal;
-
-                $isPriceInclTax = false;
+                // determine the customer's tax amount based on the taxable price
+                $tax             = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
+                $baseTax         = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
+                // determine the customer's price without taxes
+                $price = $taxPrice - $tax;
+                $basePrice = $baseTaxPrice - $baseTax;
+                // determine subtotal amounts
+                $taxable        *= $qty;
+                $baseTaxable    *= $qty;
+                $taxSubtotal     = $taxPrice * $qty;
+                $baseTaxSubtotal = $baseTaxPrice * $qty;
+                $rowTax =
+                    $this->_deltaRound($calc->calcTaxAmount($taxable, $rate, true, false), $rate, true);
+                $baseRowTax =
+                    $this->_deltaRound($calc->calcTaxAmount($baseTaxable, $rate, true, false), $rate, true, 'base');
+                $subtotal = $taxSubtotal - $rowTax;
+                $baseSubtotal = $baseTaxSubtotal - $baseRowTax;
+                $isPriceInclTax  = true;
+
+                $item->setRowTax($rowTax);
+                $item->setBaseRowTax($baseRowTax);
             }
         } else {
+            // determine which price to use when we calculate the tax
             if ($taxOnOrigPrice) {
-                $rowTax = $this->_deltaRound($calc->calcTaxAmount($origSubtotal, $rate, false, false), $rate, true);
-                $baseRowTax = $this->_deltaRound(
-                    $calc->calcTaxAmount($baseOrigSubtotal, $rate, false, false),
-                    $rate,
-                    true,
-                    'base'
-                );
-
                 $taxable = $origSubtotal;
                 $baseTaxable = $baseOrigSubtotal;
             } else {
-                $rowTax = $this->_deltaRound($calc->calcTaxAmount($subtotal, $rate, false, false), $rate, true);
-                $baseRowTax = $this->_deltaRound(
-                    $calc->calcTaxAmount($baseSubtotal, $rate, false, false),
-                    $rate,
-                    true,
+                $taxable = $subtotal;
+                $baseTaxable = $baseSubtotal;
+            }
+            $appliedRates = $this->_calculator->getAppliedRates($request);
+            $rowTaxes = array();
+            $baseRowTaxes = array();
+            foreach ($appliedRates as $appliedRate) {
+                $taxId = $appliedRate['id'];
+                $taxRate = $appliedRate['percent'];
+                $rowTaxes[] = $this->_deltaRound($calc->calcTaxAmount($taxable, $taxRate, false, false), $taxId, false);
+                $baseRowTaxes[] = $this->_deltaRound(
+                    $calc->calcTaxAmount($baseTaxable, $taxRate, false, false),
+                    $taxId,
+                    false,
                     'base'
                 );
 
-                $taxable = $subtotal;
-                $baseTaxable = $baseSubtotal;
             }
 
-            $taxSubtotal = $subtotal + $rowTax;
-            $baseTaxSubtotal = $baseSubtotal + $baseRowTax;
+            $taxSubtotal     = $subtotal + array_sum($rowTaxes);
+            $baseTaxSubtotal = $baseSubtotal + array_sum($baseRowTaxes);
 
-            $taxPrice = $calc->round($taxSubtotal / $qty);
-            $baseTaxPrice = $calc->round($baseTaxSubtotal / $qty);
+            $taxPrice        = $calc->round($taxSubtotal/$qty);
+            $baseTaxPrice    = $calc->round($baseTaxSubtotal/$qty);
 
             $isPriceInclTax = false;
         }
@@ -606,6 +634,25 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
         return $this;
     }
 
+    /**
+     * Given a store price that includes tax at the store rate, this function will back out the store's tax, and add in
+     * the customer's tax.  Returns this new price which is the customer's price including tax.
+     *
+     * @param float $storePriceInclTax
+     * @param float $storeRate
+     * @param float $customerRate
+     *
+     * @return float
+     */
+    protected function _calculatePriceInclTax($storePriceInclTax, $storeRate, $customerRate)
+    {
+        $storeTax = $this->_calculator->calcTaxAmount($storePriceInclTax, $storeRate, true, false);
+        $priceExclTax = $storePriceInclTax - $storeTax;
+        $customerTax = $this->_calculator->calcTaxAmount($priceExclTax, $customerRate, false, false);
+        $customerPriceInclTax = $this->_calculator->round($priceExclTax + $customerTax);
+        return $customerPriceInclTax;
+    }
+
     /**
      * Checks whether request for an item has same rate as store one
      * Used only after collect() started, as far as uses optimized $_areTaxRequestsSimilar property
@@ -641,7 +688,8 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
         if ($price) {
             $rate = (string)$rate;
             $type = $type . $direction;
-            $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0;
+            // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
+            $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] :0.000001;
             $price += $delta;
             $this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);
             $price = $this->_calculator->round($price);
@@ -657,32 +705,34 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
      */
     protected function _recalculateParent(AbstractItem $item)
     {
-        $price = 0;
-        $basePrice = 0;
         $rowTotal = 0;
         $baseRowTotal = 0;
-        $priceInclTax = 0;
-        $basePriceInclTax = 0;
         $rowTotalInclTax = 0;
         $baseRowTotalInclTax = 0;
+        $rowTax = 0;
+        $baseRowTax = 0;
+        $store = $item->getStore();
+        $qty = $item->getQty();
+
         foreach ($item->getChildren() as $child) {
-            $price += $child->getPrice() * $child->getQty();
-            $basePrice += $child->getBasePrice() * $child->getQty();
             $rowTotal += $child->getRowTotal();
             $baseRowTotal += $child->getBaseRowTotal();
-            $priceInclTax += $child->getPriceInclTax() * $child->getQty();
-            $basePriceInclTax += $child->getBasePriceInclTax() * $child->getQty();
             $rowTotalInclTax += $child->getRowTotalInclTax();
             $baseRowTotalInclTax += $child->getBaseRowTotalInclTax();
+            $rowTax += $child->getRowTax();
+            $baseRowTax += $child->getBaseRowTax();
         }
-        $item->setConvertedPrice($price);
-        $item->setPrice($basePrice);
+
+        $item->setConvertedPrice($store->roundPrice($rowTotal) / $qty);
+        $item->setPrice($store->roundPrice($baseRowTotal) / $qty);
         $item->setRowTotal($rowTotal);
         $item->setBaseRowTotal($baseRowTotal);
-        $item->setPriceInclTax($priceInclTax);
-        $item->setBasePriceInclTax($basePriceInclTax);
+        $item->setPriceInclTax($store->roundPrice($rowTotalInclTax) / $qty);
+        $item->setBasePriceInclTax($store->roundPrice($baseRowTotalInclTax) / $qty);
         $item->setRowTotalInclTax($rowTotalInclTax);
         $item->setBaseRowTotalInclTax($baseRowTotalInclTax);
+        $item->setRowTax($rowTax);
+        $item->setBaseRowTax($baseRowTax);
         return $this;
     }
 
@@ -726,8 +776,21 @@ class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
      */
     protected function _addSubtotalAmount(Address $address, $item)
     {
-        $address->setTotalAmount('subtotal', $address->getTotalAmount('subtotal') + $item->getRowTotal());
-        $address->setBaseTotalAmount('subtotal', $address->getBaseTotalAmount('subtotal') + $item->getBaseRowTotal());
+        if ($this->_config->priceIncludesTax($this->_store)) {
+            $subTotal = $item->getRowTotalInclTax() - $item->getRowTax();
+            $baseSubTotal = $item->getBaseRowTotalInclTax() - $item->getBaseRowTax();
+            $address->setTotalAmount('subtotal', $address->getTotalAmount('subtotal') + $subTotal);
+            $address->setBaseTotalAmount('subtotal', $address->getBaseTotalAmount('subtotal') + $baseSubTotal);
+        } else {
+            $address->setTotalAmount(
+                'subtotal',
+                $address->getTotalAmount('subtotal') + $item->getRowTotal()
+            );
+            $address->setBaseTotalAmount(
+                'subtotal',
+                $address->getBaseTotalAmount('subtotal') + $item->getBaseRowTotal()
+            );
+        }
         $address->setSubtotalInclTax($address->getSubtotalInclTax() + $item->getRowTotalInclTax());
         $address->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax() + $item->getBaseRowTotalInclTax());
         return $this;
diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php
index c43e6476973a87beafb2395534a18c4defc4d3b4..fc1080efb468a322d559a0476636788f292ca1a4 100644
--- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php
+++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php
@@ -27,6 +27,7 @@ use Magento\Store\Model\Store;
 use Magento\Sales\Model\Quote\Address;
 use Magento\Sales\Model\Quote\Address\Total\AbstractTotal;
 use Magento\Sales\Model\Quote\Item\AbstractItem;
+use Magento\Tax\Model\Calculation;
 
 /**
  * Tax totals calculation model
@@ -139,20 +140,24 @@ class Tax extends AbstractTotal
         );
 
         if ($this->_config->priceIncludesTax($this->_store)) {
-            $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests(
-                $this->_calculator->getRateOriginRequest($this->_store),
-                $request
-            );
+            if ($this->_taxData->isCrossBorderTradeEnabled($this->_store)) {
+                $this->_areTaxRequestsSimilar = true;
+            } else {
+                $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests(
+                    $this->_calculator->getRateOriginRequest($this->_store),
+                    $request
+                );
+            }
         }
 
         switch ($this->_config->getAlgorithm($this->_store)) {
-            case \Magento\Tax\Model\Calculation::CALC_UNIT_BASE:
+            case Calculation::CALC_UNIT_BASE:
                 $this->_unitBaseCalculation($address, $request);
                 break;
-            case \Magento\Tax\Model\Calculation::CALC_ROW_BASE:
+            case Calculation::CALC_ROW_BASE:
                 $this->_rowBaseCalculation($address, $request);
                 break;
-            case \Magento\Tax\Model\Calculation::CALC_TOTAL_BASE:
+            case Calculation::CALC_TOTAL_BASE:
                 $this->_totalBaseCalculation($address, $request);
                 break;
             default:
@@ -183,33 +188,18 @@ class Tax extends AbstractTotal
             if (isset($taxInfoItem['item'])) {
                 // Item hidden taxes
                 $item = $taxInfoItem['item'];
-                $rateKey = $taxInfoItem['rate_key'];
                 $hiddenTax = $taxInfoItem['value'];
                 $baseHiddenTax = $taxInfoItem['base_value'];
-                $inclTax = $taxInfoItem['incl_tax'];
                 $qty = $taxInfoItem['qty'];
 
-                if ($this->_config->getAlgorithm($this->_store) == \Magento\Tax\Model\Calculation::CALC_TOTAL_BASE) {
-                    $hiddenTax = $this->_deltaRound($hiddenTax, $rateKey, $inclTax);
-                    $baseHiddenTax = $this->_deltaRound($baseHiddenTax, $rateKey, $inclTax, 'base');
-                } else {
-                    $hiddenTax = $this->_calculator->round($hiddenTax);
-                    $baseHiddenTax = $this->_calculator->round($baseHiddenTax);
-                }
-
                 $item->setHiddenTaxAmount(max(0, $qty * $hiddenTax));
                 $item->setBaseHiddenTaxAmount(max(0, $qty * $baseHiddenTax));
                 $this->_getAddress()->addTotalAmount('hidden_tax', $item->getHiddenTaxAmount());
                 $this->_getAddress()->addBaseTotalAmount('hidden_tax', $item->getBaseHiddenTaxAmount());
             } else {
                 // Shipping hidden taxes
-                $rateKey = $taxInfoItem['rate_key'];
                 $hiddenTax = $taxInfoItem['value'];
                 $baseHiddenTax = $taxInfoItem['base_value'];
-                $inclTax = $taxInfoItem['incl_tax'];
-
-                $hiddenTax = $this->_deltaRound($hiddenTax, $rateKey, $inclTax);
-                $baseHiddenTax = $this->_deltaRound($baseHiddenTax, $rateKey, $inclTax, 'base');
 
                 $this->_getAddress()->setShippingHiddenTaxAmount(max(0, $hiddenTax));
                 $this->_getAddress()->setBaseShippingHiddenTaxAmnt(max(0, $baseHiddenTax));
@@ -220,34 +210,43 @@ class Tax extends AbstractTotal
     }
 
     /**
-     * Tax caclulation for shipping price
+     * Calculate shipping tax for a single tax rate
      *
-     * @param   Address $address
-     * @param   \Magento\Framework\Object $taxRateRequest
-     * @return  $this
+     * @param Address $address
+     * @param float $rate
+     * @param array $appliedRates
+     * @param string $taxId
+     * @return $this
      */
-    protected function _calculateShippingTax(Address $address, $taxRateRequest)
-    {
-        $taxRateRequest->setProductClassId($this->_config->getShippingTaxClass($this->_store));
-        $rate = $this->_calculator->getRate($taxRateRequest);
+    protected function _calculateShippingTaxByRate(
+        $address,
+        $rate,
+        $appliedRates,
+        $taxId = null
+    ) {
         $inclTax = $address->getIsShippingInclTax();
         $shipping = $address->getShippingTaxable();
         $baseShipping = $address->getBaseShippingTaxable();
-        $rateKey = (string)$rate;
+        $rateKey = ($taxId == null) ? (string)$rate : $taxId;
 
         $hiddenTax = null;
         $baseHiddenTax = null;
         switch ($this->_taxData->getCalculationSequence($this->_store)) {
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
                 $tax = $this->_calculator->calcTaxAmount($shipping, $rate, $inclTax, false);
                 $baseTax = $this->_calculator->calcTaxAmount($baseShipping, $rate, $inclTax, false);
                 break;
-            case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
-            case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
+            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
+            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
                 $discountAmount = $address->getShippingDiscountAmount();
                 $baseDiscountAmount = $address->getBaseShippingDiscountAmount();
-                $tax = $this->_calculator->calcTaxAmount($shipping - $discountAmount, $rate, $inclTax, false);
+                $tax = $this->_calculator->calcTaxAmount(
+                    $shipping - $discountAmount,
+                    $rate,
+                    $inclTax,
+                    false
+                );
                 $baseTax = $this->_calculator->calcTaxAmount(
                     $baseShipping - $baseDiscountAmount,
                     $rate,
@@ -257,32 +256,188 @@ class Tax extends AbstractTotal
                 break;
         }
 
-        if ($this->_config->getAlgorithm($this->_store) == \Magento\Tax\Model\Calculation::CALC_TOTAL_BASE) {
-            $tax = $this->_deltaRound($tax, $rate, $inclTax);
-            $baseTax = $this->_deltaRound($baseTax, $rate, $inclTax, 'base');
+        if ($this->_config->getAlgorithm($this->_store) == Calculation::CALC_TOTAL_BASE) {
+            $tax = $this->_deltaRound($tax, $rateKey, $inclTax);
+            $baseTax = $this->_deltaRound($baseTax, $rateKey, $inclTax, 'base');
+            $this->_addAmount(max(0, $tax));
+            $this->_addBaseAmount(max(0, $baseTax));
         } else {
             $tax = $this->_calculator->round($tax);
             $baseTax = $this->_calculator->round($baseTax);
+            $this->_addAmount(max(0, $tax));
+            $this->_addBaseAmount(max(0, $baseTax));
         }
 
         if ($inclTax && !empty($discountAmount)) {
-            $hiddenTax = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false);
-            $baseHiddenTax = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false);
+            $taxBeforeDiscount = $this->_calculator->calcTaxAmount(
+                $shipping,
+                $rate,
+                $inclTax,
+                false
+            );
+            $baseTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
+                $baseShipping,
+                $rate,
+                $inclTax,
+                false
+            );
+            if ($this->_config->getAlgorithm($this->_store) == Calculation::CALC_TOTAL_BASE) {
+                $taxBeforeDiscount = $this->_deltaRound(
+                    $taxBeforeDiscount,
+                    $rateKey,
+                    $inclTax,
+                    'tax_before_discount'
+                );
+                $baseTaxBeforeDiscount = $this->_deltaRound(
+                    $baseTaxBeforeDiscount,
+                    $rateKey,
+                    $inclTax,
+                    'tax_before_discount_base'
+                );
+            } else {
+                $taxBeforeDiscount = $this->_calculator->round($taxBeforeDiscount);
+                $baseTaxBeforeDiscount = $this->_calculator->round($baseTaxBeforeDiscount);
+            }
+            $hiddenTax = max(0, $taxBeforeDiscount - max(0, $tax));
+            $baseHiddenTax = max(0, $baseTaxBeforeDiscount - max(0, $baseTax));
             $this->_hiddenTaxes[] = array(
                 'rate_key' => $rateKey,
                 'value' => $hiddenTax,
                 'base_value' => $baseHiddenTax,
-                'incl_tax' => $inclTax
+                'incl_tax' => $inclTax,
             );
         }
 
-        $this->_addAmount(max(0, $tax));
-        $this->_addBaseAmount(max(0, $baseTax));
-        $address->setShippingTaxAmount(max(0, $tax));
-        $address->setBaseShippingTaxAmount(max(0, $baseTax));
-        $applied = $this->_calculator->getAppliedRates($taxRateRequest);
-        $this->_saveAppliedTaxes($address, $applied, $tax, $baseTax, $rate);
+        $address->setShippingTaxAmount($address->getShippingTaxAmount() + max(0, $tax));
+        $address->setBaseShippingTaxAmount($address->getBaseShippingTaxAmount() + max(0, $baseTax));
+        $this->_saveAppliedTaxes($address, $appliedRates, $tax, $baseTax, $rate);
+
+        return $this;
+    }
+
+    /**
+     * Tax calculation for shipping price
+     *
+     * @param   Address $address
+     * @param   \Magento\Framework\Object $taxRateRequest
+     * @return  $this
+     */
+    protected function _calculateShippingTax(
+        Address $address,
+        \Magento\Framework\Object $taxRateRequest
+    ) {
+        $taxRateRequest->setProductClassId($this->_config->getShippingTaxClass($this->_store));
+        $rate = $this->_calculator->getRate($taxRateRequest);
+        $inclTax = $address->getIsShippingInclTax();
 
+        $address->setShippingTaxAmount(0);
+        $address->setBaseShippingTaxAmount(0);
+        $address->setShippingHiddenTaxAmount(0);
+        $address->setBaseShippingHiddenTaxAmount(0);
+        $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest);
+        if ($inclTax) {
+            $this->_calculateShippingTaxByRate($address, $rate, $appliedRates);
+        } else {
+            foreach ($appliedRates as $appliedRate) {
+                $taxRate = $appliedRate['percent'];
+                $taxId = $appliedRate['id'];
+                $this->_calculateShippingTaxByRate($address, $taxRate, array($appliedRate), $taxId);
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Initialize tax related fields in item
+     *
+     * @param AbstractItem $item
+     * @param array $appliedRates
+     * @param float $rate
+     * @param bool $isUnitBasedCalculation
+     * @return bool
+     */
+    protected function initializeItemTax(
+        AbstractItem $item,
+        $appliedRates,
+        $rate,
+        $isUnitBasedCalculation = false
+    ) {
+        $item->setTaxAmount(0);
+        $item->setBaseTaxAmount(0);
+        $item->setHiddenTaxAmount(0);
+        $item->setBaseHiddenTaxAmount(0);
+        $item->setTaxPercent($rate);
+        $item->setDiscountTaxCompensation(0);
+        $rowTotalInclTax = $item->getRowTotalInclTax();
+        $recalculateRowTotalInclTax = false;
+        if (!isset($rowTotalInclTax)) {
+            if ($isUnitBasedCalculation) {
+                $qty = $item->getTotalQty();
+                $item->setRowTotalInclTax($this->_store->roundPrice($item->getTaxableAmount() * $qty));
+                $item->setBaseRowTotalInclTax($this->_store->roundPrice($item->getBaseTaxableAmount() * $qty));
+            } else {
+                $item->setRowTotalInclTax($item->getTaxableAmount());
+                $item->setBaseRowTotalInclTax($item->getBaseTaxableAmount());
+            }
+            $recalculateRowTotalInclTax = true;
+        }
+        $item->setTaxRates($appliedRates);
+
+        return $recalculateRowTotalInclTax;
+    }
+
+    /**
+     *
+     * @param Address $address
+     * @param AbstractItem $item
+     * @param \Magento\Framework\Object $taxRateRequest
+     * @param array $itemTaxGroups
+     * @param boolean $catalogPriceInclTax
+     * @return $this
+     */
+    protected function _unitBaseProcessItemTax(
+        Address $address,
+        AbstractItem $item,
+        \Magento\Framework\Object $taxRateRequest,
+        &$itemTaxGroups,
+        $catalogPriceInclTax
+    ) {
+        $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
+        $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest);
+        $rate = $this->_calculator->getRate($taxRateRequest);
+
+        $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate, true);
+
+        if ($catalogPriceInclTax) {
+            $this->_calcUnitTaxAmount($item, $rate);
+            $this->_saveAppliedTaxes(
+                $address,
+                $appliedRates,
+                $item->getTaxAmount(),
+                $item->getBaseTaxAmount(),
+                $rate
+            );
+        } else {
+            //need to calculate each tax separately
+            $taxGroups = array();
+            foreach ($appliedRates as $appliedTax) {
+                $taxId = $appliedTax['id'];
+                $taxRate = $appliedTax['percent'];
+                $this->_calcUnitTaxAmount($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax);
+                $this->_saveAppliedTaxes(
+                    $address,
+                    array($appliedTax),
+                    $taxGroups[$taxId]['tax'],
+                    $taxGroups[$taxId]['base_tax'],
+                    $taxRate
+                );
+            }
+        }
+        if ($rate > 0) {
+            $itemTaxGroups[$item->getId()] = $appliedRates;
+        }
+        $this->_addAmount($item->getTaxAmount());
+        $this->_addBaseAmount($item->getBaseTaxAmount());
         return $this;
     }
 
@@ -293,10 +448,15 @@ class Tax extends AbstractTotal
      * @param \Magento\Framework\Object $taxRateRequest
      * @return $this
      */
-    protected function _unitBaseCalculation(Address $address, $taxRateRequest)
-    {
+    protected function _unitBaseCalculation(
+        Address $address,
+        \Magento\Framework\Object $taxRateRequest
+    ) {
         $items = $this->_getAddressItems($address);
         $itemTaxGroups = array();
+        $store = $address->getQuote()->getStore();
+        $catalogPriceInclTax = $this->_config->priceIncludesTax($store);
+
         foreach ($items as $item) {
             if ($item->getParentItem()) {
                 continue;
@@ -304,37 +464,23 @@ class Tax extends AbstractTotal
 
             if ($item->getHasChildren() && $item->isChildrenCalculated()) {
                 foreach ($item->getChildren() as $child) {
-                    $taxRateRequest->setProductClassId($child->getProduct()->getTaxClassId());
-                    $rate = $this->_calculator->getRate($taxRateRequest);
-                    $this->_calcUnitTaxAmount($child, $rate);
-                    $this->_addAmount($child->getTaxAmount());
-                    $this->_addBaseAmount($child->getBaseTaxAmount());
-                    $applied = $this->_calculator->getAppliedRates($taxRateRequest);
-                    if ($rate > 0) {
-                        $itemTaxGroups[$child->getId()] = $applied;
-                    }
-                    $this->_saveAppliedTaxes(
+                    $this->_unitBaseProcessItemTax(
                         $address,
-                        $applied,
-                        $child->getTaxAmount(),
-                        $child->getBaseTaxAmount(),
-                        $rate
+                        $child,
+                        $taxRateRequest,
+                        $itemTaxGroups,
+                        $catalogPriceInclTax
                     );
-                    $child->setTaxRates($applied);
                 }
                 $this->_recalculateParent($item);
             } else {
-                $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
-                $rate = $this->_calculator->getRate($taxRateRequest);
-                $this->_calcUnitTaxAmount($item, $rate);
-                $this->_addAmount($item->getTaxAmount());
-                $this->_addBaseAmount($item->getBaseTaxAmount());
-                $applied = $this->_calculator->getAppliedRates($taxRateRequest);
-                if ($rate > 0) {
-                    $itemTaxGroups[$item->getId()] = $applied;
-                }
-                $this->_saveAppliedTaxes($address, $applied, $item->getTaxAmount(), $item->getBaseTaxAmount(), $rate);
-                $item->setTaxRates($applied);
+                $this->_unitBaseProcessItemTax(
+                    $address,
+                    $item,
+                    $taxRateRequest,
+                    $itemTaxGroups,
+                    $catalogPriceInclTax
+                );
             }
         }
         if ($address->getQuote()->getTaxesForItems()) {
@@ -345,51 +491,60 @@ class Tax extends AbstractTotal
     }
 
     /**
-     * Calculate unit tax anount based on unit price
+     * Calculate unit tax amount based on unit price
      *
      * @param   AbstractItem $item
      * @param   float $rate
+     * @param   array $taxGroups
+     * @param   string $taxId
+     * @param   bool $recalculateRowTotalInclTax
      * @return  $this
      */
-    protected function _calcUnitTaxAmount(AbstractItem $item, $rate)
-    {
+    protected function _calcUnitTaxAmount(
+        AbstractItem $item,
+        $rate,
+        &$taxGroups = null,
+        $taxId = null,
+        $recalculateRowTotalInclTax = false
+    ) {
         $qty = $item->getTotalQty();
         $inclTax = $item->getIsPriceInclTax();
         $price = $item->getTaxableAmount() + $item->getExtraTaxableAmount();
         $basePrice = $item->getBaseTaxableAmount() + $item->getBaseExtraTaxableAmount();
-        $rateKey = (string)$rate;
-        $item->setTaxPercent($rate);
+        $rateKey = ($taxId == null) ? (string)$rate : $taxId;
 
-        $hiddenTax = null;
-        $baseHiddenTax = null;
+        $unitTaxBeforeDiscount = 0;
+        $baseUnitTaxBeforeDiscount = 0;
         switch ($this->_config->getCalculationSequence($this->_store)) {
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
-                $unitTax = $this->_calculator->calcTaxAmount($price, $rate, $inclTax);
-                $baseUnitTax = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax);
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
+                $unitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($price, $rate, $inclTax, false);
+                $baseUnitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax, false);
+                $unitTaxBeforeDiscount = $unitTax = $this->_calculator->round($unitTaxBeforeDiscount);
+                $baseUnitTaxBeforeDiscount = $baseUnitTax = $this->_calculator->round($baseUnitTaxBeforeDiscount);
                 break;
-            case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
-            case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
+            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
+            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
                 $discountAmount = $item->getDiscountAmount() / $qty;
                 $baseDiscountAmount = $item->getBaseDiscountAmount() / $qty;
 
-                $unitTax = $this->_calculator->calcTaxAmount($price, $rate, $inclTax);
-                $discountRate = $unitTax / $price * 100;
-                $unitTaxDiscount = $this->_calculator->calcTaxAmount($discountAmount, $discountRate, $inclTax, false);
-                $unitTax = max($unitTax - $unitTaxDiscount, 0);
-                $baseUnitTax = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax);
-                $baseDiscountRate = $baseUnitTax / $basePrice * 100;
-                $baseUnitTaxDiscount = $this->_calculator->calcTaxAmount(
-                    $baseDiscountAmount,
-                    $baseDiscountRate,
-                    $inclTax,
-                    false
-                );
-                $baseUnitTax = max($baseUnitTax - $baseUnitTaxDiscount, 0);
+                $unitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($price, $rate, $inclTax, false);
+                $unitTaxDiscount = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false);
+                $unitTax = $this->_calculator->round(max($unitTaxBeforeDiscount - $unitTaxDiscount, 0));
+
+                $baseUnitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax, false);
+                $baseUnitTaxDiscount = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false);
+                $baseUnitTax = $this->_calculator->round(max($baseUnitTaxBeforeDiscount - $baseUnitTaxDiscount, 0));
+
+                $unitTax = $this->_calculator->round($unitTax);
+                $baseUnitTax = $this->_calculator->round($baseUnitTax);
+
+                $unitTaxBeforeDiscount = max(0, $this->_calculator->round($unitTaxBeforeDiscount));
+                $baseUnitTaxBeforeDiscount = max(0, $this->_calculator->round($baseUnitTaxBeforeDiscount));
 
                 if ($inclTax && $discountAmount > 0) {
-                    $hiddenTax = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false);
-                    $baseHiddenTax = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false);
+                    $hiddenTax = $unitTaxBeforeDiscount - $unitTax;
+                    $baseHiddenTax = $baseUnitTaxBeforeDiscount - $baseUnitTax;
                     $this->_hiddenTaxes[] = array(
                         'rate_key' => $rateKey,
                         'qty' => $qty,
@@ -413,12 +568,79 @@ class Tax extends AbstractTotal
                 }
                 break;
         }
-        $item->setTaxAmount($this->_store->roundPrice(max(0, $qty * $unitTax)));
-        $item->setBaseTaxAmount($this->_store->roundPrice(max(0, $qty * $baseUnitTax)));
+        $rowTax = $this->_store->roundPrice(max(0, $qty * $unitTax));
+        $baseRowTax = $this->_store->roundPrice(max(0, $qty * $baseUnitTax));
+        $item->setTaxAmount($item->getTaxAmount() + $rowTax);
+        $item->setBaseTaxAmount($item->getBaseTaxAmount() + $baseRowTax);
+        if (is_array($taxGroups)) {
+            $taxGroups[$rateKey]['tax'] = max(0, $rowTax);
+            $taxGroups[$rateKey]['base_tax'] = max(0, $baseRowTax);
+        }
+
+        $rowTotalInclTax = $item->getRowTotalInclTax();
+        if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) {
+            if ($this->_config->priceIncludesTax($this->_store)) {
+                $item->setRowTotalInclTax($price * $qty);
+                $item->setBaseRowTotalInclTax($basePrice * $qty);
+            } else {
+                $item->setRowTotalInclTax($item->getRowTotalInclTax() + $unitTaxBeforeDiscount * $qty);
+                $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseUnitTaxBeforeDiscount * $qty);
+            }
+        }
 
         return $this;
     }
 
+    /**
+     *
+     * @param Address $address
+     * @param AbstractItem $item
+     * @param \Magento\Framework\Object $taxRateRequest
+     * @param array $itemTaxGroups
+     * @param bool $catalogPriceInclTax
+     * @return $this
+     */
+    protected function _rowBaseProcessItemTax(
+        Address $address,
+        AbstractItem $item,
+        \Magento\Framework\Object $taxRateRequest,
+        &$itemTaxGroups,
+        $catalogPriceInclTax
+    ) {
+        $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
+        $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest);
+        $rate = $this->_calculator->getRate($taxRateRequest);
+
+        $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate);
+
+        if ($catalogPriceInclTax) {
+            $this->_calcRowTaxAmount($item, $rate);
+            $this->_saveAppliedTaxes($address, $appliedRates, $item->getTaxAmount(), $item->getBaseTaxAmount(), $rate);
+        } else {
+            //need to calculate each tax separately
+            $taxGroups = array();
+            foreach ($appliedRates as $appliedTax) {
+                $taxId = $appliedTax['id'];
+                $taxRate = $appliedTax['percent'];
+                $this->_calcRowTaxAmount($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax);
+                $this->_saveAppliedTaxes(
+                    $address,
+                    array($appliedTax),
+                    $taxGroups[$taxId]['tax'],
+                    $taxGroups[$taxId]['base_tax'],
+                    $taxRate
+                );
+            }
+
+        }
+        if ($rate > 0) {
+            $itemTaxGroups[$item->getId()] = $appliedRates;
+        }
+        $this->_addAmount($item->getTaxAmount());
+        $this->_addBaseAmount($item->getBaseTaxAmount());
+        return $this;
+    }
+
     /**
      * Calculate address total tax based on row total
      *
@@ -426,47 +648,38 @@ class Tax extends AbstractTotal
      * @param   \Magento\Framework\Object $taxRateRequest
      * @return  $this
      */
-    protected function _rowBaseCalculation(Address $address, $taxRateRequest)
-    {
+    protected function _rowBaseCalculation(
+        Address $address,
+        \Magento\Framework\Object $taxRateRequest
+    ) {
         $items = $this->_getAddressItems($address);
         $itemTaxGroups = array();
+        $store = $address->getQuote()->getStore();
+        $catalogPriceInclTax = $this->_config->priceIncludesTax($store);
+
         foreach ($items as $item) {
             if ($item->getParentItem()) {
                 continue;
             }
             if ($item->getHasChildren() && $item->isChildrenCalculated()) {
                 foreach ($item->getChildren() as $child) {
-                    $taxRateRequest->setProductClassId($child->getProduct()->getTaxClassId());
-                    $rate = $this->_calculator->getRate($taxRateRequest);
-                    $this->_calcRowTaxAmount($child, $rate);
-                    $this->_addAmount($child->getTaxAmount());
-                    $this->_addBaseAmount($child->getBaseTaxAmount());
-                    $applied = $this->_calculator->getAppliedRates($taxRateRequest);
-                    if ($rate > 0) {
-                        $itemTaxGroups[$child->getId()] = $applied;
-                    }
-                    $this->_saveAppliedTaxes(
+                    $this->_rowBaseProcessItemTax(
                         $address,
-                        $applied,
-                        $child->getTaxAmount(),
-                        $child->getBaseTaxAmount(),
-                        $rate
+                        $child,
+                        $taxRateRequest,
+                        $itemTaxGroups,
+                        $catalogPriceInclTax
                     );
-                    $child->setTaxRates($applied);
                 }
                 $this->_recalculateParent($item);
             } else {
-                $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
-                $rate = $this->_calculator->getRate($taxRateRequest);
-                $this->_calcRowTaxAmount($item, $rate);
-                $this->_addAmount($item->getTaxAmount());
-                $this->_addBaseAmount($item->getBaseTaxAmount());
-                $applied = $this->_calculator->getAppliedRates($taxRateRequest);
-                if ($rate > 0) {
-                    $itemTaxGroups[$item->getId()] = $applied;
-                }
-                $this->_saveAppliedTaxes($address, $applied, $item->getTaxAmount(), $item->getBaseTaxAmount(), $rate);
-                $item->setTaxRates($applied);
+                $this->_rowBaseProcessItemTax(
+                    $address,
+                    $item,
+                    $taxRateRequest,
+                    $itemTaxGroups,
+                    $catalogPriceInclTax
+                );
             }
         }
 
@@ -482,26 +695,39 @@ class Tax extends AbstractTotal
      *
      * @param   AbstractItem $item
      * @param   float $rate
+     * @param   array $taxGroups
+     * @param   string $taxId
+     * @param   bool $recalculateRowTotalInclTax
      * @return  $this
      */
-    protected function _calcRowTaxAmount($item, $rate)
-    {
+    protected function _calcRowTaxAmount(
+        AbstractItem $item,
+        $rate,
+        &$taxGroups = null,
+        $taxId = null,
+        $recalculateRowTotalInclTax = false
+    ) {
         $inclTax = $item->getIsPriceInclTax();
-        $subtotal = $item->getTaxableAmount() + $item->getExtraRowTaxableAmount();
-        $baseSubtotal = $item->getBaseTaxableAmount() + $item->getBaseExtraRowTaxableAmount();
-        $rateKey = (string)$rate;
-        $item->setTaxPercent($rate);
+        $subtotal = $taxSubtotal = $item->getTaxableAmount() + $item->getExtraRowTaxableAmount();
+        $baseSubtotal = $baseTaxSubtotal = $item->getBaseTaxableAmount() + $item->getBaseExtraRowTaxableAmount();
+        $rateKey = ($taxId == null) ? (string)$rate : $taxId;
+
+        $hiddenTax = 0;
+        $baseHiddenTax = 0;
+        $rowTaxBeforeDiscount = 0;
+        $baseRowTaxBeforeDiscount = 0;
 
-        $hiddenTax = null;
-        $baseHiddenTax = null;
         switch ($this->_taxData->getCalculationSequence($this->_store)) {
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
-                $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax);
-                $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax);
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
+                $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false);
+                $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false);
+
+                $rowTaxBeforeDiscount = $rowTax = $this->_calculator->round($rowTaxBeforeDiscount);
+                $baseRowTaxBeforeDiscount = $baseRowTax = $this->_calculator->round($baseRowTaxBeforeDiscount);
                 break;
-            case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
-            case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
+            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
+            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
                 $discountAmount = $item->getDiscountAmount();
                 $baseDiscountAmount = $item->getBaseDiscountAmount();
                 $rowTax = $this->_calculator->calcTaxAmount(max($subtotal - $discountAmount, 0), $rate, $inclTax);
@@ -510,9 +736,29 @@ class Tax extends AbstractTotal
                     $rate,
                     $inclTax
                 );
+                $rowTax = $this->_calculator->round($rowTax);
+                $baseRowTax = $this->_calculator->round($baseRowTax);
+
+                //Calculate the Row Tax before discount
+                $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
+                    $subtotal,
+                    $rate,
+                    $inclTax,
+                    false
+                );
+                $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
+                    $baseSubtotal,
+                    $rate,
+                    $inclTax,
+                    false
+                );
+
+                $rowTaxBeforeDiscount = max(0, $this->_calculator->round($rowTaxBeforeDiscount));
+                $baseRowTaxBeforeDiscount = max(0, $this->_calculator->round($baseRowTaxBeforeDiscount));
+
                 if ($inclTax && $discountAmount > 0) {
-                    $hiddenTax = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false);
-                    $baseHiddenTax = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false);
+                    $hiddenTax = $rowTaxBeforeDiscount - $rowTax;
+                    $baseHiddenTax = $baseRowTaxBeforeDiscount - $baseRowTax;
                     $this->_hiddenTaxes[] = array(
                         'rate_key' => $rateKey,
                         'qty' => 1,
@@ -536,8 +782,23 @@ class Tax extends AbstractTotal
                 }
                 break;
         }
-        $item->setTaxAmount(max(0, $rowTax));
-        $item->setBaseTaxAmount(max(0, $baseRowTax));
+        $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax));
+        $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax));
+        if (is_array($taxGroups)) {
+            $taxGroups[$rateKey]['tax'] = max(0, $rowTax);
+            $taxGroups[$rateKey]['base_tax'] = max(0, $baseRowTax);
+        }
+
+        $rowTotalInclTax = $item->getRowTotalInclTax();
+        if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) {
+            if ($this->_config->priceIncludesTax($this->_store)) {
+                $item->setRowTotalInclTax($subtotal);
+                $item->setBaseRowTotalInclTax($baseSubtotal);
+            } else {
+                $item->setRowTotalInclTax($item->getRowTotalInclTax() + $rowTaxBeforeDiscount);
+                $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseRowTaxBeforeDiscount);
+            }
+        }
         return $this;
     }
 
@@ -548,12 +809,15 @@ class Tax extends AbstractTotal
      * @param   \Magento\Framework\Object $taxRateRequest
      * @return  $this
      */
-    protected function _totalBaseCalculation(Address $address, $taxRateRequest)
-    {
+    protected function _totalBaseCalculation(
+        Address $address,
+        \Magento\Framework\Object $taxRateRequest
+    ) {
         $items = $this->_getAddressItems($address);
         $store = $address->getQuote()->getStore();
         $taxGroups = array();
         $itemTaxGroups = array();
+        $catalogPriceInclTax = $this->_config->priceIncludesTax($store);
 
         foreach ($items as $item) {
             if ($item->getParentItem()) {
@@ -562,27 +826,23 @@ class Tax extends AbstractTotal
 
             if ($item->getHasChildren() && $item->isChildrenCalculated()) {
                 foreach ($item->getChildren() as $child) {
-                    $taxRateRequest->setProductClassId($child->getProduct()->getTaxClassId());
-                    $rate = $this->_calculator->getRate($taxRateRequest);
-                    $applied_rates = $this->_calculator->getAppliedRates($taxRateRequest);
-                    $taxGroups[(string)$rate]['applied_rates'] = $applied_rates;
-                    $taxGroups[(string)$rate]['incl_tax'] = $child->getIsPriceInclTax();
-                    $this->_aggregateTaxPerRate($child, $rate, $taxGroups);
-                    if ($rate > 0) {
-                        $itemTaxGroups[$child->getId()] = $applied_rates;
-                    }
+                    $this->_totalBaseProcessItemTax(
+                        $child,
+                        $taxRateRequest,
+                        $taxGroups,
+                        $itemTaxGroups,
+                        $catalogPriceInclTax
+                    );
                 }
                 $this->_recalculateParent($item);
             } else {
-                $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
-                $rate = $this->_calculator->getRate($taxRateRequest);
-                $applied_rates = $this->_calculator->getAppliedRates($taxRateRequest);
-                $taxGroups[(string)$rate]['applied_rates'] = $applied_rates;
-                $taxGroups[(string)$rate]['incl_tax'] = $item->getIsPriceInclTax();
-                $this->_aggregateTaxPerRate($item, $rate, $taxGroups);
-                if ($rate > 0) {
-                    $itemTaxGroups[$item->getId()] = $applied_rates;
-                }
+                $this->_totalBaseProcessItemTax(
+                    $item,
+                    $taxRateRequest,
+                    $taxGroups,
+                    $itemTaxGroups,
+                    $catalogPriceInclTax
+                );
             }
         }
 
@@ -591,14 +851,63 @@ class Tax extends AbstractTotal
         }
         $address->getQuote()->setTaxesForItems($itemTaxGroups);
 
-        foreach ($taxGroups as $rateKey => $data) {
-            $rate = (double)$rateKey;
-            $inclTax = $data['incl_tax'];
-            $totalTax = $this->_calculator->calcTaxAmount(array_sum($data['totals']), $rate, $inclTax);
-            $baseTotalTax = $this->_calculator->calcTaxAmount(array_sum($data['base_totals']), $rate, $inclTax);
+        foreach ($taxGroups as $taxId => $data) {
+            if ($catalogPriceInclTax) {
+                $rate = (float)$taxId;
+            } else {
+                $rate = $data['applied_rates'][0]['percent'];
+            }
+
+            $totalTax = array_sum($data['tax']);
+            $baseTotalTax = array_sum($data['base_tax']);
             $this->_addAmount($totalTax);
             $this->_addBaseAmount($baseTotalTax);
-            $this->_saveAppliedTaxes($address, $data['applied_rates'], $totalTax, $baseTotalTax, $rate);
+            $totalTaxRounded = $this->_calculator->round($totalTax);
+            $baseTotalTaxRounded = $this->_calculator->round($totalTaxRounded);
+            $this->_saveAppliedTaxes($address, $data['applied_rates'], $totalTaxRounded, $baseTotalTaxRounded, $rate);
+        }
+
+        return $this;
+    }
+
+    /**
+     *
+     * @param AbstractItem $item
+     * @param \Magento\Framework\Object $taxRateRequest
+     * @param array $taxGroups
+     * @param array $itemTaxGroups
+     * @param bool $catalogPriceInclTax
+     * @return $this
+     */
+    protected function _totalBaseProcessItemTax(
+        AbstractItem $item,
+        \Magento\Framework\Object $taxRateRequest,
+        &$taxGroups,
+        &$itemTaxGroups,
+        $catalogPriceInclTax
+    ) {
+        $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
+        $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest);
+        $rate = $this->_calculator->getRate($taxRateRequest);
+
+        $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate);
+
+        if ($catalogPriceInclTax) {
+            $taxGroups[(string)$rate]['applied_rates'] = $appliedRates;
+            $taxGroups[(string)$rate]['incl_tax'] = $item->getIsPriceInclTax();
+            $this->_aggregateTaxPerRate($item, $rate, $taxGroups);
+        } else {
+            //need to calculate each tax separately
+            foreach ($appliedRates as $appliedTax) {
+                $taxId = $appliedTax['id'];
+                $taxRate = $appliedTax['percent'];
+                $taxGroups[$taxId]['applied_rates'] = array($appliedTax);
+                $taxGroups[$taxId]['incl_tax'] = $item->getIsPriceInclTax();
+                $this->_aggregateTaxPerRate($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax);
+            }
+        }
+        if ($rate > 0) {
+            $itemTaxGroups[$item->getId()] = $appliedRates;
         }
         return $this;
     }
@@ -609,12 +918,19 @@ class Tax extends AbstractTotal
      * @param   AbstractItem $item
      * @param   float $rate
      * @param   array &$taxGroups
+     * @param   string $taxId
+     * @param   bool $recalculateRowTotalInclTax
      * @return  $this
      */
-    protected function _aggregateTaxPerRate($item, $rate, &$taxGroups)
-    {
+    protected function _aggregateTaxPerRate(
+        AbstractItem $item,
+        $rate,
+        &$taxGroups,
+        $taxId = null,
+        $recalculateRowTotalInclTax = false
+    ) {
         $inclTax = $item->getIsPriceInclTax();
-        $rateKey = (string)$rate;
+        $rateKey = ($taxId == null) ? (string)$rate : $taxId;
         $taxSubtotal = $subtotal = $item->getTaxableAmount() + $item->getExtraRowTaxableAmount();
         $baseTaxSubtotal = $baseSubtotal = $item->getBaseTaxableAmount() + $item->getBaseExtraRowTaxableAmount();
         $item->setTaxPercent($rate);
@@ -626,14 +942,27 @@ class Tax extends AbstractTotal
 
         $hiddenTax = null;
         $baseHiddenTax = null;
+        $discount = 0;
+        $rowTaxBeforeDiscount = 0;
+        $baseRowTaxBeforeDiscount = 0;
         switch ($this->_taxData->getCalculationSequence($this->_store)) {
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
-                $rowTax = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false);
-                $baseRowTax = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false);
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
+                $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false);
+                $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false);
+
+                $taxBeforeDiscountRounded = $rowTax = $this->_deltaRound($rowTaxBeforeDiscount, $rateKey, $inclTax);
+                $baseTaxBeforeDiscountRounded = $baseRowTax = $this->_deltaRound(
+                    $baseRowTaxBeforeDiscount,
+                    $rateKey,
+                    $inclTax,
+                    'base'
+                );
+                $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax));
+                $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax));
                 break;
-            case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
-            case \Magento\Tax\Model\Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
+            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
+            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
                 if ($this->_taxData->applyTaxOnOriginalPrice($this->_store)) {
                     $discount = $item->getOriginalDiscountAmount();
                     $baseDiscount = $item->getBaseOriginalDiscountAmount();
@@ -644,21 +973,43 @@ class Tax extends AbstractTotal
 
                 $taxSubtotal = max($subtotal - $discount, 0);
                 $baseTaxSubtotal = max($baseSubtotal - $baseDiscount, 0);
+
                 $rowTax = $this->_calculator->calcTaxAmount($taxSubtotal, $rate, $inclTax, false);
                 $baseRowTax = $this->_calculator->calcTaxAmount($baseTaxSubtotal, $rate, $inclTax, false);
-                if (!$item->getNoDiscount() && $item->getWeeeTaxApplied()) {
-                    $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false);
-                    $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
-                        $baseSubtotal,
-                        $rate,
-                        $inclTax,
-                        false
-                    );
-                }
+
+                $rowTax = $this->_deltaRound($rowTax, $rateKey, $inclTax);
+                $baseRowTax = $this->_deltaRound($baseRowTax, $rateKey, $inclTax, 'base');
+
+                $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax));
+                $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax));
+
+                //Calculate the Row taxes before discount
+                $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
+                    $subtotal,
+                    $rate,
+                    $inclTax,
+                    false
+                );
+                $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
+                    $baseSubtotal,
+                    $rate,
+                    $inclTax,
+                    false
+                );
+
+                $taxBeforeDiscountRounded = max(
+                    0,
+                    $this->_deltaRound($rowTaxBeforeDiscount, $rateKey, $inclTax, 'tax_before_discount')
+                );
+                $baseTaxBeforeDiscountRounded = max(
+                    0,
+                    $this->_deltaRound($baseRowTaxBeforeDiscount, $rateKey, $inclTax, 'tax_before_discount_base')
+                );
+
 
                 if ($inclTax && $discount > 0) {
-                    $hiddenTax = $this->_calculator->calcTaxAmount($discount, $rate, $inclTax, false);
-                    $baseHiddenTax = $this->_calculator->calcTaxAmount($baseDiscount, $rate, $inclTax, false);
+                    $hiddenTax = $taxBeforeDiscountRounded - max(0, $rowTax);
+                    $baseHiddenTax = $baseTaxBeforeDiscountRounded - max(0, $baseRowTax);
                     $this->_hiddenTaxes[] = array(
                         'rate_key' => $rateKey,
                         'qty' => 1,
@@ -671,21 +1022,22 @@ class Tax extends AbstractTotal
                 break;
         }
 
-        $rowTax = $this->_deltaRound($rowTax, $rateKey, $inclTax);
-        $baseRowTax = $this->_deltaRound($baseRowTax, $rateKey, $inclTax, 'base');
-        $item->setTaxAmount(max(0, $rowTax));
-        $item->setBaseTaxAmount(max(0, $baseRowTax));
-
-        if (isset($rowTaxBeforeDiscount) && isset($baseRowTaxBeforeDiscount)) {
-            $taxBeforeDiscount = max(0, $this->_deltaRound($rowTaxBeforeDiscount, $rateKey, $inclTax));
-            $baseTaxBeforeDiscount = max(0, $this->_deltaRound($baseRowTaxBeforeDiscount, $rateKey, $inclTax, 'base'));
-
-            $item->setDiscountTaxCompensation($taxBeforeDiscount - max(0, $rowTax));
-            $item->setBaseDiscountTaxCompensation($baseTaxBeforeDiscount - max(0, $baseRowTax));
+        $rowTotalInclTax = $item->getRowTotalInclTax();
+        if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) {
+            if ($this->_config->priceIncludesTax($this->_store)) {
+                $item->setRowTotalInclTax($subtotal);
+                $item->setBaseRowTotalInclTax($baseSubtotal);
+            } else {
+                $item->setRowTotalInclTax($item->getRowTotalInclTax() + $taxBeforeDiscountRounded);
+                $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseTaxBeforeDiscountRounded);
+            }
         }
 
         $taxGroups[$rateKey]['totals'][] = max(0, $taxSubtotal);
         $taxGroups[$rateKey]['base_totals'][] = max(0, $baseTaxSubtotal);
+        $taxGroups[$rateKey]['tax'][] = max(0, $rowTax);
+        $taxGroups[$rateKey]['base_tax'][] = max(0, $baseRowTax);
+
         return $this;
     }
 
@@ -703,7 +1055,8 @@ class Tax extends AbstractTotal
         if ($price) {
             $rate = (string)$rate;
             $type = $type . $direction;
-            $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0;
+            // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
+            $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0.000001;
             $price += $delta;
             $this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);
             $price = $this->_calculator->round($price);
@@ -740,8 +1093,13 @@ class Tax extends AbstractTotal
      * @param float $rate
      * @return void
      */
-    protected function _saveAppliedTaxes(Address $address, $applied, $amount, $baseAmount, $rate)
-    {
+    protected function _saveAppliedTaxes(
+        Address $address,
+        $applied,
+        $amount,
+        $baseAmount,
+        $rate
+    ) {
         $previouslyAppliedTaxes = $address->getAppliedTaxes();
         $process = count($previouslyAppliedTaxes);
 
@@ -771,7 +1129,6 @@ class Tax extends AbstractTotal
                 }
             }
 
-
             if ($appliedAmount || $previouslyAppliedTaxes[$row['id']]['amount']) {
                 $previouslyAppliedTaxes[$row['id']]['amount'] += $appliedAmount;
                 $previouslyAppliedTaxes[$row['id']]['base_amount'] += $baseAppliedAmount;
@@ -855,7 +1212,7 @@ class Tax extends AbstractTotal
     {
         $calculationSequence = $this->_taxData->getCalculationSequence($store);
         switch ($calculationSequence) {
-            case \Magento\Tax\Model\Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
+            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
                 $config['before'][] = 'discount';
                 break;
             default:
diff --git a/app/code/Magento/Tax/Model/System/Config/Source/Tax/Region.php b/app/code/Magento/Tax/Model/System/Config/Source/Tax/Region.php
index bd1eef63668587e98c523ebedecfcfe62aadcbac..721588daf9a9d3ea28a94acb2b3154f7913f8208 100644
--- a/app/code/Magento/Tax/Model/System/Config/Source/Tax/Region.php
+++ b/app/code/Magento/Tax/Model/System/Config/Source/Tax/Region.php
@@ -25,11 +25,6 @@ namespace Magento\Tax\Model\System\Config\Source\Tax;
 
 class Region implements \Magento\Framework\Option\ArrayInterface
 {
-    /**
-     * @var array
-     */
-    protected $_options;
-
     /**
      * @var \Magento\Directory\Model\Resource\Region\CollectionFactory
      */
@@ -44,6 +39,8 @@ class Region implements \Magento\Framework\Option\ArrayInterface
     }
 
     /**
+     * Return list of country's regions as array
+     *
      * @param bool $noEmpty
      * @param string|array|null $country
      * @return array
@@ -58,9 +55,9 @@ class Region implements \Magento\Framework\Option\ArrayInterface
             unset($options[0]);
         } else {
             if ($options) {
-                $options[0]['label'] = '*';
+                $options[0] = array('value' => '0', 'label' => '*');
             } else {
-                $options = array(array('value' => '', 'label' => '*'));
+                $options = array(array('value' => '0', 'label' => '*'));
             }
         }
 
diff --git a/app/code/Magento/Tax/etc/module.xml b/app/code/Magento/Tax/etc/module.xml
index 099b9fe5254ed8ac588ebe7fa9cd823aea91c703..11fadea58db848614a890dcfcb9b775b62043b41 100644
--- a/app/code/Magento/Tax/etc/module.xml
+++ b/app/code/Magento/Tax/etc/module.xml
@@ -24,7 +24,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_Tax" version="1.6.0.5" active="true">
+    <module name="Magento_Tax" version="1.6.0.6" active="true">
         <sequence>
             <module name="Magento_Catalog"/>
             <module name="Magento_Customer"/>
diff --git a/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.5-1.6.0.6.php b/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.5-1.6.0.6.php
new file mode 100644
index 0000000000000000000000000000000000000000..580eecb848ce1dae4aaea2afe1b32bc409ca85fe
--- /dev/null
+++ b/app/code/Magento/Tax/sql/tax_setup/upgrade-1.6.0.5-1.6.0.6.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    Magento
+ * @package     Magento_Tax
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $installer \Magento\Tax\Model\Resource\Setup */
+$installer = $this;
+
+$connection = $installer->getConnection();
+$adminRuleTable = $installer->getTable('admin_rule');
+$aclRulesDelete = array(
+    'Magento_Tax::classes_customer',
+    'Magento_Tax::classes_product',
+    'Magento_Tax::import_export',
+    'Magento_Tax::tax_rates',
+    'Magento_Tax::rules'
+);
+
+/**
+ * Remove unneeded ACL rules
+ */
+$connection->delete($adminRuleTable, $connection->quoteInto('resource_id IN (?)', $aclRulesDelete));
+
+$connection->update(
+    $adminRuleTable,
+    array('resource_id' => 'Magento_Tax::manage_tax'),
+    array('resource_id = ?' => 'Magento_Tax::sales_tax')
+);
+
+/**
+ * Add new field to 'tax_calculation_rule'
+ */
+$connection->addColumn(
+    $this->getTable('tax_calculation_rule'),
+    'calculate_subtotal',
+    [
+        'TYPE' => \Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
+        'NULLABLE' => false,
+        'COMMENT' => 'Calculate off subtotal option',
+    ]
+);
diff --git a/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php b/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php
index dd605251675fa8b95e306bd9d8c9b592318b6bfc..c9863c226b453c3def73e815aab019cd69f2aae9 100644
--- a/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php
+++ b/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit/Tab/General.php
@@ -220,9 +220,12 @@ class General extends \Magento\Theme\Block\Adminhtml\System\Design\Theme\Edit\Ab
                     'label'    => __('Theme Preview Image'),
                     'title'    => __('Theme Preview Image'),
                     'name'     => 'preview',
-                    'after_element_html' => '<img width="50" src="'
+                    'after_element_html' => '<a href="'
                     . $this->_themeImagePath->getPreviewImageDirectoryUrl()
-                    . $formData['preview_image'] . '" />'
+                    . $formData['preview_image'] . '" onclick="imagePreview(\'theme_preview_image\'); return false;">'
+                    . '<img width="50" src="'
+                    . $this->_themeImagePath->getPreviewImageDirectoryUrl()
+                    . $formData['preview_image'] . '" id="theme_preview_image" /></a>'
                 )
             );
         }
diff --git a/app/code/Magento/Theme/view/frontend/1column.phtml b/app/code/Magento/Theme/view/frontend/1column.phtml
index f4c8a575b92ae4bdbc1c5ca6a2bf79d03bb868da..0b2ac06ad088a0a920604c2f017917d5c2e1d4e7 100644
--- a/app/code/Magento/Theme/view/frontend/1column.phtml
+++ b/app/code/Magento/Theme/view/frontend/1column.phtml
@@ -43,7 +43,7 @@ $bodyCss = $this->getBodyClass() ? $this->getBodyClass() : '';
     <?php echo $this->getChildHtml('after_body_start') ?>
     <div class="page wrapper">
         <?php echo $this->getChildHtml('global_notices') ?>
-        <?php echo $this->getChildHtml('header-container') ?>
+        <?php echo $this->getChildHtml('header_container') ?>
         <?php echo $this->getChildHtml('page_top') ?>
         <section id="maincontent" class="page main">
             <?php echo $this->getChildHtml('columns_top') ?>
diff --git a/app/code/Magento/Theme/view/frontend/2columns-left.phtml b/app/code/Magento/Theme/view/frontend/2columns-left.phtml
index ce0f4a8be69424968c2f0e331cb2c719643daefb..fa8ea0aa9cbfc0c237c4aaa23ae4244d31aab4f7 100644
--- a/app/code/Magento/Theme/view/frontend/2columns-left.phtml
+++ b/app/code/Magento/Theme/view/frontend/2columns-left.phtml
@@ -43,7 +43,7 @@ $bodyCss = $this->getBodyClass() ? $this->getBodyClass() : '';
     <?php echo $this->getChildHtml('after_body_start') ?>
     <div class="page wrapper">
         <?php echo $this->getChildHtml('global_notices') ?>
-        <?php echo $this->getChildHtml('header-container') ?>
+        <?php echo $this->getChildHtml('header_container') ?>
         <?php echo $this->getChildHtml('page_top') ?>
         <section id="maincontent" class="page main">
             <?php echo $this->getChildHtml('columns_top') ?>
diff --git a/app/code/Magento/Theme/view/frontend/2columns-right.phtml b/app/code/Magento/Theme/view/frontend/2columns-right.phtml
index fe652d2a1c8e4cbb901d159d25e95d30169318ce..f227734024ea55bd8561b3ce3be2689079d9349f 100644
--- a/app/code/Magento/Theme/view/frontend/2columns-right.phtml
+++ b/app/code/Magento/Theme/view/frontend/2columns-right.phtml
@@ -43,7 +43,7 @@ $bodyCss = $this->getBodyClass() ? $this->getBodyClass() : '';
     <?php echo $this->getChildHtml('after_body_start') ?>
     <div class="page wrapper">
         <?php echo $this->getChildHtml('global_notices') ?>
-        <?php echo $this->getChildHtml('header-container') ?>
+        <?php echo $this->getChildHtml('header_container') ?>
         <?php echo $this->getChildHtml('page_top') ?>
         <section id="maincontent" class="page main">
             <?php echo $this->getChildHtml('columns_top') ?>
diff --git a/app/code/Magento/Theme/view/frontend/3columns.phtml b/app/code/Magento/Theme/view/frontend/3columns.phtml
index 60b3a6886b71f7d248689a3bcc5b9efeba451aa9..320b9240ba8d8143c7ba8111804405dad945234f 100644
--- a/app/code/Magento/Theme/view/frontend/3columns.phtml
+++ b/app/code/Magento/Theme/view/frontend/3columns.phtml
@@ -43,7 +43,7 @@ $bodyCss = $this->getBodyClass() ? $this->getBodyClass() : '';
     <?php echo $this->getChildHtml('after_body_start') ?>
     <div class="page wrapper">
         <?php echo $this->getChildHtml('global_notices') ?>
-        <?php echo $this->getChildHtml('header-container') ?>
+        <?php echo $this->getChildHtml('header_container') ?>
         <?php echo $this->getChildHtml('page_top') ?>
         <section id="maincontent" class="page main">
             <?php echo $this->getChildHtml('columns_top') ?>
diff --git a/app/code/Magento/Theme/view/frontend/layout/default.xml b/app/code/Magento/Theme/view/frontend/layout/default.xml
index 91912a5ae7ea76d0d3cf40070888e5112477cb11..059f50dcc4bfac450d911769d37007de1ecbc85c 100644
--- a/app/code/Magento/Theme/view/frontend/layout/default.xml
+++ b/app/code/Magento/Theme/view/frontend/layout/default.xml
@@ -31,7 +31,7 @@
         <container name="after_body_start" as="after_body_start" label="Page Top">
             <block class="Magento\Theme\Block\Html\Notices" name="global_notices" template="html/notices.phtml"/>
         </container>
-        <container name="header-container" label="Page Header Container" as="header-container" htmlTag="header" htmlClass="page header">
+        <container name="header-container" label="Page Header Container" as="header_container" htmlTag="header" htmlClass="page header">
             <container name="header.panel" label="Page Header Panel" htmlTag="div" htmlClass="panel header">
                 <block class="Magento\Framework\View\Element\Template" name="skip_to_content" template="Magento_Theme::html/skip.phtml">
                     <arguments>
@@ -66,16 +66,6 @@
             <container name="top.container" as="topContainer" label="After Page Header Top" htmlTag="div" htmlClass="top-container"/>
             <block class="Magento\Theme\Block\Html\Breadcrumbs" name="breadcrumbs" as="breadcrumbs"/>
         </container>
-        <!--
-        <container name="page_main" as="page_main" label="Page main" htmlTag="div" htmlClass="columns">
-            <container name="main" as="main" label="Main Content Container" htmlTag="div" htmlClass="column main">
-                <container name="content-top" label="Main Content Top" />
-                <container name="content" label="Main Content Area" />
-                <container name="content-aside" label="Main Content Aside" />
-                <container name="content-bottom" label="Main Content Bottom" />
-            </container>
-        </container>
-        -->
         <container name="columns.top" label="Before Main Columns" as="columns_top">
             <block class="Magento\Theme\Block\Html\Title" name="page.main.title" template="html/title.phtml"/>
             <container name="page.messages" label="invisible" htmlTag="div" htmlClass="page messages">
diff --git a/app/code/Magento/Theme/view/frontend/page.phtml b/app/code/Magento/Theme/view/frontend/page.phtml
deleted file mode 100644
index f07b7e363a6e7320a9478549a3bd6f8f002f8180..0000000000000000000000000000000000000000
--- a/app/code/Magento/Theme/view/frontend/page.phtml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Academic Free License (AFL 3.0)
- * that is bundled with this package in the file LICENSE_AFL.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/afl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
- */
-?>
-<?php
-/**
- * Template for \Magento\Theme\Block\Html
- */
-$bodyCss = $this->getBodyClass() ? $this->getBodyClass() : '';
-?>
-<!doctype html>
-<html lang="<?php echo $this->getLang() ?>" class="no-js">
-<head>
-    <meta charset="utf-8"/>
-    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
-    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
-    <?php echo $this->getChildHtml('head') ?>
-</head>
-<body class="<?php echo $bodyCss ?>"
-      data-container="body"
-      <?php echo $this->getAddAttribute() ?>
-      data-mage-init='{"loaderAjax": {}, "loader": {}}'>
-    <?php echo $this->getChildHtml('after_body_start') ?>
-    <div class="page wrapper">
-        <?php echo $this->getChildHtml('global_notices') ?>
-        <?php echo $this->getChildHtml('header-container') ?>
-        <?php echo $this->getChildHtml('page_top') ?>
-        <section class="page main">
-            <?php echo $this->getChildHtml('page_main') ?>
-        </section>
-        <?php echo $this->getChildHtml('page_bottom') ?>
-
-        <?php echo $this->getChildHtml('footer') ?>
-
-        <?php echo $this->getChildHtml('before_body_end') ?>
-    </div>
-    <?php echo $this->getAbsoluteFooter() ?>
-</body>
-</html>
diff --git a/app/code/Magento/Theme/view/frontend/print.phtml b/app/code/Magento/Theme/view/frontend/print.phtml
index 88525aad918c75b7e3163aca275d356e29517090..d303d183fd264fdceb1f025feae93e1ce04c58a6 100644
--- a/app/code/Magento/Theme/view/frontend/print.phtml
+++ b/app/code/Magento/Theme/view/frontend/print.phtml
@@ -36,23 +36,24 @@
       data-container="body"
       <?php echo $this->getAddAttribute() ?>
       data-mage-init='{"loaderAjax": {}, "loader": {}}'>
-<?php echo $this->getChildHtml('after_body_start') ?>
-<div class="page print wrapper">
-    <header class="header print">
-        <img src="<?php echo $this->getPrintLogoUrl() ? $this->getPrintLogoUrl() : $this->getViewFileUrl('images/logo.gif') ?>" class="logo" alt="" />
-        <?php if ($this->getPrintLogoText()):?>
-            <address><?php echo nl2br($this->escapeHtml($this->getPrintLogoText())) ?></address>
-        <?php endif;?>
-    </header>
-    <div class="page print main">
-        <?php echo $this->getChildHtml('content') ?>
-    </div>
-    <footer class="page print footer">
-        <div class="actions">
-            <button type="button" title="<?php echo __('Close Window') ?>" class="action close" onclick="window.close();"><span><?php echo __('Close Window') ?></span></button>
+    <?php echo $this->getChildHtml('after_body_start') ?>
+    <div class="page print wrapper">
+        <header class="header print">
+            <img src="<?php echo $this->getPrintLogoUrl() ? $this->getPrintLogoUrl() : $this->getViewFileUrl('images/logo.gif') ?>" class="logo" alt="" />
+            <?php if ($this->getPrintLogoText()):?>
+                <address><?php echo nl2br($this->escapeHtml($this->getPrintLogoText())) ?></address>
+            <?php endif;?>
+        </header>
+        <div class="page print main">
+            <?php echo $this->getChildHtml('main') ?>
         </div>
-    </footer>
+        <footer class="page print footer">
+            <div class="actions">
+                <button type="button" title="<?php echo __('Close Window') ?>" class="action close" onclick="window.close();"><span><?php echo __('Close Window') ?></span></button>
+            </div>
+        </footer>
+        <?php echo $this->getChildHtml('before_body_end') ?>
+    </div>
     <?php echo $this->getAbsoluteFooter() ?>
-</div>
 </body>
 </html>
diff --git a/app/code/Magento/Translation/Model/Js/DataProvider.php b/app/code/Magento/Translation/Model/Js/DataProvider.php
index 291e9fd1f7f95a6f2b6139bef7e0a554c21de4a3..7bfc9a5dd188477d5b76eeb91d6c0a2d210f5480 100644
--- a/app/code/Magento/Translation/Model/Js/DataProvider.php
+++ b/app/code/Magento/Translation/Model/Js/DataProvider.php
@@ -173,6 +173,7 @@ class DataProvider implements DataProviderInterface
             'Your order cannot be completed at this time as there is no payment methods available for it.' => __('Your order cannot be completed at this time as there is no payment methods available for it.'),
             'Edit Order' => __('Edit Order'),
             'Ok' => __('Ok'),
+            'Please specify at least one search term.' => __('Please specify at least one search term.'),
         );
     }
 }
diff --git a/app/code/Magento/Wishlist/etc/module.xml b/app/code/Magento/Wishlist/etc/module.xml
index 525db7a1cd460d9c994a0198dae053d7e40876a0..b34f798969b6233f93607341045675f63f833776 100644
--- a/app/code/Magento/Wishlist/etc/module.xml
+++ b/app/code/Magento/Wishlist/etc/module.xml
@@ -42,7 +42,8 @@
             <module name="Magento_Bundle" type="soft"/>
             <module name="Magento_Sales"/>
             <module name="Magento_GroupedProduct"/>
-            <module name="Magento_ConfigurableProduct"/>
+            <module name="Magento_ConfigurableProduct" type="soft"/>
+            <module name="Magento_Downloadable" type="soft"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/Wishlist/view/frontend/js/components.phtml b/app/code/Magento/Wishlist/view/frontend/js/components.phtml
index 55af731fd1edf2410a6d46c35e6418e2b0609395..223538be23d16506138d036896ac8d835bd7bef5 100644
--- a/app/code/Magento/Wishlist/view/frontend/js/components.phtml
+++ b/app/code/Magento/Wishlist/view/frontend/js/components.phtml
@@ -34,10 +34,6 @@
             ],
             wishlistSearch: [
                 '<?php echo $this->getViewFileUrl('Magento_Wishlist::js/search.js') ?>'
-            ],
-            configurable: [
-                '<?php echo $this->getViewFileUrl('jquery/jquery.parsequery.js') ?>',
-                '<?php echo $this->getViewFileUrl('Magento_ConfigurableProduct::js/configurable.js') ?>'
             ]
         });
     })(jQuery);
diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml
index 4fcfe46d66654463978d995c43c34da641ecc0b1..7f1375379d7c029971be2f3afbd64c68f474537a 100644
--- a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml
+++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_configurable.xml
@@ -26,6 +26,7 @@
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
     <referenceBlock name="head.components">
         <block class="Magento\Framework\View\Element\Js\Components" name="wishlist_product_view_head_components" template="Magento_Wishlist::js/components.phtml"/>
+        <block class="Magento\Framework\View\Element\Js\Components" name="configurableproduct_product_view_head_components" template="Magento_ConfigurableProduct::js/components.phtml"/>
     </referenceBlock>
     <referenceBlock name="root">
         <action method="addBodyClass">
diff --git a/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.xml
new file mode 100644
index 0000000000000000000000000000000000000000..69d5d249d2a91a3c035a5814e9a57155422d3172
--- /dev/null
+++ b/app/code/Magento/Wishlist/view/frontend/layout/wishlist_index_configure_type_downloadable.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="head.components">
+        <block class="Magento\Framework\View\Element\Js\Components" name="wishlist_product_view_head_components" template="Magento_Wishlist::js/components.phtml"/>
+        <block class="Magento\Framework\View\Element\Js\Components" name="downloadable_page_head_components" template="Magento_Downloadable::js/components.phtml"/>
+    </referenceBlock>
+    <referenceContainer name="product.info.type">
+        <block class="Magento\Downloadable\Block\Catalog\Product\View\Type" name="product.info.downloadable" as="product_type_data" template="catalog/product/type.phtml">
+            <block class="Magento\Downloadable\Block\Catalog\Product\Samples" name="product.info.downloadable.samples" as="samples" template="catalog/product/samples.phtml"/>
+            <block class="Magento\CatalogInventory\Block\Stockqty\DefaultStockqty" name="product.info.downloadable.extra" as="product_type_data_extra" template="stockqty/default.phtml"/>
+        </block>
+    </referenceContainer>
+    <referenceBlock name="product.info.options.wrapper">
+        <block class="Magento\Downloadable\Block\Catalog\Product\Links" name="product.info.downloadable.options" as="type_downloadable_options" before="-" template="catalog/product/links.phtml">
+            <block class="Magento\Catalog\Pricing\Render" name="product.price.link" after="product.info.downloadable.options">
+                <arguments>
+                    <argument name="price_render" xsi:type="string">product.price.render.default</argument>
+                    <argument name="price_type_code" xsi:type="string">link_price</argument>
+                    <argument name="display_msrp_help_message" xsi:type="string">1</argument>
+                </arguments>
+            </block>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Wishlist/view/frontend/shared.phtml b/app/code/Magento/Wishlist/view/frontend/shared.phtml
index 915728ca6e58d895a01ad50ad6b87aecb7cca79d..77974db97539d4cf6ef56126b7a9b3e26a71cc26 100644
--- a/app/code/Magento/Wishlist/view/frontend/shared.phtml
+++ b/app/code/Magento/Wishlist/view/frontend/shared.phtml
@@ -66,12 +66,12 @@ $imageBlock =  $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Im
                         <td class="col actions" data-role="add-to-links">
                             <?php if ($product->isSaleable()): ?>
                                 <?php if ($isVisibleProduct): ?>
-                                    <button type="button" title="<?php echo __('Add to Cart') ?>" onclick="setLocation('<?php echo $this->getSharedItemAddToCartUrl($item) ?>')" class="action tocart">
+                                    <button type="button" title="<?php echo __('Add to Cart') ?>" onclick="location.assign('<?php echo $this->getSharedItemAddToCartUrl($item) ?>')" class="action tocart">
                                         <span><?php echo __('Add to Cart') ?></span>
                                     </button>
                                 <?php endif ?>
                             <?php endif; ?>
-                            <a href="#" data-post='<?php echo $this->getAddToWishlistParams($item); ?>'  onclick="setLocation(this.href); return false;" class="action towishlist" data-action="add-to-wishlist">
+                            <a href="#" data-post='<?php echo $this->getAddToWishlistParams($item); ?>'  onclick="location.assign(this.href); return false;" class="action towishlist" data-action="add-to-wishlist">
                                 <span><?php echo __('Add to Wishlist') ?></span>
                             </a>
                         </td>
@@ -86,7 +86,7 @@ $imageBlock =  $this->getLayout()->createBlock('Magento\Catalog\Block\Product\Im
                 <div class="primary">
                     <button type="button" 
                             title="<?php echo __('Add All to Cart') ?>" 
-                            onclick="setLocation('<?php echo $this->getUrl('*/*/allcart', array('_current'=>true)) ?>')"
+                            onclick="location.assign('<?php echo $this->getUrl('*/*/allcart', array('_current'=>true)) ?>')"
                             class="action tocart primary">
                         <span><?php echo __('Add All to Cart') ?></span>
                     </button>
diff --git a/app/design/adminhtml/Magento/backend/Magento_Backend/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Backend/css/source/module.less
index 69a1c5a06fe9146a3ae8b16001663b0ef4288384..09c58867ae82873e61385606b3853b85c149ff20 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Backend/css/source/module.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Backend/css/source/module.less
@@ -25,7 +25,7 @@
 .search-global {
     &.miniform {
         position: relative;
-        z-index: 2;
+        z-index: 1000;
         display: inline-block;
         vertical-align: top;
         margin:6px 10px 0;
@@ -384,51 +384,47 @@
     color: #9ba8b5;
 }
 
-.suggest-expandable .action-dropdown .action-toggle {
-    display: inline-block;
-    max-width: 500px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-    background: none;
-    border: none;
-    box-shadow: none;
-    color: #676056;
-    font-size: 12px;
-    padding: 5px 4px;
-    filter: none;
-}
-
-.suggest-expandable .action-dropdown .action-toggle span {
-    display: inline;
-}
-
-.suggest-expandable .action-dropdown .action-toggle:before {
-    display: inline-block;
-    float: right;
-    margin-left: 4px;
-    font-size: 13px;
-    color: #b2b0ad;
-}
-
-.suggest-expandable .action-dropdown .action-toggle:hover:before {
-    color: #7e7e7e;
-}
-
-.suggest-expandable .dropdown-menu {
-    margin: 1px 0 0;
-    left: 0;
-    right: auto;
-    width: 221px;
-}
-
 .suggest-expandable {
+    .action-dropdown .action-toggle {
+        display: inline-block;
+        max-width: 500px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        background: none;
+        border: none;
+        box-shadow: none;
+        color: #676056;
+        font-size: 12px;
+        padding: 5px 4px;
+        filter: none;
+        span {
+            display: inline;
+        }
+        &:before {
+            display: inline-block;
+            float: right;
+            margin-left: 4px;
+            font-size: 13px;
+            color: #b2b0ad;
+        }
+        &:hover:before {
+            color: #7e7e7e;
+        }
+    }
+    .dropdown-menu {
+        margin: 1px 0 0;
+        left: 0;
+        right: auto;
+        width: 245px;
+        z-index: 4;
+    }
     .mage-suggest {
         border: none;
         border-radius: 3px 3px 0 0;
         &:after {
-            top: 6px;
-            right: 6px;
+            top: 10px;
+            right: 8px;
         }
     }
     .mage-suggest-inner {
@@ -446,7 +442,7 @@
             margin: 6px 5px 5px;
             padding-right: 20px;
             border: 1px solid #ada89e;
-            width: 211px;
+            width: 236px;
             z-index: 1;
         }
         > input.ui-autocomplete-loading,
diff --git a/app/design/adminhtml/Magento/backend/Magento_Core/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Core/css/source/module.less
new file mode 100644
index 0000000000000000000000000000000000000000..85554dabcb89bc16ed0100bc22ef2e6347a8302a
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Core/css/source/module.less
@@ -0,0 +1,30 @@
+// /**
+// //  * Magento
+//  *
+//  * NOTICE OF LICENSE
+//  *
+//  * This source file is subject to the Academic Free License (AFL 3.0)
+//  * that is bundled with this package in the file LICENSE_AFL.txt.
+//  * It is also available through the world-wide-web at this URL:
+//  * http://opensource.org/licenses/afl-3.0.php
+//  * If you did not receive a copy of the license and are unable to
+//  * obtain it through the world-wide-web, please send an email
+//  * to license@magentocommerce.com so we can send you a copy immediately.
+//  *
+//  * DISCLAIMER
+//  *
+//  * Do not edit or add to this file if you wish to upgrade Magento to newer
+//  * versions in the future. If you wish to customize Magento for your
+//  * needs please refer to http://www.magentocommerce.com for more information.
+//  *
+//  * @category    design
+//  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+//  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+//  */
+
+.debugging-hints {
+    .page-actions {
+        position: relative;
+        z-index: 1;
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Tax/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Tax/css/source/module.less
new file mode 100644
index 0000000000000000000000000000000000000000..56cebcafeb028ce42c8717526caf0fc294592a41
--- /dev/null
+++ b/app/design/adminhtml/Magento/backend/Magento_Tax/css/source/module.less
@@ -0,0 +1,40 @@
+///**
+// //  * Magento
+//  *
+//  * NOTICE OF LICENSE
+//  *
+//  * This source file is subject to the Academic Free License (AFL 3.0)
+//  * that is bundled with this package in the file LICENSE_AFL.txt.
+//  * It is also available through the world-wide-web at this URL:
+//  * http://opensource.org/licenses/afl-3.0.php
+//  * If you did not receive a copy of the license and are unable to
+//  * obtain it through the world-wide-web, please send an email
+//  * to license@magentocommerce.com so we can send you a copy immediately.
+//  *
+//  * DISCLAIMER
+//  *
+//  * Do not edit or add to this file if you wish to upgrade Magento to newer
+//  * versions in the future. If you wish to customize Magento for your
+//  * needs please refer to http://www.magentocommerce.com for more information.
+//  *
+//  * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+//  * @license    http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+//  */
+
+.action-add.mselect-button-add {
+    &:extend(button all);
+}
+
+.block.mselect-list {
+    .mselect-input {
+        width: 100%;
+    }
+    .mselect-input-container {
+        .mselect-save {
+            top: 4px;
+        }
+        .mselect-cancel {
+            top: 4px;
+        }
+    }
+}
diff --git a/app/design/adminhtml/Magento/backend/Magento_Theme/css/source/module.less b/app/design/adminhtml/Magento/backend/Magento_Theme/css/source/module.less
index fcc6ba94394335bafdfcf019348376be7b70f061..3f8ddff06b025aa0caf63cd9866b86efe773dab3 100644
--- a/app/design/adminhtml/Magento/backend/Magento_Theme/css/source/module.less
+++ b/app/design/adminhtml/Magento/backend/Magento_Theme/css/source/module.less
@@ -304,7 +304,8 @@ body {
             @_icon-font-color-hover: @page-main-action-color,
             @_icon-font-color-active: @page-main-action-color,
             @_dropdown-list-item-hover: transparent,
-            @_dropdown-list-item-padding: 0
+            @_dropdown-list-item-padding: 0,
+            @_dropdown-list-min-width: 195px
         );
         .action.toggle {
             .button-reset();
@@ -316,7 +317,6 @@ body {
             margin-top: 4px;
             padding-top: 5px;
             left: 0;
-            min-width: 195px;
             li {
                 border: 0;
                 cursor: default;
@@ -464,7 +464,8 @@ button {
         @_toggle-selector: ~".action-toggle",
         @_button-selector: ~".action-default",
         @_options-selector :  ~".dropdown-menu",
-        @_dropdown-split-button-border-radius-fix: true
+        @_dropdown-split-button-border-radius-fix: true,
+        @_dropdown-split-list-min-width: 175px
     );
     vertical-align: middle;
 }
@@ -533,3 +534,7 @@ button {
         width: 100%;
     }
 }
+
+.ui-widget-overlay {
+    position: fixed;
+}
diff --git a/app/design/adminhtml/Magento/backend/css/admin.less b/app/design/adminhtml/Magento/backend/css/admin.less
index 40733464ee9ad4c1be3e1e202151ed8feb7fedb5..3a9e4d2cc35521b996c8d9af304ef4760ef88674 100644
--- a/app/design/adminhtml/Magento/backend/css/admin.less
+++ b/app/design/adminhtml/Magento/backend/css/admin.less
@@ -3368,7 +3368,7 @@ tr.dynamic-grid input.input-text {
     border-top: none;
 }
 
-.attribute-popup .fieldset-wrapper .fieldset-wrapper-title {
+.attribute-popup .fieldset-wrapper:not(.collapsable-wrapper) .fieldset-wrapper-title {
     border-bottom: none;
 }
 
@@ -3761,7 +3761,6 @@ tr.dynamic-grid input.input-text {
     }
 }
 
-
 // Clearfix
 .clearfix:before,
 .clearfix:after,
diff --git a/app/design/adminhtml/Magento/backend/css/source/abstract.less b/app/design/adminhtml/Magento/backend/css/source/abstract.less
index 442ff06ac83d0e83f002d353999cd76a3c4764cf..5fb30761d9c68591a3ab1f07e8be7032f9baa7f4 100644
--- a/app/design/adminhtml/Magento/backend/css/source/abstract.less
+++ b/app/design/adminhtml/Magento/backend/css/source/abstract.less
@@ -146,3 +146,11 @@
         width: 250px;
     }
 }
+
+.h-scroll {
+    overflow-x: auto;
+}
+
+.add-clearer {
+    .clearer();
+}
diff --git a/app/design/adminhtml/Magento/backend/css/source/navigation.less b/app/design/adminhtml/Magento/backend/css/source/navigation.less
index ab0498e10c32ed37593de59b1c389885a4c08c43..3ef24330dadb841d1ce0bf805c89a8920306233b 100644
--- a/app/design/adminhtml/Magento/backend/css/source/navigation.less
+++ b/app/design/adminhtml/Magento/backend/css/source/navigation.less
@@ -22,12 +22,14 @@
 //  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 //  */
 
-/*
-    Global Navigation
--------------------------------------- */
+//
+//    Global Navigation
+// --------------------------------------
 
 .navigation {
     background-color: @color-middle;
+    position: relative;
+    z-index: 5;
 }
 
 .navigation .level-0.reverse > .submenu {
@@ -36,9 +38,9 @@
 
 .navigation > ul {
     &:extend(._layout-width all);
+    &:extend(.add-clearer all);
     position: relative;
     text-align: right;
-    z-index: 900;
 }
 
 .navigation .level-0 > .submenu {
@@ -91,7 +93,6 @@
 
 .navigation .level-0 > a {
     background: none;
-    //position: relative;
     display: block;
     padding: 12px 13px 0;
     .style15();
@@ -115,7 +116,6 @@
     }
 }
 
-//.navigation .level-0:hover > a,
 .navigation .level-0.hover.recent > a {
     background: #fff;
     .style15I();
@@ -201,9 +201,9 @@
     margin-left: 15px;
 }
 
-/*
-    Admin and Store Settings
--------------------------------------- */
+//
+//    Admin and Store Settings
+// --------------------------------------
 .navigation .level-0.item-system,
 .navigation .level-0.item-stores {
     float: none;
diff --git a/app/design/adminhtml/Magento/backend/css/source/table.less b/app/design/adminhtml/Magento/backend/css/source/table.less
index fd207398b4f7f1fb8a1f1e883c71465b0aa99ba3..78bb5dd66fd3a48ef01309c872b4c198acc0eed3 100644
--- a/app/design/adminhtml/Magento/backend/css/source/table.less
+++ b/app/design/adminhtml/Magento/backend/css/source/table.less
@@ -852,10 +852,12 @@ td.col-sku {
     font-size: 13px;
     line-height: 28px;
     padding: 15px 15px 0;
+    &:extend(.add-clearer all);
     > .entry-edit {
         float: right;
         .field-row {
             display: inline-block;
+            vertical-align: top;
         }
         .validation-advice {
             display: none !important;
@@ -956,6 +958,11 @@ td.col-sku {
     .grid {
         padding: 0;
     }
+    .massaction {
+        padding: 0;
+        border-top: none;
+        margin-bottom: 15px;
+    }
 }
 
 .accordion .grid {
@@ -1088,13 +1095,6 @@ td.col-sku {
             &:extend(.ellipsis all);
             &:extend(.col-110-max all);
         }
-        .col-reason {
-            &:extend(.ellipsis all);
-            &:extend(.col-70-max all);
-            a {
-                display: block;
-            }
-        }
     }
     .col-actions {
         a {
@@ -1124,7 +1124,7 @@ td.col-sku {
 
 .catalog-product-edit .ui-tabs-panel .grid {
     .hor-scroll {
-        overflow-x: auto;
+        &:extend(.h-scroll);
     }
     .col-name,
     .col-type,
@@ -1236,7 +1236,7 @@ td.col-sku {
 .review-product-index {
     .grid {
         .hor-scroll {
-            overflow-x: auto;
+            &:extend(.h-scroll);
         }
         .col-name {
             &:extend(.col-110-max all);
@@ -1406,6 +1406,11 @@ td.col-sku {
         }
     }
 }
+.adminhtml-rma-edit {
+    .hor-scroll {
+        &:extend(.h-scroll);
+    }
+}
 
 //
 //    Stores -> All Stores
diff --git a/app/design/adminhtml/Magento/backend/mui/form.css b/app/design/adminhtml/Magento/backend/mui/form.css
index e266d2317bc6855a6c740357a234f098c1778ff8..4acdd9d45f7fb68ce729c9f0338ae28483933577 100644
--- a/app/design/adminhtml/Magento/backend/mui/form.css
+++ b/app/design/adminhtml/Magento/backend/mui/form.css
@@ -147,6 +147,10 @@ span.required {
     width: auto;
 }
 
+.addon select + .addafter {
+    border: none;
+}
+
 .ie .addon textarea,
 .ie .addon select {
     display:inline-block;
diff --git a/app/design/frontend/Magento/blank/Magento_Theme/css/source/module.less b/app/design/frontend/Magento/blank/Magento_Theme/css/source/module.less
index b040f3a31a0a07a06d0b4f7d69852ba7dfcac0c5..03dcf370b01f61112936b40c74ae3b559d1ce480 100644
--- a/app/design/frontend/Magento/blank/Magento_Theme/css/source/module.less
+++ b/app/design/frontend/Magento/blank/Magento_Theme/css/source/module.less
@@ -51,33 +51,6 @@ body {
     margin-bottom: 20px;
 }
 
-.customer.welcome {
-    .dropdown(
-        @_toggle-selector : ~".action.switch",
-        @_options-selector : ~"ul",
-        @_dropdown-actions-padding: 0,
-        @_dropdown-list-item-padding: 8px,
-        @_dropdown-toggle-icon-content: @icon-down,
-        @_dropdown-toggle-active-icon-content: @icon-up,
-        @_icon-font-text-hide: true,
-        @_icon-font-size: 22px,
-        @_icon-font-line-height: 22px
-    );
-    .action.switch {
-        .button-reset();
-    }
-    li {
-        &:extend(.switcher li all);
-        min-width: 120px;
-        a {
-            &:extend(.page.header .panel.header .switcher all);
-        }
-    }
-    .header.links & ~ li {
-        display: none;
-    }
-}
-
 .header {
     &.content {
         padding-top: 10px;
@@ -219,10 +192,10 @@ body {
                 @_dropdown-toggle-active-icon-content: @icon-up,
                 @_icon-font-text-hide: true,
                 @_icon-font-size: 22px,
-                @_icon-font-line-height: 22px
+                @_icon-font-line-height: 22px,
+                @_dropdown-list-min-width: 160px
             );
             ul.dropdown {
-                min-width: 160px;
                 a {
                     display: block;
                     padding: 8px;
diff --git a/dev/tests/functional/composer.json.dist b/dev/tests/functional/composer.json.dist
index 0aa8ef282c54330353f3d54c5ef5ee84a7fd8b2d..99368dbb49ebd439bd12e28cdd4da3de36f50d07 100644
--- a/dev/tests/functional/composer.json.dist
+++ b/dev/tests/functional/composer.json.dist
@@ -6,7 +6,7 @@
         }
     ],
     "require": {
-        "magento/mtf": "dev-develop",
+        "magento/mtf": "dev-master",
         "php": ">=5.4.0",
         "phpunit/phpunit": "3.7.*",
         "phpunit/phpunit-selenium": ">=1.2",
diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/JquerytreeElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/JquerytreeElement.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f6a7c38982d43b10fad305c3837930a521c046d
--- /dev/null
+++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/JquerytreeElement.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Mtf\Client\Driver\Selenium\Element;
+
+use Mtf\Client\Element;
+
+/**
+ * Class JquerytreeElement
+ * Typified element class for JqueryTree elements
+ *
+ * @package Mtf\Client\Element
+ */
+class JquerytreeElement extends Tree
+{
+    /**
+     * Css class for finding tree nodes.
+     *
+     * @var string
+     */
+    protected $nodeCssClass = ' > ul';
+
+    /**
+     * Css class for detecting tree nodes.
+     *
+     * @var string
+     */
+    protected $nodeSelector = 'li[data-id]';
+
+    /**
+     * Css class for detecting tree nodes.
+     *
+     * @var string
+     */
+    protected $checkedNodeSelector = 'li.jstree-checked[data-id]';
+
+    /**
+     * Css class for fetching node's name.
+     *
+     * @var string
+     */
+    protected $nodeName = 'a';
+
+    /**
+     * Array, which holds all selected elements paths.
+     *
+     * @var array
+     */
+    protected $checkedNodesPaths = [];
+
+    /**
+     * Returns structure of the jquerytree element.
+     *
+     * @return array
+     */
+    public function getStructure()
+    {
+        return $this->_getNodeContent($this, 'div[class*=jstree] > ul');
+    }
+
+    /**
+     *  Recursive walks tree
+     *
+     * @param Element $node
+     * @param string $parentCssClass
+     * @return array
+     */
+    protected function _getNodeContent($node, $parentCssClass)
+    {
+        $counter = 1;
+        $nextNodeSelector = $parentCssClass . " > " . $this->nodeSelector . ":nth-of-type($counter)";
+        $nodeArray = [];
+        //Get list of all children nodes to work with
+        $newNode = $node->find($nextNodeSelector);
+        while ($newNode->isVisible()) {
+            $nextCheckedNodeSelector = $parentCssClass . " > " . $this->checkedNodeSelector . ":nth-of-type($counter)";
+            $nodesNames = $newNode->find($this->nodeName);
+            $text = ltrim($nodesNames->getText());
+            $childNodeSelector = $nextNodeSelector . $this->nodeCssClass;
+            $nodesContents = $newNode->find($childNodeSelector);
+            $subNodes = null;
+            if ($nodesContents->isVisible()) {
+                $subNodes = $this->_getNodeContent($nodesContents, $childNodeSelector);
+            }
+            $nodeArray[] = [
+                'name' => $text,
+                'isChecked' => $node->find($nextCheckedNodeSelector)->isVisible() ? true : false,
+                'element' => $newNode,
+                'subnodes' => $subNodes,
+            ];
+            ++$counter;
+            $nextNodeSelector = $parentCssClass . " > " . $this->nodeSelector . ":nth-of-type($counter)";
+            $newNode = $node->find($nextNodeSelector);
+        }
+        return $nodeArray;
+    }
+
+    /**
+     * Retrieve array of checked nodes from structure array.
+     *
+     * @param array $structure
+     * @return array|null
+     */
+    protected function getCheckedNodes($structure)
+    {
+        $pathArray = [];
+        if ($structure['isChecked'] == true) {
+            array_push($pathArray, $structure['name']);
+            if (is_array($structure['subnodes'])) {
+                foreach ($structure['subnodes'] as $node) {
+                    array_push($pathArray, $this->getCheckedNodes($node));
+                }
+            }
+            return $pathArray;
+        }
+        return null;
+    }
+
+    /**
+     * Method for recursive walk array of checked elements.
+     * If element haven't subnodes, adds element's path to $checkedNodesPaths
+     *
+     * @param array $pathArray
+     * @param string $rootPath
+     * @return string
+     */
+    protected function getPathFromArray($pathArray, $rootPath = '')
+    {
+        $path = '';
+        $rootPath = $rootPath == '' ? $pathArray[0] : $rootPath . '/' . $pathArray[0];
+        if (count($pathArray) > 1) {
+            for ($counter = 1; $counter < count($pathArray); $counter++) {
+                $path .= $this->getPathFromArray($pathArray[$counter], $rootPath);
+            }
+        } else {
+            $path = $rootPath;
+            $this->checkedNodesPaths[] = $path;
+        }
+        return $path;
+    }
+
+    /**
+     * Returns array of paths of all selected elements.
+     *
+     * @return array
+     */
+    public function getValue()
+    {
+        $pathsArray = [];
+        $structure = $this->getStructure();
+        foreach ($structure as $structureChunk) {
+            $pathsArray[] = $this->getCheckedNodes($structureChunk);
+        }
+        foreach ($pathsArray as $pathArray) {
+            $this->getPathFromArray($pathArray);
+        }
+        return $this->checkedNodesPaths;
+    }
+}
diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultiselectlistElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultiselectlistElement.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b2526fa6f667bfb0e3e6aa327faeb08e268fd1e
--- /dev/null
+++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/MultiselectlistElement.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Mtf\Client\Driver\Selenium\Element;
+
+use Mtf\Client\Driver\Selenium\Element;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Typified element class for  Multiple Select List elements
+ */
+class MultiselectlistElement extends MultiselectElement
+{
+    /**
+     * XPath selector for finding option by its position number
+     *
+     * @var string
+     */
+    protected $optionElement = './/*[contains(@class,"mselect-list-item")][%d]/label';
+
+    /**
+     * XPath selector for checking is option checked
+     *
+     * @var string
+     */
+    protected $optionCheckedElement = './/*[contains(@class, "mselect-checked")]/following-sibling::span';
+
+    /**
+     * Return Wrapped Element.
+     * If element was not created before:
+     * 1. Context is defined. If context was not passed to constructor - test case (all page) is taken as context
+     * 2. Attempt to get selenium element is performed in loop
+     * that is terminated if element is found or after timeout set in configuration
+     *
+     * @param bool $waitForElementPresent
+     * @return \PHPUnit_Extensions_Selenium2TestCase_Element|\PHPUnit_Extensions_Selenium2TestCase_Element_Select
+     */
+    protected function _getWrappedElement($waitForElementPresent = true)
+    {
+        return Element::_getWrappedElement($waitForElementPresent);
+    }
+
+    /**
+     * Select options by values in multiple select list
+     *
+     * @param array|string $values
+     * @throws \Exception
+     */
+    public function setValue($values)
+    {
+        $options = $this->getOptions();
+        $values = is_array($values) ? $values : [$values];
+
+        foreach ($options as $option) {
+            /** @var Element $option */
+            $optionText = $option->getText();
+            $isChecked = $option->find($this->optionCheckedElement, Locator::SELECTOR_XPATH)->isVisible();
+            $inArray = in_array($optionText, $values);
+            if (($isChecked && !$inArray) || (!$isChecked && $inArray)) {
+                $option->click();
+            }
+        }
+    }
+
+    /**
+     * Method that returns array with checked options in multiple select list
+     *
+     * @return array|string
+     */
+    public function getValue()
+    {
+        $checkedOptions = [];
+        $options = $this->getOptions();
+
+        foreach ($options as $option) {
+            /** @var Element $option */
+            $checkedOption = $option->find($this->optionCheckedElement, Locator::SELECTOR_XPATH);
+            if ($checkedOption->isVisible()) {
+                $checkedOptions[] = $checkedOption->getText();
+            }
+        }
+
+        return $checkedOptions;
+    }
+
+    /**
+     * Getting all options in multi select list
+     *
+     * @return array
+     */
+    protected function getOptions()
+    {
+        $options = [];
+        $counter = 1;
+
+        $newOption = $this->find(sprintf($this->optionElement, $counter), Locator::SELECTOR_XPATH);
+        while ($newOption->isVisible()) {
+            $options[] = $newOption;
+            $counter++;
+            $newOption = $this->find(sprintf($this->optionElement, $counter), Locator::SELECTOR_XPATH);
+        }
+
+        return $options;
+    }
+}
diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/Tree.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/Tree.php
new file mode 100644
index 0000000000000000000000000000000000000000..03e11557086e2ad11f371c9499e1c74f8f1e24e8
--- /dev/null
+++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/Tree.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Mtf\Client\Driver\Selenium\Element;
+
+use Mtf\Client\Driver\Selenium\Element;
+use Mtf\Client\Element as ElementInterface;
+
+/**
+ * Class Tree
+ * General class for tree elements. Holds general implementation of methods, which overrides in child classes.
+ *
+ * @package Mtf\Client\Driver\Selenium\Element
+ */
+abstract class Tree extends Element
+{
+    /**
+     * Css class for finding tree nodes
+     *
+     * @var string
+     */
+    protected $nodeCssClass;
+
+    /**
+     * Css class for detecting tree nodes
+     *
+     * @var string
+     */
+    protected $nodeSelector;
+
+    /**
+     * Css class for fetching node's name
+     *
+     * @var string
+     */
+    protected $nodeName;
+
+    /**
+     * @return mixed
+     */
+    abstract public function getStructure();
+
+    /**
+     * Drag'n'drop method is not accessible in this class.
+     * Throws exception if used.
+     *
+     * @param ElementInterface $target
+     * @throws \BadMethodCallException
+     */
+    public function dragAndDrop(ElementInterface $target)
+    {
+        throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)');
+    }
+
+    /**
+     * getValue method is not accessible in this class.
+     * Throws exception if used.
+     *
+     * @throws \BadMethodCallException
+     */
+    public function getValue()
+    {
+        throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)');
+
+    }
+
+    /**
+     * keys method is not accessible in this class.
+     * Throws exception if used.
+     *
+     * @param array $keys
+     * @throws \BadMethodCallException
+     */
+    public function keys(array $keys)
+    {
+        throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)');
+    }
+
+    /**
+     * Click a tree element by its path (Node names) in tree
+     *
+     * @param string $path
+     * @throws \InvalidArgumentException
+     */
+    public function setValue($path)
+    {
+        $pathChunkCounter = 0;
+        $pathArray = explode('/', $path);
+        $pathArrayLength = count($pathArray);
+        $structureChunk = $this->getStructure(); //Set the root of a structure as a first structure chunk
+        foreach ($pathArray as $pathChunk) {
+            $structureChunk = $this->deep($pathChunk, $structureChunk);
+            $structureChunk = ($pathChunkCounter == $pathArrayLength - 1) ?
+                $structureChunk['element'] : $structureChunk['subnodes'];
+            ++$pathChunkCounter;
+        }
+        if ($structureChunk) {
+            $needleElement = $structureChunk->find($this->nodeName);
+            $needleElement->click();
+        } else {
+            throw new \InvalidArgumentException('The path specified for tree is invalid');
+        }
+    }
+
+    /**
+     * Internal function for deeping in hierarchy of the tree structure
+     * Return the nested array if it exists or object of class Element if this is the final part of structure
+     *
+     * @param string $pathChunk
+     * @param array $structureChunk
+     * @return array|Element||false
+     */
+    protected function deep($pathChunk, $structureChunk)
+    {
+        if (is_array($structureChunk)) {
+            foreach ($structureChunk as $structureNode) {
+                $pattern = '/' . $pathChunk . '\s\([\d]+\)|' . $pathChunk . '/';
+                if (isset($structureNode) && preg_match($pattern, $structureNode['name'])) {
+                    return $structureNode;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     *  Recursive walks tree
+     *
+     * @param Element $node
+     * @param string $parentCssClass
+     * @return array
+     */
+    protected function _getNodeContent($node, $parentCssClass)
+    {
+        $nodeArray = [];
+        $nodeList = [];
+        $counter = 1;
+        $newNode = $node->find($parentCssClass . ' > ' . $this->nodeSelector . ':nth-of-type(' . $counter . ')');
+        //Get list of all children nodes to work with
+        while ($newNode->isVisible()) {
+            $nodeList[] = $newNode;
+            ++$counter;
+            $newNode = $node->find($parentCssClass . ' > ' . $this->nodeSelector . ':nth-of-type(' . $counter . ')');
+        }
+        //Write to array values of current node
+        foreach ($nodeList as $currentNode) {
+            /** @var Element $currentNode */
+            $nodesNames = $currentNode->find($this->nodeName);
+            $nodesContents = $currentNode->find($this->nodeCssClass);
+            $text = ltrim($nodesNames->getText());
+            $nodeArray[] = [
+                'name' => $text,
+                'element' => $currentNode,
+                'subnodes' => $nodesContents->isVisible() ?
+                        $this->_getNodeContent($nodesContents, $this->nodeCssClass) : null
+            ];
+        }
+        return $nodeArray;
+    }
+}
diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/TreeElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/TreeElement.php
index 7ece75ae2926ddfcd6e261dcc3b29fb909d41dea..4fbbe575a59f4583faf1100c9c3e6903adbd57d5 100644
--- a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/TreeElement.php
+++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/TreeElement.php
@@ -24,16 +24,12 @@
 
 namespace Mtf\Client\Driver\Selenium\Element;
 
-use Mtf\Client\Element as ElementInterface;
-use Mtf\Client\Driver\Selenium\Element;
-use Mtf\Client\Element\Locator;
-
 /**
  * Class TreeElement
  * Typified element class for Tree elements
  *
  */
-class TreeElement extends Element
+class TreeElement extends Tree
 {
     /**
      * Css class for finding tree nodes
@@ -43,96 +39,18 @@ class TreeElement extends Element
     protected $nodeCssClass = '.x-tree-node > .x-tree-node-ct';
 
     /**
-     * Drag'n'drop method is not accessible in this class.
-     * Throws exception if used.
-     *
-     * @param ElementInterface $target
-     * @throws \BadMethodCallException
-     */
-    public function dragAndDrop(ElementInterface $target)
-    {
-        throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)');
-    }
-
-    /**
-     * setValue method is not accessible in this class.
-     * Throws exception if used.
-     *
-     * @param string|array $value
-     * @throws \BadMethodCallException
-     */
-    public function setValue($value)
-    {
-        throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)');
-    }
-
-    /**
-     * getValue method is not accessible in this class.
-     * Throws exception if used.
+     * Css class for detecting tree nodes
      *
-     * @throws \BadMethodCallException
-     */
-    public function getValue()
-    {
-        throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)');
-
-    }
-
-    /**
-     * keys method is not accessible in this class.
-     * Throws exception if used.
-     *
-     * @param array $keys
-     * @throws \BadMethodCallException
-     */
-    public function keys(array $keys)
-    {
-        throw new \BadMethodCallException('Not applicable for this class of elements (TreeElement)');
-    }
-
-    /**
-     * Click a tree element by its path (Node names) in tree
-     *
-     * @param string $path
-     * @throws \InvalidArgumentException
+     * @var string
      */
-    public function clickByPath($path)
-    {
-        $pathChunkCounter = 0;
-        $pathArray = explode('/', $path);
-        $pathArrayLength = count($pathArray);
-        $structureChunk = $this->getStructure(); //Set the root of a structure as a first structure chunk
-        foreach ($pathArray as $pathChunk) {
-            $structureChunk = $this->deep($pathChunk, $structureChunk);
-            $structureChunk = ($pathChunkCounter == $pathArrayLength - 1) ?
-                $structureChunk['element'] : $structureChunk['subnodes'];
-            ++$pathChunkCounter;
-        }
-        if ($structureChunk) {
-            $needleElement = $structureChunk->find('div > a');
-            $needleElement->click();
-        } else {
-            throw new \InvalidArgumentException('The path specified for tree is invalid');
-        }
-    }
+    protected $nodeSelector = '.x-tree-node';
 
     /**
-     * Internal function for deeping in hierarchy of the tree structure
-     * Return the nested array if it exists or object of class Element if this is the final part of structure
+     * Css class for fetching node's name
      *
-     * @param string $pathChunk
-     * @param array $structureChunk
-     * @return array|Element||false
+     * @var string
      */
-    protected function deep($pathChunk, $structureChunk)
-    {
-        foreach ($structureChunk as $structureNode) {
-            if (isset($structureNode) && preg_match('/' . $pathChunk . ' \(\d+\)/', $structureNode['name'])) {
-                return $structureNode;
-            }
-        }
-        return false;
-    }
+    protected $nodeName = 'div > a';
 
     /**
      * Get structure of the tree element
@@ -143,43 +61,4 @@ class TreeElement extends Element
     {
         return $this->_getNodeContent($this, '.x-tree-root-node');
     }
-
-    /**
-     * Get recursive structure of the tree content
-     *
-     * @param Element $node
-     * @param string $parentCssClass
-     * @return array
-     */
-    protected function _getNodeContent($node, $parentCssClass)
-    {
-        $nodeArray = array();
-        $nodeList = array();
-        $counter = 1;
-
-        $newNode = $node->find($parentCssClass .' > .x-tree-node:nth-of-type(' . $counter . ')');
-
-        //Get list of all children nodes to work with
-        while ($newNode->isVisible()) {
-            $nodeList[] = $newNode;
-            ++$counter;
-            $newNode = $node->find($parentCssClass .' > .x-tree-node:nth-of-type(' . $counter . ')');
-        }
-
-        //Write to array values of current node
-        foreach ($nodeList as $currentNode) {
-            /** @var Element $currentNode */
-            $nodesNames = $currentNode->find('div > a > span');
-            $nodesContents = $currentNode->find($this->nodeCssClass);
-            $text = $nodesNames->getText();
-            $nodeArray[] = array(
-                'name' => $text,
-                'element' => $currentNode,
-                'subnodes' => $nodesContents->isVisible() ?
-                        $this->_getNodeContent($nodesContents, '.x-tree-node > .x-tree-node-ct') : null
-            );
-        }
-
-        return $nodeArray;
-    }
 }
diff --git a/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml b/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
index 954a17a51142c4c9345fdfe2d3def827b53d45b7..19edcac77746368272de05ee0b04d90da9e6e555 100644
--- a/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
+++ b/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" ?>
+<?xml version="1.0"?>
 <!--
 /**
  * Magento
@@ -46,7 +46,58 @@
     <ticketId>MTA-3</ticketId>
     <steps/>
   </testcase>
+  <testcase module="Magento\Catalog">
+    <id>MTA-179</id>
+    <ticketId>MTA-179</ticketId>
+    <name>CreateSimpleProductEntityTest</name>
+    <description>Test Creation for CreateSimpleProductEntity</description>
+    <module>Catalog</module>
+    <components>
+      <component>Products (CS)</component>
+    </components>
+    <steps>
+      <step>Login to the backend.</step>
+      <step>Navigate to Products &gt; Catalog.</step>
+      <step>Start to create simple product.</step>
+      <step>Fill in data according to attached data set.</step>
+      <step>Save Product.</step>
+      <step>Perform appropriate assertions.</step>
+    </steps>
+  </testcase>
   <testcase>
-    <id>MTA-46</id>
+    <id>MTA-42</id>
+    <ticketId>MTA-42</ticketId>
+    <name>CreateCustomerGroupEntityTest</name>
+    <description>Test Creation for CreateCustomerGroupEntity</description>
+    <module>Customer</module>
+    <components>
+      <component>Customer Groups (MX)</component>
+    </components>
+    <steps>
+      <step>Log in to backend as admin user.</step>
+      <step>Navigate to Stores&gt;Other Settings&gt;Customer Groups.</step>
+      <step>Start to create new Customer Group.</step>
+      <step>Fill in all data according to data set.</step>
+      <step>Click "Save Customer Group" button.</step>
+      <step>Perform all assertions.</step>
+    </steps>
+  </testcase>
+  <testcase>
+    <id>MTA-164</id>
+    <ticketId>MTA-164</ticketId>
+    <name>CreateNewsletterTemplateEntityTest</name>
+    <description>Test Creation for Create Newsletter Template Entity</description>
+    <module>Newsletter</module>
+    <components>
+      <component>Newsletters (MX)</component>
+    </components>
+    <steps>
+      <step>Login to backend.</step>
+      <step>Navigate to MARKETING -> Newsletter Template.</step>
+      <step>Add New Template.</step>
+      <step>Fill in all data according to data set.</step>
+      <step>Save.</step>
+      <step>Perform asserts.</step>
+    </steps>
   </testcase>
 </testcases>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Cache.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Cache.php
index df59b3f1a4f67ce4fff505e9aac0b5347ed2df98..095ed5ef24be78992c4dcfeba61c6b111f6b3ce2 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Cache.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Cache.php
@@ -90,7 +90,7 @@ class Cache extends Block
      */
     public function isStorageCacheFlushed()
     {
-        return $this->getMessageBlock()->getSuccessMessages() == $this->messagesText['cache_storage_flushed'];
+        return $this->getMessagesBlock()->getSuccessMessages() == $this->messagesText['cache_storage_flushed'];
     }
 
     /**
@@ -100,7 +100,7 @@ class Cache extends Block
      */
     public function isMagentoCacheFlushed()
     {
-        return $this->getMessageBlock()->getSuccessMessages() == $this->messagesText['cache_magento_flushed'];
+        return $this->getMessagesBlock()->getSuccessMessages() == $this->messagesText['cache_magento_flushed'];
     }
 
     /**
@@ -108,7 +108,7 @@ class Cache extends Block
      *
      * @return \Magento\Core\Test\Block\Messages
      */
-    protected function getMessageBlock()
+    protected function getMessagesBlock()
     {
         return Factory::getBlockFactory()->getMagentoCoreMessages(
             $this->_rootElement->find($this->messagesSelector, Locator::SELECTOR_XPATH)
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/FormPageActions.php
index 6dbeb79f59de0e88696e2d889145018e6e5eef00..92a90eab91c8c239838b63896ea06df9fe66b065 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/FormPageActions.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/FormPageActions.php
@@ -24,6 +24,8 @@
 
 namespace Magento\Backend\Test\Block;
 
+use Mtf\Client\Element\Locator;
+
 /**
  * Class FormPageActions
  * Form page actions block
@@ -66,6 +68,20 @@ class FormPageActions extends PageActions
      */
     protected $deleteButton = '#delete';
 
+    /**
+     * Magento loader
+     *
+     * @var string
+     */
+    protected $loader = '//ancestor::body/div[@data-role="loader"]';
+
+    /**
+     * Magento varienLoader.js loader
+     *
+     * @var string
+     */
+    protected $loaderOld = '//ancestor::body/div[@id="loading-mask"]';
+
     /**
      * Click on "Back" button
      */
@@ -98,8 +114,8 @@ class FormPageActions extends PageActions
     public function save()
     {
         $this->_rootElement->find($this->saveButton)->click();
-        $this->waitForElementNotVisible('.popup popup-loading');
-        $this->waitForElementNotVisible('.loader');
+        $this->waitForElementNotVisible($this->loader, Locator::SELECTOR_XPATH);
+        $this->waitForElementNotVisible($this->loaderOld, Locator::SELECTOR_XPATH);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/FormTabs.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/FormTabs.php
index 354c616c39310b5bd9521f1b6d808ae19584b37b..fd68db66592c63f84854d687e89619b8333b25d7 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/FormTabs.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/FormTabs.php
@@ -18,7 +18,6 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @api
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
@@ -26,17 +25,17 @@
 namespace Magento\Backend\Test\Block\Widget;
 
 use Mtf\Block\Mapper;
-use Mtf\Fixture\FixtureInterface;
 use Mtf\Client\Element;
+use Mtf\Util\XmlConverter;
+use Mtf\Util\Iterator\File;
+use Mtf\Block\BlockFactory;
 use Mtf\Client\Element\Locator;
+use Mtf\Fixture\FixtureInterface;
 use Mtf\Fixture\InjectableFixture;
-use Mtf\Util\Iterator\File;
-use Mtf\Util\XmlConverter;
 
 /**
  * Class FormTabs
  * Is used to represent any form with tabs on the page
- *
  */
 class FormTabs extends Form
 {
@@ -61,15 +60,17 @@ class FormTabs extends Form
      * @constructor
      * @param Element $element
      * @param Mapper $mapper
+     * @param BlockFactory $blockFactory
      * @param XmlConverter $xmlConverter
      */
     public function __construct(
         Element $element,
         Mapper $mapper,
+        BlockFactory $blockFactory,
         XmlConverter $xmlConverter
     ) {
         $this->xmlConverter = $xmlConverter;
-        parent::__construct($element, $mapper);
+        parent::__construct($element, $blockFactory, $mapper);
     }
 
     /**
@@ -111,7 +112,7 @@ class FormTabs extends Form
      * Fill form with tabs
      *
      * @param FixtureInterface $fixture
-     * @param Element $element
+     * @param Element|null $element
      * @return FormTabs
      */
     public function fill(FixtureInterface $fixture, Element $element = null)
@@ -170,24 +171,34 @@ class FormTabs extends Form
     }
 
     /**
-     * Verify form with tabs
+     * Get data of the tabs
      *
-     * @param FixtureInterface $fixture
-     * @param Element $element
-     * @return bool
+     * @param FixtureInterface|null $fixture
+     * @param Element|null $element
+     * @return array
      */
-    public function verify(FixtureInterface $fixture, Element $element = null)
+    public function getData(FixtureInterface $fixture = null, Element $element = null)
     {
-        $tabs = $this->getFieldsByTabs($fixture);
+        $data = [];
 
-        foreach ($tabs as $tab => $tabFields) {
-            $this->openTab($tab);
-            if (!$this->getTabElement($tab)->verifyFormTab($tabFields, $this->_rootElement)) {
-                return false;
+        if (null === $fixture) {
+            foreach ($this->tabs as $tabName => $tab) {
+                $this->openTab($tabName);
+                $tabData = $this->getTabElement($tabName)->getDataFormTab();
+                $data = array_merge($data, $tabData);
+            }
+        } else {
+            $isHasData = ($fixture instanceof InjectableFixture) ? $fixture->hasData() : true;
+            $tabsFields = $isHasData ? $this->getFieldsByTabs($fixture) : [];
+            foreach ($this->tabs as $tabName => $tab) {
+                $this->openTab($tabName);
+                $tabFields = isset($tabsFields[$tabName]) ? $tabsFields[$tabName] : [];
+                $tabData = $this->getTabElement($tabName)->getDataFormTab($tabFields, $this->_rootElement);
+                $data = array_merge($data, $tabData);
             }
         }
 
-        return true;
+        return $data;
     }
 
     /**
@@ -279,7 +290,7 @@ class FormTabs extends Form
     {
         $tabClass = $this->tabs[$tabName]['class'];
         /** @var $tabElement Tab */
-        $tabElement = new $tabClass($this->_rootElement, $this->mapper);
+        $tabElement = new $tabClass($this->_rootElement, $this->blockFactory, $this->mapper);
         if (!$tabElement instanceof Tab) {
             throw new \Exception('Wrong Tab Class.');
         }
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
index 4ee1be06fb6143bad1798bd38cb56fa72d5248c3..ad48d1e9ff26fb6662c272753ae9d0c021fe9c58 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Grid.php
@@ -32,7 +32,6 @@ use Mtf\Client\Element\Locator;
 /**
  * Abstract class Grid
  * Basic grid actions
- *
  */
 abstract class Grid extends Block
 {
@@ -50,6 +49,13 @@ abstract class Grid extends Block
      */
     protected $searchButton = '[title=Search][class*=action]';
 
+    /**
+     * Locator for 'Sort' link
+     *
+     * @var string
+     */
+    protected $sortLink = "[name='%s'][title='%s']";
+
     /**
      * Locator value for 'Reset' button
      *
@@ -282,7 +288,7 @@ abstract class Grid extends Block
             $this->search($filter);
         }
         $location = '//div[@class="grid"]//tr[';
-        $rows = array();
+        $rows = [];
         foreach ($filter as $value) {
             $rows[] = 'td[text()[normalize-space()="' . $value . '"]]';
         }
@@ -301,4 +307,18 @@ abstract class Grid extends Block
     {
         return $this->getRow($filter, $isSearchable)->isVisible();
     }
+
+    /**
+     * Sort grid by field
+     *
+     * @param $field
+     * @param string $sort
+     */
+    public function sortGridByField($field, $sort = "desc")
+    {
+        $sortBlock = $this->_rootElement->find(sprintf($this->sortLink, $field, $sort));
+        if ($sortBlock->isVisible()) {
+            $sortBlock->click();
+        }
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Tab.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Tab.php
index 14efb9833c1ac38ce69f2d24cbf9153beb8bd865..5fe1995edfcc5930e1b64e5ada3dfa17f6d05907 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Tab.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/Tab.php
@@ -18,20 +18,18 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @api
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
 namespace Magento\Backend\Test\Block\Widget;
 
-use Mtf\Block\Form as AbstractForm;
 use Mtf\Client\Element;
+use Mtf\Block\Form as AbstractForm;
 
 /**
  * Class Tab
  * Is used to represent any tab on the page
- *
  */
 class Tab extends AbstractForm
 {
@@ -39,10 +37,10 @@ class Tab extends AbstractForm
      * Fill data to fields on tab
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
-    public function fillFormTab(array $fields, Element $element)
+    public function fillFormTab(array $fields, Element $element = null)
     {
         $data = $this->dataMapping($fields);
         $this->_fill($data, $element);
@@ -51,26 +49,25 @@ class Tab extends AbstractForm
     }
 
     /**
-     * Verify data to fields on tab
-     *
-     * @param array $fields
-     * @param Element $element
+     * Get data of tab
      *
-     * @return bool
+     * @param array|null $fields
+     * @param Element|null $element
+     * @return array
      */
-    public function verifyFormTab(array $fields, Element $element)
+    public function getDataFormTab($fields = null, Element $element = null)
     {
         $data = $this->dataMapping($fields);
-        return $this->_verify($data, $element);
+        return $this->_getData($data, $element);
     }
 
     /**
      * Update data to fields on tab
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      */
-    public function updateFormTab(array $fields, Element $element)
+    public function updateFormTab(array $fields, Element $element = null)
     {
         $this->fillFormTab($fields, $element);
     }
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/Date.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/Date.php
new file mode 100644
index 0000000000000000000000000000000000000000..5186e8a1752d82fd0739854b5a5ccd7a378c7b0f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Fixture/Date.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\Fixture;
+
+use Mtf\Fixture\FixtureInterface;
+
+/**
+ * Class Date
+ *
+ * Data keys:
+ *  - pattern (Format a local time/date with delta, e.g. 'm-d-Y -3 days' = current day - 3 days)
+ */
+class Date implements FixtureInterface
+{
+    /**
+     * Date for fill on form
+     *
+     * @var string
+     */
+    protected $data;
+
+    /**
+     * @param array $params
+     * @param array $data
+     * @throws \Exception
+     */
+    public function __construct(array $params, array $data = [])
+    {
+        $this->params = $params;
+        if (isset($data['pattern']) && $data['pattern'] !== '-') {
+            $matches = [];
+            $delta = '';
+            if (preg_match_all('/(\+|-)\d+.+/', $data['pattern'], $matches)) {
+                $delta = $matches[0][0];
+            }
+            $timestamp = $delta === '' ? time() : strtotime($delta);
+            if (!$timestamp) {
+                throw new \Exception('Invalid date format for "' . $this->params['attribute_code'] . '" field');
+            }
+            $date = date(str_replace($delta, '', $data['pattern']), $timestamp);
+            if (!$date) {
+                $date = date('m/d/Y');
+            }
+            $this->data = $date;
+        }
+    }
+
+    /**
+     * Persists prepared data into application
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param $key [optional]
+     * @return mixed
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return string
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php
index 5ec3f35bedd7742ed310d61fd910d5cc3f65123b..e1a07a4a27cc73e0f61949d6949b29a509b4e5a4 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/AdminAuthLogin.php
@@ -58,7 +58,7 @@ class AdminAuthLogin extends Page
      *
      * @var string
      */
-    protected $messageBlock = '#messages .messages';
+    protected $messagesBlock = '#messages .messages';
 
     /**
      * Constructor
@@ -99,7 +99,7 @@ class AdminAuthLogin extends Page
      */
     public function getMessagesBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messageBlock));
+        return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messagesBlock));
     }
 
     public function waitForHeaderBlock()
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
index 80f3dc3f826948f8b326fdccb02e48c3e7a8a993..647546e12bb6752421ad7ccf964abf15838329ec 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
@@ -66,10 +66,10 @@ class Bundle extends Tab
      * Fill bundle options
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
-    public function fillFormTab(array $fields, Element $element)
+    public function fillFormTab(array $fields, Element $element = null)
     {
         if (!isset($fields['bundle_selections'])) {
             return $this;
@@ -90,10 +90,10 @@ class Bundle extends Tab
      * Update bundle options
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return void
      */
-    public function updateFormTab(array $fields, Element $element)
+    public function updateFormTab(array $fields, Element $element = null)
     {
         if (!isset($fields['bundle_selections'])) {
             return;
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
index a9a83f2f44003281a0b8a42de3fffb1ef14cc255..c1b300dfbf7c706c9fea241b9d5bda74a548b1c7 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
@@ -31,7 +31,7 @@ use Mtf\Client\Element\Locator;
 
 /**
  * Class Option
- * Bundle options
+ * Bundle product options block
  */
 class Option extends Block
 {
@@ -40,7 +40,7 @@ class Option extends Block
      *
      * @var string
      */
-    protected $searchGridBlock = '[role=dialog][style*="display: block;"]';
+    protected $searchGridBlock = "ancestor::body//div[contains(@style,'display: block') and @role='dialog']";
 
     /**
      * Added product row
@@ -87,14 +87,12 @@ class Option extends Block
     /**
      * Get grid for assigning products for bundle option
      *
-     * @param Element $context
      * @return \Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Search\Grid
      */
-    protected function getSearchGridBlock(Element $context = null)
+    protected function getSearchGridBlock()
     {
-        $element = $context ? : $this->_rootElement;
         return Factory::getBlockFactory()->getMagentoBundleAdminhtmlCatalogProductEditTabBundleOptionSearchGrid(
-            $element->find($this->searchGridBlock)
+            $this->_rootElement->find($this->searchGridBlock, Locator::SELECTOR_XPATH)
         );
     }
 
@@ -107,7 +105,7 @@ class Option extends Block
      */
     protected function getSelectionBlock($rowNumber, Element $context = null)
     {
-        $element = $context ? : $this->_rootElement;
+        $element = $context !== null ? $context : $this->_rootElement;
         return Factory::getBlockFactory()->getMagentoBundleAdminhtmlCatalogProductEditTabBundleOptionSelection(
             $element->find($this->selectionBlock . '_' . $rowNumber)
         );
@@ -115,6 +113,8 @@ class Option extends Block
 
     /**
      * Expand block
+     *
+     * @return void
      */
     public function expand()
     {
@@ -128,6 +128,7 @@ class Option extends Block
      *
      * @param array $fields
      * @param Element $context
+     * @return void
      */
     public function fillBundleOption(array $fields, Element $context)
     {
@@ -136,7 +137,7 @@ class Option extends Block
         foreach ($fields['assigned_products'] as $field) {
             if (is_array($field)) {
                 $this->_rootElement->find($this->addProducts)->click();
-                $searchBlock = $this->getSearchGridBlock($context);
+                $searchBlock = $this->getSearchGridBlock();
                 $searchBlock->searchAndSelect($field['search_data']);
                 $searchBlock->addProducts();
                 $this->getSelectionBlock($rowNumber)->fillProductRow($field['data']);
@@ -149,6 +150,7 @@ class Option extends Block
      * Update bundle option (now only general data, skipping assignments)
      *
      * @param array $fields
+     * @return void
      */
     public function updateBundleOption(array $fields)
     {
@@ -159,6 +161,7 @@ class Option extends Block
      * Fill in general data to bundle option
      *
      * @param array $fields
+     * @return void
      */
     private function fillOptionData(array $fields)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Backend/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Form.xml
similarity index 100%
rename from dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Backend/ProductForm.xml
rename to dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Product/Form.xml
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php
index 97ff839497a790b8d680f09fa9be1e976b6abd69..11efcbd7f85114e2f71da9b1ed91519c10ffcb19 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Catalog/Product/View/Type/Bundle.php
@@ -24,21 +24,21 @@
 
 namespace Magento\Bundle\Test\Block\Catalog\Product\View\Type;
 
-use Mtf\Factory\Factory;
 use Mtf\Client\Element;
-use Magento\Catalog\Test\Block\Product\View\Options;
+use Mtf\Factory\Factory;
+use Magento\Catalog\Test\Block\Product\View\CustomOptions;
 
 /**
  * Class Bundle
  * Catalog bundle product info block
- *
  */
-class Bundle extends Options
+class Bundle extends CustomOptions
 {
     /**
      * Fill bundle options
      *
      * @param array $bundleOptions
+     * @return void
      */
     public function fillBundleOptions($bundleOptions)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php
index 685b2e024213fa9759895e8b0810ea766504274a..6e5a7bf751e8f44f48aeef60677b54d1ff02b7b0 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php
@@ -32,7 +32,6 @@ use Mtf\Repository\RepositoryFactory;
 
 /**
  * Class CatalogProductBundle
- *
  */
 class CatalogProductBundle extends InjectableFixture
 {
@@ -195,7 +194,7 @@ class CatalogProductBundle extends InjectableFixture
         'default_value' => '',
         'input' => 'text',
         'group' => 'advanced-pricing',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions'
     ];
 
     protected $has_options = [
@@ -342,7 +341,7 @@ class CatalogProductBundle extends InjectableFixture
         'default_value' => '',
         'input' => 'price',
         'group' => 'product-details',
-        'fixture' => 'Magento\Bundle\Test\Fixture\Bundle\Price'
+        'source' => 'Magento\Bundle\Test\Fixture\Bundle\Price'
     ];
 
     protected $price_type = [
@@ -551,7 +550,7 @@ class CatalogProductBundle extends InjectableFixture
         'backend_type' => 'virtual',
         'is_required' => '1',
         'group' => 'bundle',
-        'fixture' => 'Magento\Bundle\Test\Fixture\Bundle\Selections',
+        'source' => 'Magento\Bundle\Test\Fixture\Bundle\Selections',
     ];
 
     protected $custom_options = [
@@ -559,7 +558,7 @@ class CatalogProductBundle extends InjectableFixture
         'backend_type' => 'virtual',
         'is_required' => '0',
         'group' => 'customer-options',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
     ];
 
     public function getCategoryIds()
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleDynamicTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleDynamicTest.php
index 86083468f08ca57d926f905fd742b1485fd7cad0..771e737c60d8e9cf42d4ac43d8bfc85b866bee59 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleDynamicTest.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleDynamicTest.php
@@ -28,10 +28,16 @@ use Mtf\Factory\Factory;
 use Mtf\TestCase\Functional;
 use Magento\Bundle\Test\Fixture\Bundle;
 
+/**
+ * Class BundleDynamicTest
+ * Bundle product dynamic test
+ */
 class BundleDynamicTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -42,6 +48,7 @@ class BundleDynamicTest extends Functional
      * Creating bundle (dynamic) product and assigning it to the category
      *
      * @ZephyrId MAGETWO-12702
+     * @return void
      */
     public function testCreate()
     {
@@ -51,12 +58,12 @@ class BundleDynamicTest extends Functional
         //Pages & Blocks
         $manageProductsGrid = Factory::getPageFactory()->getCatalogProductIndex();
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getForm();
         //Steps
         $manageProductsGrid->open();
         $manageProductsGrid->getProductBlock()->addProduct('bundle');
-        $productBlockForm->fill($bundle);
-        $productBlockForm->save($bundle);
+        $productForm->fillProduct($bundle);
+        $createProductPage->getFormAction()->save();
         //Verification
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         // Flush cache
@@ -73,6 +80,7 @@ class BundleDynamicTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param Bundle $product
+     * @return void
      */
     protected function assertOnGrid($product)
     {
@@ -83,7 +91,10 @@ class BundleDynamicTest extends Functional
     }
 
     /**
+     * Checking the product on the category page
+     *
      * @param Bundle $product
+     * @return void
      */
     protected function assertOnCategory($product)
     {
@@ -104,8 +115,8 @@ class BundleDynamicTest extends Functional
         $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice());
 
         // @TODO: add click on "Customize and Add To Cart" button and assert options count
-        $productOptionsBlock = $productPage->getOptionsBlock();
-        $actualOptions = $productOptionsBlock->getBundleOptions();
+        $productOptionsBlock = $productPage->getCustomOptionsBlock();
+        $actualOptions = $productOptionsBlock->getOptions();
         $expectedOptions = $product->getBundleOptions();
         foreach ($actualOptions as $optionType => $actualOption) {
             $this->assertContains($expectedOptions[$optionType], $actualOption);
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleFixedTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleFixedTest.php
index fcfd7a683c5c867d12fd7cac9fcabb5e69b3aa7a..efa6cc081d9f20493c7f11bfabc7a20d76205bd7 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleFixedTest.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/BundleFixedTest.php
@@ -28,10 +28,16 @@ use Mtf\Factory\Factory;
 use Mtf\TestCase\Functional;
 use Magento\Bundle\Test\Fixture\Bundle;
 
+/**
+ * Class BundleFixedTest
+ * Bundle product fixed test
+ */
 class BundleFixedTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -42,6 +48,7 @@ class BundleFixedTest extends Functional
      * Creating bundle (fixed) product and assigning it to the category
      *
      * @ZephyrId MAGETWO-12622
+     * @return void
      */
     public function testCreate()
     {
@@ -51,12 +58,12 @@ class BundleFixedTest extends Functional
         //Pages & Blocks
         $manageProductsGrid = Factory::getPageFactory()->getCatalogProductIndex();
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
-        $productBlockForm = $createProductPage->getProductBlockForm();
         //Steps
         $manageProductsGrid->open();
         $manageProductsGrid->getProductBlock()->addProduct('bundle');
-        $productBlockForm->fill($bundle);
-        $productBlockForm->save($bundle);
+        $productForm = $createProductPage->getForm();
+        $productForm->fillProduct($bundle);
+        $createProductPage->getFormAction()->save();
         //Verification
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         // Flush cache
@@ -73,6 +80,7 @@ class BundleFixedTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param Bundle $product
+     * @return void
      */
     protected function assertOnGrid($product)
     {
@@ -83,7 +91,10 @@ class BundleFixedTest extends Functional
     }
 
     /**
+     * Checking the product on the category page
+     *
      * @param Bundle $product
+     * @return void
      */
     protected function assertOnCategory($product)
     {
@@ -104,8 +115,8 @@ class BundleFixedTest extends Functional
         $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice());
 
         // @TODO: add click on "Customize and Add To Cart" button and assert options count
-        $productOptionsBlock = $productPage->getOptionsBlock();
-        $actualOptions = $productOptionsBlock->getBundleOptions();
+        $productOptionsBlock = $productPage->getCustomOptionsBlock();
+        $actualOptions = $productOptionsBlock->getOptions();
         $expectedOptions = $product->getBundleOptions();
         foreach ($actualOptions as $optionType => $actualOption) {
             $this->assertContains($expectedOptions[$optionType], $actualOption);
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/EditBundleTest.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/EditBundleTest.php
index 46d65ac45d8803c83a5117f234dedfc571689d8d..25961f99bd2b6869e7c02ccbcb3d377c1abafafe 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/EditBundleTest.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/TestCase/EditBundleTest.php
@@ -28,8 +28,17 @@ use Mtf\Factory\Factory;
 use Mtf\TestCase\Functional;
 use Magento\Bundle\Test\Fixture\Bundle;
 
+/**
+ * Class EditBundleTest
+ * Edit bundle product test
+ */
 class EditBundleTest extends Functional
 {
+    /**
+     * Login user to backend
+     *
+     * @return void
+     */
     protected function setUp()
     {
         Factory::getApp()->magentoBackendLoginUser();
@@ -41,6 +50,9 @@ class EditBundleTest extends Functional
      * @dataProvider createDataProvider
      * @ZephyrId MAGETWO-12842
      * @ZephyrId MAGETWO-12841
+     *
+     * @param $fixture
+     * @return void
      */
     public function testEditBundle($fixture)
     {
@@ -56,7 +68,7 @@ class EditBundleTest extends Functional
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $gridBlock = $productGridPage->getProductGrid();
         $editProductPage = Factory::getPageFactory()->getCatalogProductEdit();
-        $productBlockForm = $editProductPage->getProductBlockForm();
+        $productForm = $editProductPage->getForm();
         $cachePage = Factory::getPageFactory()->getAdminCache();
 
         $productGridPage->open();
@@ -66,8 +78,8 @@ class EditBundleTest extends Functional
                 'type' => 'Bundle Product'
             )
         );
-        $productBlockForm->fill($editProduct);
-        $productBlockForm->save($editProduct);
+        $productForm->fillProduct($editProduct);
+        $editProductPage->getFormAction()->save();
         //Verifying
         $editProductPage->getMessagesBlock()->assertSuccessMessage();
         // Flush cache
@@ -78,6 +90,11 @@ class EditBundleTest extends Functional
         $this->assertOnCategory($editProduct, $product->getCategoryName());
     }
 
+    /**
+     * Create data provider
+     *
+     * @return array
+     */
     public function createDataProvider()
     {
         return array(
@@ -90,6 +107,7 @@ class EditBundleTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param Bundle $product
+     * @return void
      */
     protected function assertOnGrid($product)
     {
@@ -100,8 +118,11 @@ class EditBundleTest extends Functional
     }
 
     /**
+     * Check the product on the category page
+     *
      * @param Bundle $product
      * @param string $categoryName
+     * @return void
      */
     protected function assertOnCategory($product, $categoryName)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
index 020276ffbc540ee4ad947bcc27b5439a31c6f308..945ded51fd17e0f71518b67f806a9c416f65c70c 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
@@ -57,6 +57,13 @@ class Tree extends Block
      */
     protected $templateBlock = './ancestor::body';
 
+    /**
+     * Category tree
+     *
+     * @var string
+     */
+    protected $treeElement = '.tree-holder';
+
     /**
      * Get backend abstract block
      *
@@ -86,7 +93,7 @@ class Tree extends Block
     public function selectCategory($path)
     {
         $this->expandAllCategories();
-        $this->_rootElement->clickByPath($path);
+        $this->_rootElement->find($this->treeElement, Locator::SELECTOR_CSS, 'tree')->setValue($path);
         $this->getTemplateBlock()->waitLoader();
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/AffectedAttributeSetForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/AffectedAttributeSetForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..56526dd15e6816dfbd171f8d18a7fdc5513214ff
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/AffectedAttributeSetForm.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product;
+
+use Mtf\Client\Element;
+use Mtf\Client\Element\Locator;
+use Mtf\Fixture\FixtureInterface;
+use Magento\Backend\Test\Block\Widget\Form as ParentForm;
+
+/**
+ * Class AffectedAttributeSet
+ * Choose affected attribute set dialog popup window
+ */
+class AffectedAttributeSetForm extends ParentForm
+{
+    /**
+     * 'Confirm' button locator
+     *
+     * @var string
+     */
+    protected $confirmButton = '//parent::div[div[@id="affected-attribute-set-form"]]//button[contains(@id,"confirm-button")]';
+
+    /**
+     * Locator buttons new name attribute set
+     *
+     * @var string
+     */
+    protected $affectedAttributeSetNew = '#affected-attribute-set-new';
+
+    /**
+     * Fill popup form
+     *
+     * @param FixtureInterface $product
+     * @param Element|null $element
+     * @return $this
+     */
+    public function fill(FixtureInterface $product, Element $element = null)
+    {
+        $data = $product->getData('affect_configurable_product_attributes');
+        if (!empty($data)) {
+            $this->_rootElement->find($this->affectedAttributeSetNew)->click();
+            $fields = ['new_attribute_set_name' => strval($data)];
+            $mapping = $this->dataMapping($fields);
+            $this->_fill($mapping, $element);
+        }
+        return $this;
+    }
+
+    /**
+     * Click confirm button
+     *
+     * @return void
+     */
+    public function confirm()
+    {
+        if ($this->_rootElement->find($this->confirmButton, Locator::SELECTOR_XPATH)->isVisible()) {
+            $this->_rootElement->find($this->confirmButton, Locator::SELECTOR_XPATH)->click();
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/view/frontend/blank.phtml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/AffectedAttributeSetForm.xml
similarity index 80%
rename from app/code/Magento/Theme/view/frontend/blank.phtml
rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/AffectedAttributeSetForm.xml
index b1351ddab8ed1aa308d243d6f0806c74c16a02ef..34163c9cb58c235ac00af759f11920c4d635ea2d 100644
--- a/app/code/Magento/Theme/view/frontend/blank.phtml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/AffectedAttributeSetForm.xml
@@ -1,4 +1,5 @@
-<?php
+<?xml version="1.0" ?>
+<!--
 /**
  * Magento
  *
@@ -21,10 +22,11 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-?>
-<?php
-/**
- * Blank page Template for \Magento\Theme\Block\Html
- */
-?>
-<?php echo $this->getChildHtml('content'); ?>
+-->
+<mapping strict="0">
+    <fields>
+        <new_attribute_set_name>
+            <selector>[name='new-attribute-set-name']</selector>
+        </new_attribute_set_name>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab.php
index 7f612055742d34bbcf438278092f69565a296cdf..192f4ea671de1f20458782de0b20ea119248890a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab.php
@@ -24,64 +24,95 @@
 
 namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit;
 
+use Mtf\ObjectManager;
 use Mtf\Client\Element;
-use Mtf\Client\Element\Locator;
 use Magento\Backend\Test\Block\Widget\Tab;
-use Mtf\Factory\Factory;
 
 /**
- * Custom Options Tab
- *
+ * Class AdvancedPricingTab
+ * Product advanced pricing tab
  */
 class AdvancedPricingTab extends Tab
 {
     /**
-     * Fill group price options
+     * Class name 'Subform' of the main tab form
+     *
+     * @var array
+     */
+    protected $childrenForm = [
+        'group_price' => 'AdvancedPricingTab\OptionGroup',
+        'tier_price' => 'AdvancedPricingTab\OptionTier'
+    ];
+
+    /**
+     * Fill 'Advanced price' product form on tab
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
-    public function fillFormTab(array $fields, Element $element)
+    public function fillFormTab(array $fields, Element $element = null)
     {
-        $root = $element;
-        $this->_rootElement->waitUntil(
-            function () use ($root) {
-                return $root->find('[data-tab-panel=advanced-pricing]')->isVisible();
-            }
-        );
-        if (isset($fields['special_price']['value'])) {
-            $container = $root->find('#attribute-special_price-container');
-            Factory::getBlockFactory()
-                ->getMagentoCatalogAdminhtmlProductEditAdvancedPricingTabSpecialOption($container)
-                ->fill($fields['special_price']);
-        }
+        foreach ($fields as $fieldName => $field) {
+            // Fill form
+            if (isset($this->childrenForm[$fieldName]) && is_array($field['value'])) {
+                /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */
+                $optionsForm = $this->blockFactory->create(
+                    __NAMESPACE__ . '\\' . $this->childrenForm[$fieldName],
+                    ['element' => $this->_rootElement]
+                );
 
-        if (isset($fields['group_price']['value'])) {
-            $button = $root->find('[title="Add Group Price"]');
-            $container = $root->find('#attribute-group_price-container');
-            foreach ($fields['group_price']['value'] as $rowId => $data) {
-                $rowPrefix = 'group_price_row_' . $rowId;
-                $button->click();
-                $row = $container->find('//tr[td[select[@id="' . $rowPrefix . '_website"]]]', Locator::SELECTOR_XPATH);
-                Factory::getBlockFactory()
-                    ->getMagentoCatalogAdminhtmlProductEditAdvancedPricingTabGroupOption($row)
-                    ->fill($rowPrefix, $data);
+                foreach ($field['value'] as $key => $option) {
+                    ++$key;
+                    $optionsForm->fillOptions(
+                        $option,
+                        $this->_rootElement->find(
+                            '#attribute-' . $fieldName . '-container tbody tr:nth-child(' . $key . ')'
+                        )
+                    );
+                }
+            } elseif (!empty($field['value'])) {
+                $data = $this->dataMapping([$fieldName => $field]);
+                $this->_fill($data, $this->_rootElement);
             }
         }
-        if (isset($fields['tier_price']['value'])) {
-            $button = $root->find('[title="Add Tier"]');
 
-            $container = $root->find('#attribute-tier_price-container');
-            foreach ($fields['tier_price']['value'] as $rowId => $data) {
-                $rowPrefix = 'tier_price_row_' . $rowId;
-                $button->click();
-                $row = $container->find('//tr[td[select[@id="' . $rowPrefix . '_website"]]]', Locator::SELECTOR_XPATH);
-                Factory::getBlockFactory()
-                    ->getMagentoCatalogAdminhtmlProductEditAdvancedPricingTabGroupOption($row)
-                    ->fill($rowPrefix, $data);
+        return $this;
+    }
+
+    /**
+     * Get data of tab
+     *
+     * @param array|null $fields
+     * @param Element|null $element
+     * @return array
+     */
+    public function getDataFormTab($fields = null, Element $element = null)
+    {
+        $formData = [];
+        foreach ($fields as $fieldName => $field) {
+            // Data collection forms
+            if (isset($this->childrenForm[$fieldName]) && is_array($field['value'])) {
+                /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */
+                $optionsForm = $this->blockFactory->create(
+                    __NAMESPACE__ . '\\' . $this->childrenForm[$fieldName],
+                    ['element' => $this->_rootElement]
+                );
+
+                foreach ($field['value'] as $key => $option) {
+                    $formData[$fieldName][$key++] = $optionsForm->getDataOptions(
+                        $option,
+                        $this->_rootElement->find(
+                            '#attribute-' . $fieldName . '-container tbody tr:nth-child(' . $key . ')'
+                        )
+                    );
+                }
+            } elseif (!empty($field['value'])) {
+                $data = $this->dataMapping([$fieldName => $field]);
+                $formData[$fieldName] = $this->_getData($data, $this->_rootElement);
             }
         }
-        return $this;
+
+        return $formData;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/GroupOption.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/GroupOption.php
deleted file mode 100644
index 45ee4077a581bcb9ac4e86fd5226085f65f3a312..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/GroupOption.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab;
-
-use Mtf\Client\Element;
-use Mtf\Client\Element\Locator;
-use Mtf\Block\Block;
-
-/**
- * Select Type
- */
-class GroupOption extends Block
-{
-    /**
-     * Fill
-     *
-     * @param string $rowPrefix
-     * @param array $data
-     */
-    public function fill($rowPrefix, $data)
-    {
-        if (isset($data['website'])) {
-            $this->_rootElement
-                ->find('#' . $rowPrefix . '_website', Locator::SELECTOR_CSS, 'select')
-                ->setValue($data['website']);
-        }
-        if (isset($data['customer_group'])) {
-            $this->_rootElement
-                ->find('#' . $rowPrefix . '_cust_group', Locator::SELECTOR_CSS, 'select')
-                ->setValue($data['customer_group']);
-        }
-        if (isset($data['quantity'])) {
-            $this->_rootElement->find('#' . $rowPrefix . '_qty')->setValue($data['quantity']);
-        }
-        if (isset($data['price'])) {
-            $this->_rootElement->find('#' . $rowPrefix . '_price')->setValue($data['price']);
-        }
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d98751f3928403d9ae0775a211ab46f93d74dd4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab;
+
+use Mtf\Client\Element;
+use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options;
+
+/**
+ * Class OptionField
+ * Form "Group prices" on the tab "Extended price"
+ */
+class OptionGroup extends Options
+{
+    /**
+     * 'Add Group Price' button selector
+     *
+     * @var string
+     */
+    protected $buttonFormLocator = "#group_prices_table tfoot button";
+
+    /**
+     * Fill the form 'Extended price'
+     *
+     * @param array $fields
+     * @param Element $element
+     * @return $this
+     */
+    public function fillOptions(array $fields, Element $element = null)
+    {
+        $this->_rootElement->find($this->buttonFormLocator)->click();
+        return parent::fillOptions($fields, $element);
+    }
+}
diff --git a/app/code/Magento/Persistent/view/frontend/remember_me_tooltip.phtml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.xml
similarity index 62%
rename from app/code/Magento/Persistent/view/frontend/remember_me_tooltip.phtml
rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.xml
index 8d8d5d5ffa584b4eef74e5529394b0f262d0dd01..a6577bd2c34748fccee3cc47c2e8fd1517cc1212 100644
--- a/app/code/Magento/Persistent/view/frontend/remember_me_tooltip.phtml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionGroup.xml
@@ -1,4 +1,5 @@
-<?php
+<?xml version="1.0" ?>
+<!--
 /**
  * Magento
  *
@@ -21,20 +22,19 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-?>
-<?php
-/**
- * "Remember Me" popup template (when click on "What's this?")
- *
- */
-/** @var $this \Magento\Framework\View\Element\Template */
-?>
-<script type="text/javascript">
-    (function($) {
-        $('#remember-me-box').mage("rememberMePopup", {
-            title: '<?php echo __('What is this?');?>',
-            close: '<?php echo __('Close');?>',
-            content: '<?php echo __('Check &quot;Remember Me&quot; to access your shopping cart on this computer when you are logged out')?>'
-        });
-    })(jQuery);
-</script>
+-->
+<mapping strict="0">
+    <fields>
+        <price>
+            <selector>[id$="_price"]</selector>
+        </price>
+        <website>
+            <selector>[id$="_website"]</selector>
+            <input>select</input>
+        </website>
+        <customer_group>
+            <selector>[id$="_cust_group"]</selector>
+            <input>select</input>
+        </customer_group>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.php
new file mode 100644
index 0000000000000000000000000000000000000000..f62941712b8a126acc23c4a906e1beb15d1efa05
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab;
+
+use Mtf\Client\Element;
+use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options;
+
+/**
+ * Class OptionTier
+ * Form 'Tier prices' on the 'Advanced Pricing' tab
+ */
+class OptionTier extends Options
+{
+    /**
+     * 'Add Tier' button selector
+     *
+     * @var string
+     */
+    protected $buttonFormLocator = "#tiers_table tfoot button";
+
+    /**
+     * Fill product form 'Tier price'
+     *
+     * @param array $fields
+     * @param Element $element
+     * @return $this
+     */
+    public function fillOptions(array $fields, Element $element = null)
+    {
+        $this->_rootElement->find($this->buttonFormLocator)->click();
+        return parent::fillOptions($fields, $element);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.xml
new file mode 100644
index 0000000000000000000000000000000000000000..69c25f9a7c1d96e6c0e3eec0b65e6b68bfede2f4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/OptionTier.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <price>
+            <selector>[id$="_price"]</selector>
+        </price>
+        <website>
+            <selector>[id$="_website"]</selector>
+            <input>select</input>
+        </website>
+        <customer_group>
+            <selector>[id$="_cust_group"]</selector>
+            <input>select</input>
+        </customer_group>
+        <price_qty>
+            <selector>[id$="_qty"]</selector>
+        </price_qty>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/TierOption.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/TierOption.php
deleted file mode 100644
index b57b6e2fdbef4341efb7cd0d9b21085bd18d1ca9..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/TierOption.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab;
-
-use Mtf\Client\Element;
-use Mtf\Client\Element\Locator;
-use Mtf\Block\Block;
-
-/**
- * Select Type
- */
-class TierOption extends Block
-{
-    /**
-     * Fill
-     *
-     * @param string $rowPrefix
-     * @param array $data
-     */
-    public function fill($rowPrefix, $data)
-    {
-        if (isset($data['website'])) {
-            $this->_rootElement
-                ->find('#' . $rowPrefix . '_website', Locator::SELECTOR_CSS, 'select')
-                ->setValue($data['website']);
-        }
-        if (isset($data['customer_group'])) {
-            $this->_rootElement
-                ->find('#' . $rowPrefix . '_cust_group', Locator::SELECTOR_CSS, 'select')
-                ->setValue($data['customer_group']);
-        }
-        if (isset($data['price'])) {
-            $this->_rootElement->find('#' . $rowPrefix . '_price')->setValue($data['price']);
-        }
-        if (isset($data['quantity'])) {
-            $this->_rootElement->find('#' . $rowPrefix . '_qty')->setValue($data['quantity']);
-        }
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab.php
index 442339d6cd69cfd2c6956059e64b8d27e9e10f64..7de6ebe8edd278708f95d8eb065a6df9e7b60e87 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab.php
@@ -24,49 +24,138 @@
 
 namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit;
 
+use Mtf\ObjectManager;
 use Mtf\Client\Element;
 use Magento\Backend\Test\Block\Widget\Tab;
-use Mtf\Factory\Factory;
 
 /**
- * Custom Options Tab
- *
+ * Class CustomOptionsTab
+ * Product custom options tab
  */
 class CustomOptionsTab extends Tab
 {
     /**
-     * Fill custom options
+     * Custom option row CSS locator
+     *
+     * @var string
+     */
+    protected $customOptionRow = '#product-custom-options-content .fieldset-wrapper:nth-child(%d)';
+
+    /**
+     * Class name 'Subform' of the main tab form
+     *
+     * @var array
+     */
+    protected $childrenForm = [
+        'Field' => 'CustomOptionsTab\OptionField',
+        'Drop-down' => 'CustomOptionsTab\OptionDropDown'
+    ];
+
+    /**
+     * Add an option button
+     *
+     * @var string
+     */
+    protected $buttonFormLocator = '[data-ui-id="admin-product-options-add-button"]';
+
+    /**
+     * Fill custom options form on tab
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
-    public function fillFormTab(array $fields, Element $element)
+    public function fillFormTab(array $fields, Element $element = null)
     {
-        if (!isset($fields['custom_options'])) {
+        $fields = reset($fields);
+        if (empty($fields['value'])) {
             return $this;
         }
-        $root = $element;
-        $this->_rootElement->waitUntil(
-            function () use ($root) {
-                return $root->find('#Custom_Options')->isVisible();
+
+        foreach ($fields['value'] as $keyRoot => $field) {
+            $options = null;
+            $this->_rootElement->find($this->buttonFormLocator)->click();
+            if (!empty($field['options'])) {
+                $options = $field['options'];
+                unset($field['options']);
             }
-        );
 
-        $button = $root->find('[data-ui-id="admin-product-options-add-button"]');
+            $rootElement = $this->_rootElement->find(sprintf($this->customOptionRow, $keyRoot + 1));
+            $data = $this->dataMapping($field);
+            $this->_fill($data, $rootElement);
 
-        $container = $root->find('#product_options_container');
+            // Fill subform
+            if (isset($field['type']) && isset($this->childrenForm[$field['type']])
+                && !empty($options)
+            ) {
+                /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */
+                $optionsForm = $this->blockFactory->create(
+                    __NAMESPACE__ . '\\' . $this->childrenForm[$field['type']],
+                    ['element' => $rootElement]
+                );
 
-        if (isset($fields['custom_options']['value'])) {
-            foreach ($fields['custom_options']['value'] as $index => $data) {
-                $button->click();
-                $row = $container->find('.fieldset-wrapper:nth-child(' . ($index + 1) . ')');
-                Factory::getBlockFactory()
-                    ->getMagentoCatalogAdminhtmlProductEditCustomOptionsTabOption($row)
-                    ->fill($data);
+                foreach ($options as $key => $option) {
+                    ++$key;
+                    $optionsForm->fillOptions(
+                        $option,
+                        $rootElement->find('.fieldset .data-table tbody tr:nth-child(' . $key . ')')
+                    );
+                }
             }
         }
 
         return $this;
     }
+
+    /**
+     * Get data of tab
+     *
+     * @param array|null $fields
+     * @param Element|null $element
+     * @return array
+     */
+    public function getDataFormTab($fields = null, Element $element = null)
+    {
+        $fields = reset($fields);
+        $formData = [];
+        if (empty($fields['value'])) {
+            return $formData;
+        }
+
+        foreach ($fields['value'] as $keyRoot => $field) {
+            $formDataItem = null;
+            $options = null;
+            if (!empty($field['options'])) {
+                $options = $field['options'];
+                unset($field['options']);
+            }
+
+            $rootLocator = sprintf($this->customOptionRow, $keyRoot + 1);
+            $rootElement = $this->_rootElement->find($rootLocator);
+            $this->waitForElementVisible($rootLocator);
+            $data = $this->dataMapping($field);
+            $formDataItem = $this->_getData($data, $rootElement);
+
+            // Data collection subform
+            if (isset($field['type']) && isset($this->childrenForm[$field['type']])
+                && !empty($options)
+            ) {
+                /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options $optionsForm */
+                $optionsForm = $this->blockFactory->create(
+                    __NAMESPACE__ . '\\' . $this->childrenForm[$field['type']],
+                    ['element' => $rootElement]
+                );
+
+                foreach ($options as $key => $option) {
+                    $formDataItem['options'][$key++] = $optionsForm->getDataOptions(
+                        $option,
+                        $rootElement->find('.fieldset .data-table tbody tr:nth-child(' . $key . ')')
+                    );
+                }
+            }
+            $formData[$fields['attribute_code']][$keyRoot] = $formDataItem;
+        }
+
+        return $formData;
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/Option.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/Option.php
deleted file mode 100644
index d84c296dc9b0d56cf95fa2f57554696683ae2e2f..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/Option.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab;
-
-use Mtf\Client\Element;
-use Mtf\Client\Element\Locator;
-use Mtf\Block\Block;
-use Mtf\Factory\Factory;
-
-/**
- * Select Type
- */
-class Option extends Block
-{
-    /**
-     * Create block of special type
-     *
-     * @param string $type
-     * @param Element $element
-     * @throws \InvalidArgumentException
-     * @return Block|\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab\TypeSelect
-     */
-    protected function factory($type, Element $element)
-    {
-        switch ($type) {
-            case 'Drop-down':
-                return Factory::getBlockFactory()
-                    ->getMagentoCatalogAdminhtmlProductEditCustomOptionsTabTypeSelect($element);
-                break;
-            default:
-                throw new \InvalidArgumentException('Option type is not set');
-        }
-    }
-
-    /**
-     * Fill
-     *
-     * @param array $data
-     */
-    public function fill($data)
-    {
-        $this->_rootElement->find('.fieldset-alt [name$="[title]"]')
-            ->setValue($data['title']);
-        $this->_rootElement->find('.fieldset-alt [name$="[type]"]', Locator::SELECTOR_CSS, 'select')
-            ->setValue($data['type']);
-
-        $addButton = $this->_rootElement->find('.add-select-row');
-        $table = $this->_rootElement->find('.data-table');
-        foreach ($data['options'] as $index => $value) {
-            $addButton->click();
-            $subRow = $table->find('tbody tr:nth-child(' . ($index + 1) . ')');
-            $this->factory($data['type'], $subRow)->fill($value);
-        }
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.php
new file mode 100644
index 0000000000000000000000000000000000000000..54a92ab01bd5cbd1e93207b6c244b22fd68dfbd2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab;
+
+use Mtf\Client\Element;
+use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options;
+
+/**
+ * Class OptionDropDown
+ * Form "Option dropdown" on tab product "Custom options"
+ */
+class OptionDropDown extends Options
+{
+    /**
+     * Add button css selector
+     *
+     * @var string
+     */
+    private $buttonAddLocator = '[id$="_add_select_row"]';
+
+    /**
+     * Fill the form
+     *
+     * @param array $fields
+     * @param Element $element
+     * @return $this
+     */
+    public function fillOptions(array $fields, Element $element = null)
+    {
+        $this->_rootElement->find($this->buttonAddLocator)->click();
+        return parent::fillOptions($fields, $element);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4dac6efd003d6b8f317418a7e16f3a8eafdec485
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionDropDown.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <title>
+            <selector>[id$="_title"]</selector>
+        </title>
+        <price>
+            <selector>[id$="_price"]</selector>
+        </price>
+        <price_type>
+            <selector>[id$="_price_type"]</selector>
+            <input>select</input>
+        </price_type>
+        <sku>
+            <selector>[name$='[sku]']</selector>
+        </sku>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/TypeSelect.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php
similarity index 64%
rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/TypeSelect.php
rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php
index 331c36ec283148b5d2e09214a58690d5dbbcfa4f..702715d0ba801fa0687c42e50e35ce14dae451f9 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/TypeSelect.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.php
@@ -21,23 +21,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab;
 
-use Mtf\Client\Element;
-use Mtf\Client\Element\Locator;
-use Mtf\Block\Block;
+use Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Options;
 
 /**
- * Select Type
+ * Class OptionField
+ * Form "Text field" on tab product "Custom options"
  */
-class TypeSelect extends Block
+class OptionField extends Options
 {
-    public function fill($data)
-    {
-        $this->_rootElement->find('[name$="[title]"]')->setValue($data['title']);
-        $this->_rootElement->find('[name$="[price]"]')->setValue($data['price']);
-        $this->_rootElement->find('[name$="[price_type]"]', Locator::SELECTOR_CSS, 'select')
-            ->setValue($data['price_type']);
-        $this->_rootElement->find('[name$="[sku]"]')->setValue($data['sku']);
-    }
+    // Parent behavior
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e5b42e7e52488ab41a91cd305821910f72738cbd
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/CustomOptionsTab/OptionField.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <price>
+            <selector>[id$='_price']</selector>
+        </price>
+        <price_type>
+            <selector>[id$='_price_type']</selector>
+            <input>select</input>
+        </price_type>
+        <sku>
+            <selector>[name$='[sku]']</selector>
+        </sku>
+        <max_characters>
+            <selector>[name$='[max_characters]']</selector>
+        </max_characters>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Options.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Options.php
new file mode 100644
index 0000000000000000000000000000000000000000..f24a3a59eaa026c8f4d9f6c7c995f73bedefa9c6
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Options.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit;
+
+use Mtf\Client\Element;
+use Magento\Backend\Test\Block\Widget\Tab;
+
+/**
+ * Abstract class Options
+ * Parent class for all forms of product options
+ */
+abstract class Options extends Tab
+{
+    /**
+     * Fills in the form of an array of input data
+     *
+     * @param array $fields
+     * @param Element $element
+     * @return $this
+     */
+    public function fillOptions(array $fields, Element $element = null)
+    {
+        $element = $element === null ? $this->_rootElement : $element;
+        $mapping = $this->dataMapping($fields);
+        $this->_fill($mapping, $element);
+        return $this;
+    }
+
+    /**
+     * Getting options data form on the product form
+     *
+     * @param array $fields
+     * @param Element $element
+     * @return $this
+     */
+    public function getDataOptions(array $fields = null, Element $element = null)
+    {
+        $element = $element === null ? $this->_rootElement : $element;
+        $mapping = $this->dataMapping($fields);
+        return $this->_getData($mapping, $element);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php
index 8343bd02ff7c61c44dfdc91805850c0537ca59bd..15519e22b001c69e51cb134b7a73994b3867d0cd 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php
@@ -41,7 +41,7 @@ class Crosssell extends Tab
      * Select cross-sells products
      *
      * @param array $products
-     * @param Element $context
+     * @param Element|null $context
      * @return $this
      */
     public function fillFormTab(array $products, Element $context = null)
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php
index 20495e32a27ebd518afc233b2aaec47129967eb5..93f5243e9b632122004599f8909eb9351fe40875 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php
@@ -41,7 +41,7 @@ class Related extends Tab
      * Select related products
      *
      * @param array $products
-     * @param Element $context
+     * @param Element|null $context
      * @return $this
      */
     public function fillFormTab(array $products, Element $context = null)
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
index 1adca6b97826a73f76ae7185cc1c69f53e9f3cd8..592ed95817c33e8f4f77f9d8955dbb5f11f47de6 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
@@ -61,7 +61,7 @@ class Config extends Tab
      *
      * @var string
      */
-    protected $loader = '[data-role=loader]';
+    protected $loader = './ancestor::body//*[contains(@data-role,"loader")]';
 
     /**
      * Attribute Opened
@@ -116,7 +116,7 @@ class Config extends Tab
         $loaderSelector = $this->loader;
         $browser->waitUntil(
             function () use ($browser, $loaderSelector) {
-                $loaderElement = $browser->find($loaderSelector);
+                $loaderElement = $browser->find($loaderSelector, Locator::SELECTOR_XPATH);
                 return $loaderElement->isVisible() == false ? true : null;
             }
         );
@@ -126,10 +126,10 @@ class Config extends Tab
      * Fill variations fieldset
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
-    public function fillFormTab(array $fields, Element $element)
+    public function fillFormTab(array $fields, Element $element = null)
     {
         if (!isset($fields['configurable_attributes_data'])) {
             return $this;
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php
index e55cd06a9613bbf0893546cb3c44003498bb148c..752d50ecb197795479feee504927f96ffeadf016 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php
@@ -41,7 +41,7 @@ class Upsell extends Tab
      * Select up-sell products
      *
      * @param array $products
-     * @param Element $context
+     * @param Element|null $context
      * @return $this
      */
     public function fillFormTab(array $products, Element $context = null)
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..a600e6af39c314db769280750e77831e3980282a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.php
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product;
+
+use Mtf\Client\Element;
+use Mtf\Factory\Factory;
+use Mtf\Client\Element\Locator;
+use Mtf\Fixture\FixtureInterface;
+use Magento\Catalog\Test\Fixture\Product;
+use Magento\Catalog\Test\Fixture\Category;
+use Magento\Backend\Test\Block\Widget\Tab;
+use Magento\Backend\Test\Block\Widget\FormTabs;
+use Magento\Catalog\Test\Fixture\ConfigurableProduct;
+
+/**
+ * Class ProductForm
+ * Product form on backend product page
+ */
+class Form extends FormTabs
+{
+    /**
+     * Variations tab selector
+     *
+     * @var string
+     */
+    protected $variationsTab = '[data-ui-id="product-tabs-tab-content-super-config"] .title';
+
+    /**
+     * Variations wrapper selector
+     *
+     * @var string
+     */
+    protected $variationsWrapper = '[data-ui-id="product-tabs-tab-content-super-config"]';
+
+    /**
+     * New variation set button selector
+     *
+     * @var string
+     */
+    protected $newVariationSet = '[data-ui-id="admin-product-edit-tab-super-config-grid-container-add-attribute"]';
+
+    /**
+     * Category name selector
+     *
+     * @var string
+     */
+    protected $categoryName = '//*[contains(@class, "mage-suggest-choice")]/*[text()="%categoryName%"]';
+
+    /**
+     * 'Advanced Settings' tab
+     *
+     * @var string
+     */
+    protected $advancedSettings = '#ui-accordion-product_info_tabs-advanced-header-0[aria-selected="false"]';
+
+    /**
+     * Advanced tab list
+     *
+     * @var string
+     */
+    protected $advancedTabList = '#product_info_tabs-advanced[role="tablist"]';
+
+    /**
+     * Advanced tab panel
+     *
+     * @var string
+     */
+    protected $advancedTabPanel = '[role="tablist"] [role="tabpanel"][aria-expanded="true"]:not("overflow")';
+
+    /**
+     * Category fixture
+     *
+     * @var Category
+     */
+    protected $category;
+
+    /**
+     * Fill the product form
+     *
+     * @param FixtureInterface $fixture
+     * @param Category $category
+     * @param Element $element
+     * @return $this
+     */
+    public function fillProduct(FixtureInterface $fixture, Category $category = null, Element $element = null)
+    {
+        $this->category = $category;
+        $this->fillCategory($fixture);
+        return parent::fill($fixture, $element);
+    }
+
+    /**
+     * Fill product variations
+     *
+     * @param ConfigurableProduct $variations
+     * @return void
+     */
+    public function fillVariations(ConfigurableProduct $variations)
+    {
+        $variationsBlock = Factory::getBlockFactory()->getMagentoCatalogAdminhtmlProductEditTabSuperConfig(
+            $this->_rootElement->find($this->variationsWrapper)
+        );
+        $variationsBlock->fillAttributeOptions($variations->getConfigurableAttributes());
+        $variationsBlock->generateVariations();
+        $variationsBlock->fillVariationsMatrix($variations->getVariationsMatrix());
+    }
+
+    /**
+     * Select category
+     *
+     * @param FixtureInterface $fixture
+     * @return void|null
+     */
+    protected function fillCategory(FixtureInterface $fixture)
+    {
+        // TODO should be removed after suggest widget implementation as typified element
+        $categoryName = $this->category
+            ? $this->category->getCategoryName()
+            : ($fixture->getCategoryName() ? $fixture->getCategoryName() : '');
+
+        if (!$categoryName) {
+            return;
+        }
+        $category = $this->_rootElement->find(
+            str_replace(
+                '%categoryName%',
+                $categoryName,
+                $this->categoryName
+            ),
+            Locator::SELECTOR_XPATH
+        );
+        if (!$category->isVisible()) {
+            $this->fillCategoryField(
+                $categoryName,
+                'category_ids-suggest',
+                '//*[@id="attribute-category_ids-container"]'
+            );
+        }
+    }
+
+    /**
+     * Fills select category field
+     *
+     * @param string $name
+     * @param string $elementId
+     * @param string $parentLocation
+     * @return void
+     */
+    protected function fillCategoryField($name, $elementId, $parentLocation)
+    {
+        // TODO should be removed after suggest widget implementation as typified element
+        $this->_rootElement->find($elementId, Locator::SELECTOR_ID)->setValue($name);
+        $this->waitForElementVisible(
+            $parentLocation . '//div[@class="mage-suggest-dropdown"]',
+            Locator::SELECTOR_XPATH
+        );
+        $this->_rootElement->find(
+            $parentLocation . '//li[contains(@data-suggest-option, \'"label":"' . $name . '",\')]//a',
+            Locator::SELECTOR_XPATH
+        )->click();
+    }
+
+    /**
+     * Save new category
+     *
+     * @param Product $fixture
+     * @return void
+     */
+    public function addNewCategory(Product $fixture)
+    {
+        $this->openNewCategoryDialog();
+        $this->_rootElement->find('input#new_category_name', Locator::SELECTOR_CSS)
+            ->setValue($fixture->getNewCategoryName());
+
+        $this->clearCategorySelect();
+        $this->selectParentCategory();
+
+        $this->_rootElement->find('div.ui-dialog-buttonset button.action-create')->click();
+        $this->waitForElementNotVisible('div.ui-dialog-buttonset button.action-create');
+    }
+
+    /**
+     * Select parent category for new one
+     *
+     * @return void
+     */
+    protected function selectParentCategory()
+    {
+        // TODO should be removed after suggest widget implementation as typified element
+        $this->fillCategoryField(
+            'Default Category',
+            'new_category_parent-suggest',
+            '//*[@id="new_category_form_fieldset"]'
+        );
+    }
+
+    /**
+     * Clear category field
+     *
+     * @return void
+     */
+    public function clearCategorySelect()
+    {
+        $selectedCategory = 'li.mage-suggest-choice span.mage-suggest-choice-close';
+        if ($this->_rootElement->find($selectedCategory)->isVisible()) {
+            $this->_rootElement->find($selectedCategory)->click();
+        }
+    }
+
+    /**
+     * Open new category dialog
+     *
+     * @return void
+     */
+    protected function openNewCategoryDialog()
+    {
+        $this->_rootElement->find('#add_category_button', Locator::SELECTOR_CSS)->click();
+        $this->waitForElementVisible('input#new_category_name');
+    }
+
+    /**
+     * Open tab
+     *
+     * @param string $tabName
+     * @return Tab|bool
+     */
+    public function openTab($tabName)
+    {
+        $rootElement = $this->_rootElement;
+        $selector = $this->tabs[$tabName]['selector'];
+        $strategy = isset($this->tabs[$tabName]['strategy'])
+            ? $this->tabs[$tabName]['strategy']
+            : Locator::SELECTOR_CSS;
+        $advancedTabList = $this->advancedTabList;
+        $tab = $this->_rootElement->find($selector, $strategy);
+        $advancedSettings = $this->_rootElement->find($this->advancedSettings);
+
+        // Wait until all tabs will load
+        $this->_rootElement->waitUntil(
+            function () use ($rootElement, $advancedTabList) {
+                return $rootElement->find($advancedTabList)->isVisible();
+            }
+        );
+
+        if ($tab->isVisible()) {
+            $tab->click();
+        } elseif ($advancedSettings->isVisible()) {
+            $advancedSettings->click();
+            // Wait for open tab animation
+            $tabPanel = $this->advancedTabPanel;
+            $this->_rootElement->waitUntil(
+                function () use ($rootElement, $tabPanel) {
+                    return $rootElement->find($tabPanel)->isVisible();
+                }
+            );
+            // Wait until needed tab will appear
+            $this->_rootElement->waitUntil(
+                function () use ($rootElement, $selector, $strategy) {
+                    return $rootElement->find($selector, $strategy)->isVisible();
+                }
+            );
+            $tab->click();
+        } else {
+            return false;
+        }
+
+        return $this;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6e9319187ff4d099f37041f8660f88284c7d1ad0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Form.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<tabs>
+    <product-details>
+        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
+        <selector>#product_info_tabs_product-details</selector>
+        <strategy>css selector</strategy>
+        <wrapper>product</wrapper>
+        <fields>
+            <tax_class_id>
+                <input>select</input>
+            </tax_class_id>
+            <is_virtual>
+                <input>checkbox</input>
+            </is_virtual>
+            <qty>
+                <selector>[name='product[quantity_and_stock_status][qty]']</selector>
+            </qty>
+            <quantity_and_stock_status>
+                <selector>[name='product[quantity_and_stock_status][is_in_stock]']</selector>
+                <input>select</input>
+            </quantity_and_stock_status>
+            <description>
+                <selector>#description</selector>
+                <input>textarea</input>
+            </description>
+        </fields>
+    </product-details>
+    <websites>
+        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
+        <selector>#product_info_tabs_websites</selector>
+        <strategy>css selector</strategy>
+        <wrapper>product</wrapper>
+        <fields>
+            <product_website_1>
+                <selector>[name='product[website_ids][]']</selector>
+                <input>checkbox</input>
+            </product_website_1>
+        </fields>
+    </websites>
+    <advanced-pricing>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab</class>
+        <selector>#product_info_tabs_advanced-pricing</selector>
+        <strategy>css selector</strategy>
+        <wrapper>product</wrapper>
+        <fields>
+            <special_price>
+                <selector>#special_price</selector>
+            </special_price>
+        </fields>
+    </advanced-pricing>
+    <advanced-inventory>
+        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
+        <selector>#product_info_tabs_advanced-inventory</selector>
+        <strategy>css selector</strategy>
+        <wrapper>product[stock_data]</wrapper>
+        <fields>
+            <inventory_manage_stock>
+                <selector>[name='product[stock_data][manage_stock]']</selector>
+                <input>select</input>
+            </inventory_manage_stock>
+            <inventory_qty>
+                <selector>[name='product[stock_data][qty]']</selector>
+            </inventory_qty>
+        </fields>
+    </advanced-inventory>
+    <autosettings>
+        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
+        <selector>#product_info_tabs_autosettings</selector>
+        <strategy>css selector</strategy>
+        <wrapper>product</wrapper>
+        <fields>
+            <visibility>
+                <input>select</input>
+            </visibility>
+            <short_description>
+                <selector>#short_description</selector>
+                <input>textarea</input>
+            </short_description>
+        </fields>
+    </autosettings>
+    <variations>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Super\Config</class>
+        <selector>#product_info_tabs_product-details</selector>
+        <strategy>css selector</strategy>
+    </variations>
+    <grouped-product>
+        <class>\Magento\Catalog\Test\Block\Product\Grouped\AssociatedProducts</class>
+        <selector>#product_info_tabs_product-details</selector>
+        <strategy>css selector</strategy>
+    </grouped-product>
+    <customer-options>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\CustomOptionsTab</class>
+        <selector>#product_info_tabs_customer_options</selector>
+        <strategy>css selector</strategy>
+        <fields>
+            <title>
+                <selector>.field [id$='_title']</selector>
+                <strategy>css selector</strategy>
+            </title>
+            <is_require>
+                <selector>.field input[id$='_required']</selector>
+                <strategy>css selector</strategy>
+                <input>checkbox</input>
+            </is_require>
+            <type>
+                <selector>.field [id$='_type']</selector>
+                <strategy>css selector</strategy>
+                <input>select</input>
+            </type>
+        </fields>
+    </customer-options>
+    <related-products>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Related</class>
+        <selector>#product_info_tabs_related</selector>
+        <strategy>css selector</strategy>
+    </related-products>
+    <upsells>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Upsell</class>
+        <selector>#product_info_tabs_upsell</selector>
+        <strategy>css selector</strategy>
+    </upsells>
+    <crosssells>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Crosssell</class>
+        <selector>#product_info_tabs_crosssell</selector>
+        <strategy>css selector</strategy>
+    </crosssells>
+</tabs>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.php
new file mode 100644
index 0000000000000000000000000000000000000000..467ad465bc9552d906b53f9c4a98a8e5d0fe7126
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/FormPageActions.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product;
+
+use Mtf\Page\BackendPage;
+use Mtf\Fixture\FixtureInterface;
+use Magento\Backend\Test\Block\FormPageActions as ParentFormPageActions;
+
+/**
+ * Class FormAction
+ * Form action
+ */
+class FormPageActions extends ParentFormPageActions
+{
+    /**
+     * "Save" button
+     *
+     * @var string
+     */
+    protected $saveButton = '#save-split-button-button';
+
+    /**
+     * Save product form with window confirmation
+     *
+     * @param BackendPage $page
+     * @param FixtureInterface $product
+     * @return void
+     */
+    public function saveProduct(BackendPage $page, FixtureInterface $product)
+    {
+        parent::save();
+        /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\AffectedAttributeSetForm $affectedAttributeSetForm */
+        $affectedAttributeSetForm = $page->getAffectedAttributeSetForm();
+        $affectedAttributeSetForm->fill($product)->confirm();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..55376f2f69d1654f09e0bbf6cd39e2243ac86d83
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Grid.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Product;
+
+use Magento\Backend\Test\Block\Widget\Grid as ParentGrid;
+
+/**
+ * Class ProductGrid
+ * Backend catalog product grid
+ */
+class Grid extends ParentGrid
+{
+    /**
+     * Initialize block elements
+     */
+    protected $filters = array(
+        'name' => array(
+            'selector' => '#productGrid_product_filter_name'
+        ),
+        'sku' => array(
+            'selector' => '#productGrid_product_filter_sku'
+        ),
+        'type' => array(
+            'selector' => '#productGrid_product_filter_type',
+            'input' => 'select'
+        ),
+        'price_from' => array(
+            'selector' => '#productGrid_product_filter_price_from'
+        ),
+        'price_to' => array(
+            'selector' => '#productGrid_product_filter_price_to'
+        )
+    );
+
+    /**
+     * Update attributes for selected items
+     *
+     * @param array $items
+     * @return void
+     */
+    public function updateAttributes(array $items = array())
+    {
+        $this->massaction('Update Attributes', $items);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/Product/Attribute/Edit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/Product/Attribute/Edit.php
index 67b7178f6aceadaaa371ba78bfef80763f3d2ae0..bc56affda4c873bddefb2c61b499220ca442c581 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/Product/Attribute/Edit.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/Product/Attribute/Edit.php
@@ -82,7 +82,7 @@ class Edit extends Form
      * Fill form with attribute options
      *
      * @param FixtureInterface $fixture
-     * @param null|Element $element
+     * @param Element|null $element
      * @return $this
      */
     public function fill(FixtureInterface $fixture, Element $element = null)
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php
index 357df855f75330510dbd6bb86a7872b763c61880..4972a686f670c53e523e6ffe073f28a2474c5964 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Backend/ProductForm.php
@@ -37,7 +37,6 @@ use Magento\Catalog\Test\Fixture\ConfigurableProduct;
 /**
  * Class ProductForm
  * Product creation form
- *
  */
 class ProductForm extends FormTabs
 {
@@ -105,6 +104,15 @@ class ProductForm extends FormTabs
     protected $advancedTabPanel = '[role="tablist"] [role="tabpanel"][aria-expanded="true"]:not("overflow")';
 
     /**
+     * Selector popups 'New category'
+     *
+     * @var string
+     */
+    protected $newCategoryPopup = "./ancestor::body//div[div[contains(@id,'new-category')]]";
+
+    /**
+     * Category fixture
+     *
      * @var Category
      */
     protected $category;
@@ -122,7 +130,10 @@ class ProductForm extends FormTabs
     }
 
     /**
+     * Set category
+     *
      * @param Category $category
+     * @return void
      */
     public function setCategory(Category $category)
     {
@@ -189,18 +200,22 @@ class ProductForm extends FormTabs
      * Save new category
      *
      * @param Product $fixture
+     * @return void
      */
     public function addNewCategory(Product $fixture)
     {
         $this->openNewCategoryDialog();
-        $this->_rootElement->find('input#new_category_name', Locator::SELECTOR_CSS)
-            ->setValue($fixture->getNewCategoryName());
-
-        $this->clearCategorySelect();
-        $this->selectParentCategory();
+        $popupElement =  $this->_rootElement->find($this->newCategoryPopup, Locator::SELECTOR_XPATH);
+
+        if ($popupElement->isVisible()) {
+            $popupElement->find('input#new_category_name', Locator::SELECTOR_CSS)
+                ->setValue($fixture->getNewCategoryName());
+            $this->clearCategorySelect($popupElement);
+            $this->selectParentCategory($popupElement);
+            $popupElement->find('div.ui-dialog-buttonset button.action-create')->click();
+            $this->waitForElementNotVisible('div.ui-dialog-buttonset button.action-create');
+        }
 
-        $this->_rootElement->find('div.ui-dialog-buttonset button.action-create')->click();
-        $this->waitForElementNotVisible('div.ui-dialog-buttonset button.action-create');
     }
 
     /**
@@ -219,6 +234,7 @@ class ProductForm extends FormTabs
      * Fill product variations
      *
      * @param ConfigurableProduct $variations
+     * @return void
      */
     public function fillVariations(ConfigurableProduct $variations)
     {
@@ -230,6 +246,8 @@ class ProductForm extends FormTabs
 
     /**
      * Open variations tab
+     *
+     * @return void
      */
     public function openVariationsTab()
     {
@@ -238,6 +256,8 @@ class ProductForm extends FormTabs
 
     /**
      * Click on 'Create New Variation Set' button
+     *
+     * @return void
      */
     public function clickCreateNewVariationSet()
     {
@@ -246,25 +266,34 @@ class ProductForm extends FormTabs
 
     /**
      * Clear category field
+     *
+     * @param Element $element
+     * @return void
      */
-    public function clearCategorySelect()
+    public function clearCategorySelect(Element $element = null)
     {
+        $element = $element === null ? $this->_rootElement : $element;
         $selectedCategory = 'li.mage-suggest-choice span.mage-suggest-choice-close';
-        if ($this->_rootElement->find($selectedCategory)->isVisible()) {
-            $this->_rootElement->find($selectedCategory)->click();
+        if ($element->find($selectedCategory)->isVisible()) {
+            $element->find($selectedCategory)->click();
         }
     }
 
     /**
      * Select parent category for new one
+     *
+     * @param Element $element
+     * @return void
      */
-    protected function selectParentCategory()
+    protected function selectParentCategory(Element $element = null)
     {
+        $element = $element === null ? $this->_rootElement : $element;
         // TODO should be removed after suggest widget implementation as typified element
         $this->fillCategoryField(
             'Default Category',
             'new_category_parent-suggest',
-            '//*[@id="new_category_form_fieldset"]'
+            '//*[@id="new_category_form_fieldset"]',
+            $element
         );
     }
 
@@ -274,25 +303,30 @@ class ProductForm extends FormTabs
      * @param string $name
      * @param string $elementId
      * @param string $parentLocation
+     * @param Element $element
+     * @return void
      */
-    protected function fillCategoryField($name, $elementId, $parentLocation)
+    protected function fillCategoryField($name, $elementId, $parentLocation, Element $element = null)
     {
+        $element = $element === null ? $this->_rootElement : $element;
         // TODO should be removed after suggest widget implementation as typified element
-        $this->_rootElement->find($elementId, Locator::SELECTOR_ID)->setValue($name);
+        $element->find($elementId, Locator::SELECTOR_ID)->setValue($name);
         //*[@id="attribute-category_ids-container"]  //*[@id="new_category_form_fieldset"]
         $categoryListLocation = $parentLocation . '//div[@class="mage-suggest-dropdown"]'; //
         $this->waitForElementVisible($categoryListLocation, Locator::SELECTOR_XPATH);
         $categoryLocation = $parentLocation . '//li[contains(@data-suggest-option, \'"label":"' . $name . '",\')]//a';
-        $this->_rootElement->find($categoryLocation, Locator::SELECTOR_XPATH)->click();
+        $element->find($categoryLocation, Locator::SELECTOR_XPATH)->click();
     }
 
     /**
      * Open new category dialog
+     *
+     * @return void
      */
     protected function openNewCategoryDialog()
     {
         $this->_rootElement->find('#add_category_button', Locator::SELECTOR_CSS)->click();
-        $this->waitForElementVisible('input#new_category_name');
+        $this->waitForElementVisible($this->newCategoryPopup, Locator::SELECTOR_XPATH);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts.php
index a178cc7e268312876f19c37f4bd5c1d7e47359c1..bc639021f2dc19319df63824adfc01a3752540f5 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts.php
@@ -26,11 +26,12 @@ namespace Magento\Catalog\Test\Block\Product\Grouped;
 
 use Mtf\Client\Element;
 use Mtf\Factory\Factory;
+use Mtf\Client\Element\Locator;
 use Magento\Backend\Test\Block\Widget\Tab;
 
 /**
  * Class AssociatedProducts
- *
+ * Associated products tab
  */
 class AssociatedProducts extends Tab
 {
@@ -42,11 +43,11 @@ class AssociatedProducts extends Tab
     protected $addNewOption = '#grouped-product-container>button';
 
     /**
-     * Associated products grid
+     * Associated products grid locator
      *
      * @var string
      */
-    protected $productSearchGrid = '[role=dialog][style*="display: block;"]';
+    protected $productSearchGrid = "./ancestor::body//div[div[contains(@data-role,'add-product-dialog')]]";
 
     /**
      * Associated products list block
@@ -58,15 +59,12 @@ class AssociatedProducts extends Tab
     /**
      * Get search grid
      *
-     * @param Element $context
      * @return AssociatedProducts\Search\Grid
      */
-    protected function getSearchGridBlock(Element $context = null)
+    protected function getSearchGridBlock()
     {
-        $element = $context ? : $this->_rootElement;
-
         return Factory::getBlockFactory()->getMagentoCatalogProductGroupedAssociatedProductsSearchGrid(
-            $element->find($this->productSearchGrid)
+            $this->_rootElement->find($this->productSearchGrid, Locator::SELECTOR_XPATH)
         );
     }
 
@@ -89,15 +87,15 @@ class AssociatedProducts extends Tab
      * Fill data to fields on tab
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
-    public function fillFormTab(array $fields, Element $element)
+    public function fillFormTab(array $fields, Element $element = null)
     {
         if (isset($fields['grouped_products'])) {
             foreach ($fields['grouped_products']['value'] as $groupedProduct) {
                 $element->find($this->addNewOption)->click();
-                $searchBlock = $this->getSearchGridBlock($element);
+                $searchBlock = $this->getSearchGridBlock();
                 $searchBlock->searchAndSelect($groupedProduct['search_data']);
                 $searchBlock->addProducts();
                 $this->getListAssociatedProductsBlock()->fillProductOptions($groupedProduct['data']);
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php
index fe576653619acdc5f70c54343480d98997771318..468309c831ae13a38294148d8fbb980df1dff815 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Grouped/AssociatedProducts/ListAssociatedProducts.php
@@ -32,11 +32,13 @@ use Mtf\Client\Element\Locator;
 
 /**
  * Class ListAssociatedProducts
- *
+ * List associated products on the page
  */
 class ListAssociatedProducts extends Block
 {
     /**
+     * Getting block products
+     *
      * @param string $productId
      * @param Element $context
      * @return ListAssociatedProducts\Product
@@ -54,6 +56,8 @@ class ListAssociatedProducts extends Block
     }
 
     /**
+     * Filling options products
+     *
      * @param array $data
      * @param Element $element
      */
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
index 1a6f7df7207af10869ca4f4d659be63c2a978616..838888f3db374dd4317da9f4190a11072de90f9c 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ListProduct.php
@@ -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.
  *
- * @spi
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Catalog\Test\Block\Product;
 
 use Mtf\Block\Block;
 use Mtf\Client\Element;
-use Mtf\Client\Element\Locator;
 use Mtf\Factory\Factory;
+use Mtf\Client\Element\Locator;
 
 /**
  * Class SearchResultsList
  * Product list
- *
  */
 class ListProduct extends Block
 {
@@ -78,6 +77,13 @@ class ListProduct extends Block
      */
     protected $oldPrice = ".old-price .price";
 
+    /**
+     * 'Add to Card' button
+     *
+     * @var string
+     */
+    protected $addToCard = "button.action.tocart";
+
     /**
      * This method returns the price box block for the named product.
      *
@@ -95,6 +101,7 @@ class ListProduct extends Block
      * Check if product with specified name is visible
      *
      * @param string $productName
+     *
      * @return bool
      */
     public function isProductVisible($productName)
@@ -126,6 +133,7 @@ class ListProduct extends Block
      * This method returns the element representing the product details for the named product.
      *
      * @param string $productName String containing the name of the product
+     *
      * @return Element
      */
     protected function getProductDetailsElement($productName)
@@ -140,6 +148,7 @@ class ListProduct extends Block
      * This method returns the element on the page associated with the product name.
      *
      * @param string $productName String containing the name of the product
+     *
      * @return Element
      */
     protected function getProductNameElement($productName)
@@ -155,6 +164,10 @@ class ListProduct extends Block
 
     /**
      * Open MAP block on category page
+     *
+     * @param $productName
+     *
+     * @return void
      */
     public function openMapBlockOnCategoryPage($productName)
     {
@@ -175,6 +188,7 @@ class ListProduct extends Block
      * Retrieve product price by specified Id
      *
      * @param int $productId
+     *
      * @return string
      */
     public function getPrice($productId)
@@ -184,4 +198,14 @@ class ListProduct extends Block
             Locator::SELECTOR_CSS
         )->getText();
     }
+
+    /**
+     * Check 'Add To Card' button availability
+     *
+     * @return bool
+     */
+    public function checkAddToCardButton()
+    {
+        return $this->_rootElement->find($this->addToCard, Locator::SELECTOR_CSS)->isVisible();
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
index 0f16c3bdbe67314eebe5435b4091e80dd797921d..dbb3c7a717e6cd6b13a853ccd330ad5b1deea11a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/Price.php
@@ -29,9 +29,7 @@ use Mtf\Client\Element\Locator;
 
 /**
  * Class Price
- *
- * This class is used to access the price related information from the storefront.
- *
+ * This class is used to access the price related information from the storefront
  */
 class Price extends Block
 {
@@ -40,28 +38,28 @@ class Price extends Block
      *
      * @var string
      */
-    protected $oldPriceClass = 'old-price';
+    protected $oldPriceClass = '.old-price';
 
     /**
      * This member holds the class name of the price block that contains the actual price value.
      *
      * @var string
      */
-    protected $priceClass = 'price';
+    protected $priceClass = '.price';
 
     /**
      * This member holds the class name of the regular price block.
      *
      * @var string
      */
-    protected $regularPriceClass = "regular-price";
+    protected $regularPriceClass = '.price-final_price';
 
     /**
      * This member holds the class name of the special price block.
      *
      * @var string
      */
-    protected $specialPriceClass = 'special-price';
+    protected $specialPriceClass = '.special-price';
 
     /**
      * Minimum Advertised Price
@@ -106,31 +104,35 @@ class Price extends Block
     protected $priceToSelector = 'p.price-to span.price';
 
     /**
+     * Getting prices
+     *
      * @param string $currency
-     * @return string|array
+     * @return array
      */
     public function getPrice($currency = '$')
     {
         //@TODO it have to rewrite when will be possibility to divide it to different blocks(by product type)
         $prices = explode("\n", trim($this->_rootElement->getText()));
-        if (count($prices) == 1) {
-            return floatval(trim($prices[0], $currency));
+        if (count($prices) === 1) {
+            return ['price_regular_price' => trim($prices[0], $currency)];
         }
         return $this->formatPricesData($prices, $currency);
     }
 
     /**
+     * Formatting data prices
+     *
      * @param array $prices
      * @param string $currency
      * @return array
      */
     private function formatPricesData(array $prices, $currency = '$')
     {
-        $formatted = array();
+        $formatted = [];
         foreach ($prices as $price) {
             list($name, $price) = explode($currency, $price);
-            $name = trim(preg_replace('#[^0-9a-z]+#i', ' ', strtolower($name)), ' ');
-            $formatted['price_' . $name] = floatval($price);
+            $name = str_replace(' ', '_', trim(preg_replace('#[^0-9a-z]+#i', ' ', strtolower($name)), ' '));
+            $formatted['price_' . $name] = $price;
         }
         return $formatted;
     }
@@ -145,15 +147,15 @@ class Price extends Block
     public function getEffectivePrice()
     {
         // if a special price is available, then return that
-        $priceElement = $this->_rootElement->find($this->specialPriceClass, Locator::SELECTOR_CLASS_NAME);
+        $priceElement = $this->_rootElement->find($this->specialPriceClass, Locator::SELECTOR_CSS);
         if (!$priceElement->isVisible()) {
-            $priceElement = $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CLASS_NAME);
+            $priceElement = $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CSS);
             if (!$priceElement->isVisible()) {
-                $priceElement = $this->_rootElement->find($this->oldPriceClass, Locator::SELECTOR_CLASS_NAME);
+                $priceElement = $this->_rootElement->find($this->oldPriceClass, Locator::SELECTOR_CSS);
             }
         }
         // return the actual value of the price
-        return $priceElement->find($this->priceClass, Locator::SELECTOR_CLASS_NAME)->getText();
+        return $priceElement->find($this->priceClass, Locator::SELECTOR_CSS)->getText();
     }
 
     /**
@@ -164,12 +166,12 @@ class Price extends Block
     public function getRegularPrice()
     {
         // either return the old price (implies special price display or a regular price
-        $priceElement = $this->_rootElement->find($this->oldPriceClass, Locator::SELECTOR_CLASS_NAME);
+        $priceElement = $this->_rootElement->find($this->oldPriceClass, Locator::SELECTOR_CSS);
         if (!$priceElement->isVisible()) {
-            $priceElement = $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CLASS_NAME);
+            $priceElement = $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CSS);
         }
         // return the actual value of the price
-        return $priceElement->find($this->priceClass, Locator::SELECTOR_CLASS_NAME)->getText();
+        return $priceElement->find($this->priceClass, Locator::SELECTOR_CSS)->getText();
     }
 
     /**
@@ -181,10 +183,10 @@ class Price extends Block
     {
         return $this->_rootElement->find(
             $this->specialPriceClass,
-            Locator::SELECTOR_CLASS_NAME
+            Locator::SELECTOR_CSS
         )->find(
             $this->priceClass,
-            Locator::SELECTOR_CLASS_NAME
+            Locator::SELECTOR_CSS
         )->getText();
     }
 
@@ -195,7 +197,7 @@ class Price extends Block
      */
     public function isRegularPriceVisible()
     {
-        return $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CLASS_NAME)->isVisible();
+        return $this->_rootElement->find($this->regularPriceClass, Locator::SELECTOR_CSS)->isVisible();
     }
 
     /**
@@ -205,13 +207,13 @@ class Price extends Block
      */
     public function isSpecialPriceVisible()
     {
-        return $this->_rootElement->find($this->specialPriceClass, Locator::SELECTOR_CLASS_NAME)->isVisible();
+        return $this->_rootElement->find($this->specialPriceClass, Locator::SELECTOR_CSS)->isVisible();
     }
 
     /**
      * Get Minimum Advertised Price value
      *
-     * @return array|string
+     * @return string
      */
     public function getOldPrice()
     {
@@ -229,7 +231,7 @@ class Price extends Block
     {
         //@TODO it have to rewrite when will be possibility to divide it to different blocks(by product type)
         $prices = explode("\n", trim($this->_rootElement->find($this->actualPrice, Locator::SELECTOR_CSS)->getText()));
-        if (count($prices) == 1) {
+        if (count($prices) === 1) {
             return floatval(trim($prices[0], $currency));
         }
         return $this->formatPricesData($prices, $currency);
@@ -238,6 +240,7 @@ class Price extends Block
     /**
      * Add product to shopping cart from MAP Block
      *
+     * @return void
      */
     public function addToCartFromMap()
     {
@@ -247,6 +250,7 @@ class Price extends Block
     /**
      * Close MAP Block
      *
+     * @return void
      */
     public function closeMapBlock()
     {
@@ -256,7 +260,7 @@ class Price extends Block
     /**
      * Get price from
      *
-     * @return array|string
+     * @return string
      */
     public function getPriceFrom()
     {
@@ -266,7 +270,7 @@ class Price extends Block
     /**
      * Get price to
      *
-     * @return array|string
+     * @return string
      */
     public function getPriceTo()
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Crosssell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Crosssell.php
index 0061e16d5e529637f2532393b0049b5c736179b0..3793f42964185626217b5e8b49c74b069b19780a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Crosssell.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Crosssell.php
@@ -22,14 +22,17 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-
 namespace Magento\Catalog\Test\Block\Product\ProductList;
 
-use Magento\Catalog\Test\Fixture\AbstractProduct;
 use Mtf\Block\Block;
+use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
 use \Magento\Catalog\Test\Fixture\Product;
 
+/**
+ * Class Crosssell
+ * Crosssell product block on the page
+ */
 class Crosssell extends Block
 {
     /**
@@ -58,8 +61,7 @@ class Crosssell extends Block
      * Click on cross-sell product link
      *
      * @param Product $product
-     * @return \Mtf\Client\Element
-     * @throws \Exception
+     * @return Element
      */
     public function clickLink($product)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Related.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Related.php
index 05f50a5123f4ab40359b12c240e4a0b4b724e585..1e24159100246347b04befbd9ecfcf16b23856d0 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Related.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Related.php
@@ -18,7 +18,6 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @spi
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
@@ -26,14 +25,25 @@
 namespace Magento\Catalog\Test\Block\Product\ProductList;
 
 use Mtf\Block\Block;
-use Mtf\Factory\Factory;
+use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
 
+/**
+ * Class Related
+ * Related product block on the page
+ */
 class Related extends Block
 {
+    /**
+     * Related product locator on the page
+     *
+     * @var string
+     */
     protected $relatedProduct = "//div[normalize-space(div//a)='%s']";
 
     /**
+     * Checking related product visibility
+     *
      * @param string $productName
      * @return bool
      */
@@ -43,6 +53,8 @@ class Related extends Block
     }
 
     /**
+     * Verify that you can choose the related products
+     *
      * @param string $productName
      * @return bool
      */
@@ -52,7 +64,10 @@ class Related extends Block
     }
 
     /**
+     * Open related product
+     *
      * @param string $productName
+     * @return void
      */
     public function openRelatedProduct($productName)
     {
@@ -60,7 +75,10 @@ class Related extends Block
     }
 
     /**
+     * Select related product
+     *
      * @param string $productName
+     * @return void
      */
     public function selectProductForAddToCart($productName)
     {
@@ -70,8 +88,10 @@ class Related extends Block
     }
 
     /**
+     * Get related product element
+     *
      * @param string $productName
-     * @return mixed|\Mtf\Client\Element
+     * @return Element
      */
     private function getProductElement($productName)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Toolbar.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Toolbar.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1e7ce1b27a75707187ab0ad10a08ee988bea454
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Toolbar.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Product\ProductList;
+
+use Mtf\Block\Block;
+
+/**
+ * Class ProductPagination
+ * Toolbar the product list page
+ */
+class Toolbar extends Block
+{
+    /**
+     * Selector next active element
+     *
+     * @var string
+     */
+    protected $nextPageSelector = '.item.current + .item a';
+
+    /**
+     * Go to the next page
+     *
+     * @return bool
+     */
+    public function nextPage()
+    {
+        $nextPageItem = $this->_rootElement->find($this->nextPageSelector);
+        if ($nextPageItem->isVisible()) {
+            $nextPageItem->click();
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Upsell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Upsell.php
index 2bfa88f9a59533b302e6d5a1924ea803b7361bdc..ebe98223223b3adf0ab198f9a6657fe702cb08b3 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Upsell.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/ProductList/Upsell.php
@@ -25,14 +25,25 @@
 namespace Magento\Catalog\Test\Block\Product\ProductList;
 
 use Mtf\Block\Block;
-use Mtf\Factory\Factory;
+use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
 
+/**
+ * Class Upsell
+ * Upsell product block on the page
+ */
 class Upsell extends Block
 {
+    /**
+     * Upsell product locator on the page
+     *
+     * @var string
+     */
     protected $upsellProduct = "//div[normalize-space(div//a)='%s']";
 
     /**
+     * Checking upsell product visibility
+     *
      * @param string $productName
      * @return bool
      */
@@ -42,6 +53,8 @@ class Upsell extends Block
     }
 
     /**
+     * Open upsell product
+     *
      * @param string $productName
      */
     public function openUpsellProduct($productName)
@@ -50,8 +63,10 @@ class Upsell extends Block
     }
 
     /**
+     * Get a the product
+     *
      * @param string $productName
-     * @return mixed|\Mtf\Client\Element
+     * @return Element
      */
     private function getProductElement($productName)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
index 3bec840a1ade299af03a116b10605458b0efd4a4..2eceac5d6d0ebad32346d74cf46a242a413dbe94 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View.php
@@ -21,21 +21,19 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Catalog\Test\Block\Product;
 
 use Mtf\Block\Block;
 use Mtf\Factory\Factory;
 use Mtf\Client\Element\Locator;
-use Magento\Catalog\Test\Fixture\Product;
-use Magento\Catalog\Test\Fixture\ConfigurableProduct;
-use Magento\Catalog\Test\Fixture\GroupedProduct;
-use Magento\Bundle\Test\Fixture\Bundle as BundleFixture;
 use Mtf\Fixture\FixtureInterface;
+use Magento\Catalog\Test\Fixture\GroupedProduct;
+use Magento\Catalog\Test\Fixture\ConfigurableProduct;
 
 /**
  * Class View
- * Product View block
- *
+ * Product view block on the product page
  */
 class View extends Block
 {
@@ -67,6 +65,27 @@ class View extends Block
      */
     protected $productName = '.page.title.product span';
 
+    /**
+     * Product sku element
+     *
+     * @var string
+     */
+    protected $productSku = '[itemprop="sku"]';
+
+    /**
+     * Product description element
+     *
+     * @var string
+     */
+    protected $productDescription = '.product.attibute.description';
+
+    /**
+     * Product short-description element
+     *
+     * @var string
+     */
+    protected $productShortDescription = '.product.attibute.overview';
+
     /**
      * Product price element
      *
@@ -109,6 +128,13 @@ class View extends Block
      */
     protected $customizeButton = '.action.primary.customize';
 
+    /**
+     * This member holds the class name of the tier price block.
+     *
+     * @var string
+     */
+    protected $tierPricesSelector = "//ul[contains(@class,'tier')]//*[@class='item'][%line-number%]";
+
     /**
      * Get bundle options block
      *
@@ -122,6 +148,8 @@ class View extends Block
     }
 
     /**
+     * Get block price
+     *
      * @return \Magento\Catalog\Test\Block\Product\Price
      */
     protected function getPriceBlock()
@@ -135,6 +163,7 @@ class View extends Block
      * Add product to shopping cart
      *
      * @param FixtureInterface $product
+     * @return void
      */
     public function addToCart(FixtureInterface $product)
     {
@@ -142,16 +171,40 @@ class View extends Block
         $this->clickAddToCart();
     }
 
+    /**
+     * Find button 'Add to cart'
+     *
+     * @return boolean
+     */
+    public function addToCartIsVisible()
+    {
+        return $this->_rootElement->find($this->addToCart, Locator::SELECTOR_CSS)->isVisible();
+    }
+
     /**
      * Click link
+     *
+     * @return void
      */
     public function clickAddToCart()
     {
         $this->_rootElement->find($this->addToCart, Locator::SELECTOR_CSS)->click();
     }
 
+    /**
+     * Find Add To Cart button
+     *
+     * @return bool
+     */
+    public function isVisibleAddToCart()
+    {
+        return $this->_rootElement->find($this->addToCart, Locator::SELECTOR_CSS)->isVisible();
+    }
+
     /**
      * Press 'Check out with PayPal' button
+     *
+     * @return void
      */
     public function paypalCheckout()
     {
@@ -168,6 +221,16 @@ class View extends Block
         return $this->_rootElement->find($this->productName, Locator::SELECTOR_CSS)->getText();
     }
 
+    /**
+     * Get product sku displayed on page
+     *
+     * @return string
+     */
+    public function getProductSku()
+    {
+        return $this->_rootElement->find($this->productSku, Locator::SELECTOR_CSS)->getText();
+    }
+
     /**
      * This method returns the price box block.
      *
@@ -190,6 +253,32 @@ class View extends Block
         return $this->getPriceBlock()->getPrice();
     }
 
+    /**
+     * Return product short description on page
+     *
+     * @return string|null
+     */
+    public function getProductShortDescription()
+    {
+        if ($this->_rootElement->find($this->productShortDescription, Locator::SELECTOR_CSS)->isVisible()) {
+            return $this->_rootElement->find($this->productShortDescription, Locator::SELECTOR_CSS)->getText();
+        }
+        return null;
+    }
+
+    /**
+     * Return product description on page
+     *
+     * @return string|null
+     */
+    public function getProductDescription()
+    {
+        if ($this->_rootElement->find($this->productDescription, Locator::SELECTOR_CSS)->isVisible()) {
+            return $this->_rootElement->find($this->productDescription, Locator::SELECTOR_CSS)->getText();
+        }
+        return null;
+    }
+
     /**
      * Return configurable product options
      *
@@ -234,9 +323,10 @@ class View extends Block
     /**
      * Fill in the option specified for the product
      *
-     * @param BundleFixture|Product $product
+     * @param FixtureInterface $product
+     * @return void
      */
-    public function fillOptions($product)
+    public function fillOptions(FixtureInterface $product)
     {
         $configureButton = $this->_rootElement->find($this->customizeButton);
         $configureSection = $this->_rootElement->find('.product.options.wrapper');
@@ -252,8 +342,24 @@ class View extends Block
         }
     }
 
+    /**
+     * This method return array tier prices
+     *
+     * @param int $lineNumber
+     * @return array
+     */
+    public function getTierPrices($lineNumber = 1)
+    {
+        return $this->_rootElement->find(
+            str_replace('%line-number%', $lineNumber, $this->tierPricesSelector),
+            Locator::SELECTOR_XPATH
+        )->getText();
+    }
+
     /**
      * Click "Customize and add to cart button"
+     *
+     * @return void
      */
     public function clickCustomize()
     {
@@ -263,6 +369,8 @@ class View extends Block
 
     /**
      * Click "ADD TO CART" button
+     *
+     * @return void
      */
     public function clickAddToCartButton()
     {
@@ -270,6 +378,8 @@ class View extends Block
     }
 
     /**
+     * Verification of group products
+     *
      * @param GroupedProduct $product
      * @return bool
      */
@@ -289,6 +399,8 @@ class View extends Block
 
     /**
      * Open MAP block on Product View page
+     *
+     * @return void
      */
     public function openMapBlockOnProductPage()
     {
@@ -297,11 +409,11 @@ class View extends Block
     }
 
     /**
-     * Is 'ADD TO CART' button visible
+     * Check 'Add to card' button visible
      *
      * @return bool
      */
-    public function isAddToCartButtonVisible()
+    public function checkAddToCardButton()
     {
         return $this->_rootElement->find($this->addToCart, Locator::SELECTOR_CSS)->isVisible();
     }
@@ -309,7 +421,7 @@ class View extends Block
     /**
      * Get text of Stock Availability control
      *
-     * @return array|string
+     * @return string
      */
     public function stockAvailability()
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
index cdede23e765eed04ee27abcdda10103cf40ce854..958aa9fda7cd36a25726511467ff230e7f439baf 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
@@ -27,52 +27,182 @@ namespace Magento\Catalog\Test\Block\Product\View;
 use Mtf\Block\Block;
 use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
-use Mtf\Factory\Factory;
 
 /**
  * Class Custom Options
- *
+ * Block of custom options product
  */
 class CustomOptions extends Block
 {
-    protected $fieldsetSelector = '.fieldset';
-    protected $rowSelector = '.field';
+    /**
+     * Regexp price pattern
+     *
+     * @var string
+     */
+    protected $pricePattern = '#\$([\d,]+\.\d+)$#';
+
+    /**
+     * Field set XPath locator
+     *
+     * @var string
+     */
+    protected $fieldsetLocator = '//*[@id="product-options-wrapper"]//*[@class="fieldset"]';
+
+    /**
+     * Field XPath locator
+     *
+     * @var string
+     */
+    protected $fieldLocator = '/div[not(contains(@class,"downloads")) and contains(@class,"field")%s][%d]';
+
+    /**
+     * Required field XPath locator
+     *
+     * @var string
+     */
+    protected $requiredLocator = ' and contains(@class,"required")';
 
     /**
-     * Get options
+     * Select field XPath locator
+     *
+     * @var string
+     */
+    protected $selectLocator = '//div[contains(@class,"control")]//select';
+
+    /**
+     * Title value CSS locator
+     *
+     * @var string
+     */
+    protected $titleLocator = '.label span:not(.price-notice)';
+
+    /**
+     * Price value CSS locator
+     *
+     * @var string
+     */
+    protected $priceLocator = '.label .price-notice';
+
+    /**
+     * Option XPath locator
+     *
+     * @var string
+     */
+    protected $optionLocator = '//option[%d]';
+
+    /**
+     * Option XPath locator by value
+     *
+     * @var string
+     */
+    protected $optionByValueLocator = '//*[@class="product options wrapper"]//option[text()="%s"]/..';
+
+    /**
+     * Select XPath locator by title
+     *
+     * @var string
+     */
+    protected $selectByTitleLocator = '//*[*[@class="product options wrapper"]//span[text()="%s"]]//select';
+
+    /**
+     * Bundle field CSS locator
+     *
+     * @var string
+     */
+    protected $bundleFieldLocator = '#product-options-wrapper > .fieldset > .field';
+
+    /**
+     * Get product options
      *
      * @return array
      */
-    public function get()
+    public function getOptions()
     {
-        $optionsFieldset = $this->_rootElement->find($this->fieldsetSelector);
-        $fieldsetIndex = 1;
-        $options = array();
-        //@todo move to separate block
-        $field = $optionsFieldset->find($this->rowSelector . ':nth-of-type(' . $fieldsetIndex . ')');
-        while ($field->isVisible()) {
-            $optionFieldset = [];
-            $optionFieldset['title'] = $field->find('.label')->getText();
-            $optionFieldset['is_require'] = $field->find('select.required')->isVisible();
-            $options[] = & $optionFieldset;
-            $optionIndex = 1;
-            //@todo move to separate block
-            $option = $field->find('select > option:nth-of-type(' . $optionIndex . ')');
-            while ($option->isVisible()) {
-                if (preg_match('~^(?<title>.+) .?\$(?P<price>\d+\.\d*)$~', $option->getText(), $matches) !== false
-                    && !empty($matches['price'])
+        $options = [];
+        $index = 1;
+
+        $fieldElement = $this->_rootElement->find(
+            $this->fieldsetLocator . sprintf($this->fieldLocator, '', $index),
+            Locator::SELECTOR_XPATH
+        );
+
+        while ($fieldElement && $fieldElement->isVisible()) {
+            $option = ['price' => []];
+            $option['is_require'] = $this->_rootElement->find(
+                $this->fieldsetLocator . sprintf($this->fieldLocator, $this->requiredLocator, $index),
+                Locator::SELECTOR_XPATH
+            )->isVisible();
+            $option['title'] = $fieldElement->find($this->titleLocator)->getText();
+
+            if (($price = $fieldElement->find($this->priceLocator))
+                && $price->isVisible()
+            ) {
+                $matches = [];
+                $value = $price->getText();
+                if (preg_match($this->pricePattern, $value, $matches)) {
+                    $option['value'][] = $value;
+                    $option['price'][] = $matches[1];
+                }
+            } elseif (($prices = $fieldElement->find(
+                $this->selectLocator,
+                Locator::SELECTOR_XPATH
+            )
+                ) && $prices->isVisible()
+            ) {
+                $priceIndex = 0;
+                while (($price = $prices->find(sprintf($this->optionLocator, ++$priceIndex), Locator::SELECTOR_XPATH))
+                    && $price->isVisible()
                 ) {
-                    $optionFieldset['options'][] = [
-                        'title' => $matches['title'],
-                        'price' => $matches['price'],
-                    ];
-                };
-                $optionIndex++;
-                $option = $field->find('select > option:nth-of-type(' . $optionIndex . ')');
+                    $matches = [];
+                    $value = $price->getText();
+                    if (preg_match($this->pricePattern, $value, $matches)) {
+                        $option['value'][] = $value;
+                        $option['price'][] = $matches[1];
+                    }
+                }
             }
-            $fieldsetIndex++;
-            $field = $optionsFieldset->find($this->rowSelector . ':nth-of-type(' . $fieldsetIndex . ')');
+            $options[$option['title']] = $option;
+            ++$index;
+            $fieldElement = $this->_rootElement->find(
+                $this->fieldsetLocator . sprintf($this->fieldLocator, '', $index),
+                Locator::SELECTOR_XPATH
+            );
         }
+
         return $options;
     }
+
+    /**
+     * Fill configurable product options
+     *
+     * @param array $productOptions
+     * @return void
+     */
+    public function fillProductOptions($productOptions)
+    {
+        foreach ($productOptions as $attributeLabel => $attributeValue) {
+            $select = $this->_rootElement->find(
+                sprintf($this->selectByTitleLocator, $attributeLabel),
+                Locator::SELECTOR_XPATH,
+                'select'
+            );
+            $select->setValue($attributeValue);
+        }
+    }
+
+    /**
+     * Choose custom option in a drop down
+     *
+     * @param string $productOption
+     * @return void
+     */
+    public function selectProductCustomOption($productOption)
+    {
+        $select = $this->_rootElement->find(
+            sprintf($this->optionByValueLocator, $productOption),
+            Locator::SELECTOR_XPATH,
+            'select'
+        );
+        $select->setValue($productOption);
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/Options.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/Options.php
deleted file mode 100644
index aeaeea05b0ff3d80da11afe6fa0f021e9b1a4e33..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/Options.php
+++ /dev/null
@@ -1,128 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Catalog\Test\Block\Product\View;
-
-use Mtf\Block\Block;
-use Mtf\Client\Element;
-use Mtf\Client\Element\Locator;
-
-/**
- * Class Bundle
- * Catalog bundle product info block
- *
- */
-class Options extends Block
-{
-    /**
-     * Get product custom options
-     *
-     * @return array
-     */
-    public function getProductCustomOptions()
-    {
-        return $this->getOptions('.fieldset > .field');
-    }
-
-    /**
-     * Get bundle custom options
-     *
-     * @return array
-     */
-    public function getBundleCustomOptions()
-    {
-        return $this->getOptions('#product-options-wrapper > .fieldset > .field');
-    }
-
-    /**
-     * Get bundle options
-     *
-     * @return array
-     */
-    public function getBundleOptions()
-    {
-        return $this->getOptions('.fieldset.bundle.options > .field');
-    }
-
-    /**
-     * Get options from specified fieldset using specified fieldDiv selector
-     *
-     * @param string $fieldSelector
-     * @return array
-     */
-    protected function getOptions($fieldSelector = '.fieldset.bundle.options')
-    {
-        $index = 1;
-        $options = [];
-        $field = $this->_rootElement->find($fieldSelector . ':nth-of-type(' . $index . ')');
-        while ($field->isVisible()) {
-            $optionName = $field->find('label > span')->getText();
-            $options[$optionName] = [];
-            $productIndex = 1;
-            $productOption = $field->find('select > option:nth-of-type(' . $productIndex . ')');
-            while ($productOption->isVisible()) {
-                $options[$optionName][] = trim($productOption->getText());
-                $productIndex++;
-                $productOption = $field->find('select > option:nth-of-type(' . $productIndex . ')');
-            }
-            $index++;
-            $field = $this->_rootElement->find($fieldSelector . ':nth-of-type(' . $index . ')');
-        }
-        return $options;
-    }
-
-    /**
-     * Fill configurable product options
-     *
-     * @param array $productOptions
-     */
-    public function fillProductOptions($productOptions)
-    {
-        foreach ($productOptions as $attributeLabel => $attributeValue) {
-            $select = $this->_rootElement->find(
-                '//*[*[@class="product options wrapper"]//span[text()="' .
-                $attributeLabel .
-                '"]]//select',
-                Locator::SELECTOR_XPATH,
-                'select'
-            );
-            $select->setValue($attributeValue);
-        }
-    }
-
-    /**
-     * Choose custom option in a drop down
-     *
-     * @param string $productOption
-     */
-    public function selectProductCustomOption($productOption)
-    {
-        $select = $this->_rootElement->find(
-            '//*[@class="product options wrapper"]//option[text()="' . $productOption . '"]/..',
-            Locator::SELECTOR_XPATH,
-            'select'
-        );
-        $select->setValue($productOption);
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Search.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Search.php
index b1efb82c13063d0f64e273a71c83f256376b3ed7..24029a7351bbc0eb387bf3cd9ed69a3a6b20d781 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Search.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Search.php
@@ -30,7 +30,6 @@ use Mtf\Client\Element\Locator;
 /**
  * Class Search
  * Block for search field
- *
  */
 class Search extends Block
 {
@@ -59,6 +58,7 @@ class Search extends Block
      * Search products by a keyword
      *
      * @param string $keyword
+     * @return void
      */
     public function search($keyword)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3bd7ca03010665350546d4467ada588abecefa7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+
+/**
+ * Class AssertAddToCartButtonAbsent
+ * Checks the button on the category/product pages
+ */
+class AssertAddToCartButtonAbsent extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Category Page
+     *
+     * @var CatalogCategoryView
+     */
+    protected $catalogCategoryView;
+
+    /**
+     * Index Page
+     *
+     * @var CmsIndex
+     */
+    protected $cmsIndex;
+
+    /**
+     * Product simple fixture
+     *
+     * @var CatalogProductSimple
+     */
+    protected $catalogProductSimple;
+
+    /**
+     * Product Page on Frontend
+     *
+     * @var CatalogProductView
+     */
+    protected $catalogProductView;
+
+    /**
+     * Assert that "Add to cart" button is not display on page.
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CatalogCategoryView $catalogCategoryView
+     * @param CatalogProductSimple $catalogProductSimple
+     * @param CatalogProductView $catalogProductView
+     *
+     * @return void
+     */
+    public function processAssert(
+        CmsIndex $cmsIndex,
+        CatalogCategoryView $catalogCategoryView,
+        CatalogProductSimple $catalogProductSimple,
+        CatalogProductView $catalogProductView
+    ) {
+        $this->catalogCategoryView = $catalogCategoryView;
+        $this->cmsIndex = $cmsIndex;
+        $this->catalogProductSimple = $catalogProductSimple;
+        $this->catalogProductView = $catalogProductView;
+
+        $this->addToCardAbsentOnCategory();
+        $this->addToCardAbsentOnProduct();
+    }
+
+    /**
+     * "Add to cart" button is not displayed on Category page
+     *
+     * @return void
+     */
+    protected function addToCardAbsentOnCategory()
+    {
+        $this->cmsIndex->open();
+        $this->cmsIndex->getTopmenu()->selectCategoryByName(
+            $this->catalogProductSimple->getCategoryIds()[0]['name']
+        );
+        \PHPUnit_Framework_Assert::assertFalse(
+            $this->catalogCategoryView->getListProductBlock()->checkAddToCardButton(),
+            "Button 'Add to Card' is present on Category page"
+        );
+    }
+
+    /**
+     * "Add to cart" button is not display on Product page
+     *
+     * @return void
+     */
+    protected function addToCardAbsentOnProduct()
+    {
+        $this->cmsIndex->open();
+        $this->cmsIndex->getTopmenu()->selectCategoryByName(
+            $this->catalogProductSimple->getCategoryIds()[0]['name']
+        );
+        $this->catalogCategoryView->getListProductBlock()->openProductViewPage($this->catalogProductSimple->getName());
+        \PHPUnit_Framework_Assert::assertFalse(
+            $this->catalogProductView->getViewBlock()->checkAddToCardButton(),
+            "Button 'Add to Card' is present on Product page"
+        );
+    }
+
+    /**
+     * Text absent button "Add to Cart" on the category/product pages
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Button 'Add to Card' is absent on Category page and Product Page.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php
new file mode 100644
index 0000000000000000000000000000000000000000..60b6febce2924aa106087516662280d5d06c0164
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+
+/**
+ * Class AssertAddToCartButtonPresent
+ * Checks the button on the category/product pages
+ */
+class AssertAddToCartButtonPresent extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Category Page on Frontend
+     *
+     * @var CatalogCategoryView
+     */
+    protected $catalogCategoryView;
+
+    /**
+     * Index Page
+     *
+     * @var CmsIndex
+     */
+    protected $cmsIndex;
+
+    /**
+     * Product simple fixture
+     *
+     * @var CatalogProductSimple
+     */
+    protected $catalogProductSimple;
+
+    /**
+     * Product Page on Frontend
+     *
+     * @var CatalogProductView
+     */
+    protected $catalogProductView;
+
+    /**
+     * Assert that "Add to cart" button is present on page.
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CatalogCategoryView $catalogCategoryView
+     * @param CatalogProductSimple $catalogProductSimple
+     * @param CatalogProductView $catalogProductView
+     *
+     * @return void
+     */
+    public function processAssert(
+        CmsIndex $cmsIndex,
+        CatalogCategoryView $catalogCategoryView,
+        CatalogProductSimple $catalogProductSimple,
+        CatalogProductView $catalogProductView
+    ) {
+        $this->catalogCategoryView = $catalogCategoryView;
+        $this->cmsIndex = $cmsIndex;
+        $this->catalogProductSimple = $catalogProductSimple;
+        $this->catalogProductView = $catalogProductView;
+
+        $this->addToCardPresentOnCategory();
+        $this->addToCardPresentOnProduct();
+    }
+
+    /**
+     * "Add to cart" button is display on Category page
+     *
+     * @return void
+     */
+    protected function addToCardPresentOnCategory()
+    {
+        $this->cmsIndex->open();
+        $this->cmsIndex->getTopmenu()->selectCategoryByName(
+            $this->catalogProductSimple->getCategoryIds()[0]['name']
+        );
+        \PHPUnit_Framework_Assert::assertTrue(
+            $this->catalogCategoryView->getListProductBlock()->checkAddToCardButton(),
+            "Button 'Add to Card' is absent on Category page"
+        );
+    }
+
+    /**
+     * "Add to cart" button is display on Product page
+     *
+     * @return void
+     */
+    protected function addToCardPresentOnProduct()
+    {
+        $this->cmsIndex->open();
+        $this->cmsIndex->getTopmenu()->selectCategoryByName(
+            $this->catalogProductSimple->getCategoryIds()[0]['name']
+        );
+        $this->catalogCategoryView->getListProductBlock()->openProductViewPage($this->catalogProductSimple->getName());
+        \PHPUnit_Framework_Assert::assertTrue(
+            $this->catalogProductView->getViewBlock()->checkAddToCardButton(),
+            "Button 'Add to Card' is absent on Product page"
+        );
+    }
+
+    /**
+     * Text present button "Add to Cart"  on the category/product pages
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Button 'Add to Card' is present on Category page.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..288629bbdcee71f08be19c3ab736bbedf7a99a60
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+
+/**
+ * Class AssertCustomOptionsOnProductPage
+ *
+ * @package Magento\Catalog\Test\Constraint
+ */
+class AssertCustomOptionsOnProductPage extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Product fixture
+     *
+     * @var FixtureInterface
+     */
+    protected $product;
+
+    /**
+     * Assertion that commodity options are displayed correctly
+     *
+     * @param CatalogProductView $catalogProductView
+     * @param FixtureInterface $product
+     * @return void
+     */
+    public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product)
+    {
+        $this->product = $product;
+        // TODO fix initialization url for frontend page
+        // Open product view page
+        $catalogProductView->init($this->product);
+        $catalogProductView->open();
+        $customOptions = $catalogProductView->getCustomOptionsBlock()->getOptions();
+        $compareOptions = $this->product->getCustomOptions();
+
+        $compareOptions = $this->prepareOptionArray($compareOptions);
+        ksort($compareOptions);
+        ksort($customOptions);
+        $noError = array_keys($compareOptions) === array_keys($customOptions);
+
+        if ($noError) {
+            $noError = $this->compareOptions($customOptions, $compareOptions);
+        }
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            $noError,
+            'Incorrect display of custom product options on the product page.'
+        );
+    }
+
+    /**
+     * Comparison of options
+     *
+     * @param array $options
+     * @param array $compareOptions
+     * @return bool
+     */
+    protected function compareOptions(array $options, array $compareOptions)
+    {
+        foreach ($options as $key => $option) {
+            sort($option['price']);
+            if (!isset($compareOptions[$key]['price'])) {
+                return false;
+            }
+            sort($compareOptions[$key]['price']);
+            if ($option['is_require'] !== $compareOptions[$key]['is_require']
+                || $option['price'] !== $compareOptions[$key]['price']
+            ) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Preparation options before comparing
+     *
+     * @param array $options
+     * @return array
+     */
+    protected function prepareOptionArray(array $options)
+    {
+        $result = [];
+        $productPrice = $this->product->getPrice();
+        $placeholder = ['Yes' => true, 'No' => false];
+        foreach ($options as $option) {
+            $result[$option['title']]['is_require'] = $placeholder[$option['is_require']];
+            $result[$option['title']]['price'] = [];
+            foreach ($option['options'] as $optionValue) {
+                if ($optionValue['price_type'] === 'Percent') {
+                    $optionValue['price'] = $productPrice / 100 * $optionValue['price'];
+                }
+                $result[$option['title']]['price'][] = number_format($optionValue['price'], 2);
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Value of custom option on the page is correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..f6b68f85742cd858c1a4c4130ecf15af9c4c52d2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+
+/**
+ * Class AssertGroupedPriceOnProductPage
+ */
+class AssertGroupedPriceOnProductPage extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that displayed grouped price on product page equals passed from fixture
+     *
+     * @param CatalogProductView $catalogProductView
+     * @param FixtureInterface $product
+     * @return void
+     */
+    public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product)
+    {
+        $catalogProductView->init($product);
+        $catalogProductView->open();
+        $fields = $product->getData();
+        $groupPrice = $catalogProductView->getViewBlock()->getProductPrice();
+        $groupPrice = empty($groupPrice['price_special_price']) ? null : $groupPrice['price_special_price'];
+        if (!empty($fields['group_price'])) {
+            foreach ($fields['group_price'] as $itemGroupPrice) {
+                \PHPUnit_Framework_Assert::assertEquals(
+                    $itemGroupPrice['price'],
+                    $groupPrice,
+                    'Assert that displayed grouped price on product page NOT equals passed from fixture.'
+                );
+            }
+        }
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Assert that displayed grouped price on product page equals passed from fixture.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..654a826c0c321b783aebedc68f16ccd319d08f9c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+
+/**
+ * Class AssertProductForm
+ */
+class AssertProductForm extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert form data equals fixture data
+     *
+     * @param FixtureInterface $product
+     * @param CatalogProductIndex $productGrid
+     * @param CatalogProductEdit $productPage
+     * @return void
+     */
+    public function processAssert(
+        FixtureInterface $product,
+        CatalogProductIndex $productGrid,
+        CatalogProductEdit $productPage
+    ) {
+        $filter = ['sku' => $product->getSku()];
+        $productGrid->open()->getProductGrid()->searchAndOpen($filter);
+
+        $fixtureData = $productPage->getForm()->getData($product);
+        $formData = $this->prepareFixtureData($product);
+
+        $errors = $this->compareArray($fixtureData, $formData);
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($errors),
+            "These data must be equal to each other:\n" . implode("\n - ", $errors)
+        );
+    }
+
+    /**
+     * Prepares and returns data to the fixture, ready for comparison
+     *
+     * @param FixtureInterface $product
+     * @return array
+     */
+    protected function prepareFixtureData(FixtureInterface $product)
+    {
+        $compareData = $product->getData();
+        $compareData = array_filter($compareData);
+
+        $compareData['price'] = $this->priceFormat($compareData['price']);
+        $compareData['qty'] = number_format($compareData['qty'], 4, '.', '');
+        $compareData['weight'] = number_format($compareData['weight'], 4, '.', '');
+        unset($compareData['url_key']);
+
+        if (!empty($compareData['tier_price'])) {
+            foreach ($compareData['tier_price'] as &$value) {
+                $value['price'] = $this->priceFormat($value['price']);
+            }
+            unset($value);
+        }
+        if (!empty($compareData['group_price'])) {
+            foreach ($compareData['group_price'] as &$value) {
+                $value['price'] = $this->priceFormat($value['price']);
+            }
+            unset($value);
+        }
+        if (!empty($compareData['custom_options'])) {
+            $placeholder = ['Yes' => true, 'No' => false];
+            foreach ($compareData['custom_options'] as &$option) {
+                $option['is_require'] = $placeholder[$option['is_require']];
+                foreach ($option['options'] as &$value) {
+                    $value['price'] = $this->priceFormat($value['price']);
+                }
+                unset($value);
+            }
+            unset($option);
+        }
+
+        return $compareData;
+    }
+
+    /**
+     * Comparison of multidimensional arrays
+     *
+     * @param array $fixtureData
+     * @param array $formData
+     * @return array
+     */
+    protected function compareArray(array $fixtureData, array $formData)
+    {
+        $errors = [];
+        ksort($fixtureData);
+        ksort($formData);
+        if (array_keys($fixtureData) !== array_keys($formData)) {
+            return ['arrays do not correspond to each other in composition'];
+        }
+
+        foreach ($fixtureData as $key => $value) {
+            if (is_array($value) && is_array($formData[$key])
+                && ($innerErrors = $this->compareArray($value, $formData[$key])) && !empty($innerErrors)
+            ) {
+                $errors = array_merge($errors, $innerErrors);
+            } elseif ($value != $formData[$key]) {
+                $fixtureValue = empty($value) ? '<empty-value>' : $value;
+                $formValue = empty($formData[$key]) ? '<empty-value>' : $formData[$key];
+                $errors = array_merge(
+                    $errors,
+                    [
+                        "error key -> '{$key}' : error value ->  '{$fixtureValue}' does not equal -> '{$formValue}'"
+                    ]
+                );
+            }
+        }
+
+        return $errors;
+    }
+
+    /**
+     * Formatting prices
+     *
+     * @param $price
+     * @return string
+     */
+    protected function priceFormat($price)
+    {
+        return number_format($price, 2, '.', '');
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Form data equal the fixture data.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php
index 55362a5afd49f5af2dcabad295fd5e90623910f0..9ea5b041805185337ddf80218b2665c15d337b0a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCart.php
@@ -24,10 +24,10 @@
 
 namespace Magento\Catalog\Test\Constraint;
 
-use Magento\Catalog\Test\Page\Product\CatalogProductView;
-use Magento\Checkout\Test\Page\CheckoutCart;
+use Mtf\Fixture\FixtureInterface;
 use Mtf\Constraint\AbstractConstraint;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Checkout\Test\Page\CheckoutCart;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
 
 /**
  * Class AssertProductInCart
@@ -42,13 +42,16 @@ class AssertProductInCart extends AbstractConstraint
     protected $severeness = 'low';
 
     /**
+     * Assertion that the product is correctly displayed in cart
+     *
      * @param CatalogProductView $catalogProductView
-     * @param CatalogProductSimple $product
+     * @param FixtureInterface $product
      * @param CheckoutCart $checkoutCart
+     * @return void
      */
     public function processAssert(
         CatalogProductView $catalogProductView,
-        CatalogProductSimple $product,
+        FixtureInterface $product,
         CheckoutCart $checkoutCart
     ) {
         //Add product to cart
@@ -56,43 +59,74 @@ class AssertProductInCart extends AbstractConstraint
         $catalogProductView->open();
         $productOptions = $product->getCustomOptions();
         if ($productOptions) {
-            $customOption = $catalogProductView->getOptionsBlock();
-            $options = $customOption->getProductCustomOptions();
+            $customOption = $catalogProductView->getCustomOptionsBlock();
+            $options = $customOption->getOptions();
             $key = $productOptions[0]['title'];
-            $customOption->selectProductCustomOption($options[$key][1]);
+            $customOption->selectProductCustomOption(reset($options[$key]['value']));
         }
         $catalogProductView->getViewBlock()->clickAddToCart();
 
+        // Check price
         $this->assertOnShoppingCart($product, $checkoutCart);
     }
 
     /**
-     * Assert prices on the shopping Cart
+     * Assert prices on the shopping cart
      *
-     * @param CatalogProductSimple $product
+     * @param FixtureInterface $product
      * @param CheckoutCart $checkoutCart
+     * @return void
      */
-    protected function assertOnShoppingCart(CatalogProductSimple $product, CheckoutCart $checkoutCart)
+    protected function assertOnShoppingCart(FixtureInterface $product, CheckoutCart $checkoutCart)
     {
-        /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple\Price $priceFixture */
-        $priceFixture = $product->getDataFieldConfig('price')['source'];
-        $pricePresetData = $priceFixture->getPreset();
+        $cartBlock = $checkoutCart->getCartBlock();
+        $productName = $product->getName();
+        $productOptions = $product->getCustomOptions();
+        $priceComparing = $product->getPrice();
+
+        if ($groupPrice = $product->getGroupPrice()) {
+            $groupPrice = reset($groupPrice);
+            $priceComparing = $groupPrice['price'];
+        }
+
+        if ($specialPrice = $product->getSpecialPrice()) {
+            $priceComparing = $specialPrice;
+        }
+
+        if (!empty($productOptions)) {
+            $productOption = reset($productOptions);
+            $optionsData = reset($productOption['options']);
+            $optionName = $cartBlock->getCartItemOptionsNameByProductName($productName);
+            $optionValue = $cartBlock->getCartItemOptionsValueByProductName($productName);
+
+            \PHPUnit_Framework_Assert::assertTrue(
+                trim($optionName) === $productOption['title']
+                && trim($optionValue) === $optionsData['title'],
+                'In the cart wrong option product.'
+            );
+
+            if ($optionsData['price_type'] === 'Percent') {
+                $priceComparing = $priceComparing * (1 + $optionsData['price'] / 100);
+            } else {
+                $priceComparing += $optionsData['price'];
+            }
+        }
 
-        $price = $checkoutCart->getCartBlock()->getProductPriceByName($product->getName());
+        $price = $checkoutCart->getCartBlock()->getProductPriceByName($productName);
         \PHPUnit_Framework_Assert::assertEquals(
-            $pricePresetData['cart_price'],
+            '$' . number_format($priceComparing, 2),
             $price,
             'Product price in shopping cart is not correct.'
         );
     }
 
     /**
-     * Text of Visible in category assert
+     * Returns a string representation of the object.
      *
      * @return string
      */
     public function toString()
     {
-        return 'Product price in shopping cart is not correct.';
+        return 'Product is correctly displayed in cart.';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCategory.php
index 0697b26cb6a1415805da33a40d6d3bc193f4e471..24097b3170328f23194bfd2fccc5a6be1eaf1343 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCategory.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInCategory.php
@@ -24,11 +24,11 @@
 
 namespace Magento\Catalog\Test\Constraint;
 
-use Mtf\Constraint\AbstractConstraint;
-use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+use Mtf\Fixture\FixtureInterface;
 use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
 use Magento\Catalog\Test\Fixture\Category;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
 
 /**
  * Class AssertProductInCategory
@@ -43,74 +43,65 @@ class AssertProductInCategory extends AbstractConstraint
     protected $severeness = 'low';
 
     /**
+     * Checking the product in the page of its price
+     *
      * @param CatalogCategoryView $catalogCategoryView
      * @param CmsIndex $cmsIndex
-     * @param CatalogProductSimple $product
+     * @param FixtureInterface $product
      * @param Category $category
+     * @return void
      */
     public function processAssert(
         CatalogCategoryView $catalogCategoryView,
         CmsIndex $cmsIndex,
-        CatalogProductSimple $product,
+        FixtureInterface $product,
         Category $category
     ) {
-        //Open category view page
+        //Open category view page and check visible product
         $cmsIndex->open();
         $cmsIndex->getTopmenu()->selectCategoryByName($category->getCategoryName());
 
-        //process asserts
+        $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName());
+        while (!$isProductVisible && $catalogCategoryView->getToolbar()->nextPage()) {
+            $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName());
+        }
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            $isProductVisible,
+            'Product is absent on category page.'
+        );
+
+        //Process price asserts
         $this->assertPrice($product, $catalogCategoryView);
     }
 
     /**
      * Verify product price on category view page
      *
-     * @param CatalogProductSimple $product
+     * @param FixtureInterface $product
      * @param CatalogCategoryView $catalogCategoryView
+     * @return void
      */
-    protected function assertPrice(CatalogProductSimple $product, CatalogCategoryView $catalogCategoryView)
+    protected function assertPrice(FixtureInterface $product, CatalogCategoryView $catalogCategoryView)
     {
-        /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple\Price $priceFixture */
-        $priceFixture = $product->getDataFieldConfig('price')['source'];
-        $pricePresetData = $priceFixture->getPreset();
+        $price = $catalogCategoryView->getListProductBlock()->getProductPriceBlock($product->getName())
+            ->getRegularPrice();
 
-        //Regular price verification
-        if (isset($pricePresetData['category_special_price'])) {
-            $regularPrice = $catalogCategoryView->getListProductBlock()->getProductPriceBlock($product->getName())
-                ->getRegularPrice();
-            \PHPUnit_Framework_Assert::assertEquals(
-                $pricePresetData['category_price'],
-                $regularPrice,
-                'Product regular price on category page is not correct.'
-            );
-            //Special price verification
-            $specialPrice = $catalogCategoryView->getListProductBlock()->getProductPriceBlock(
-                $product->getName()
-            )->getSpecialPrice();
-            \PHPUnit_Framework_Assert::assertEquals(
-                $pricePresetData['category_special_price'],
-                $specialPrice,
-                'Product special price on category page is not correct.'
-            );
-        } else {
-            //Price verification
-            $price = $catalogCategoryView->getListProductBlock()->getProductPriceBlock($product->getName())
-                ->getPrice();
-            \PHPUnit_Framework_Assert::assertContains(
-                (string)$price,
-                $pricePresetData['category_price'],
-                'Product price on category page is not correct.'
-            );
-        }
+        $priceComparing = '$' . number_format($product->getPrice(), 2);
+        \PHPUnit_Framework_Assert::assertEquals(
+            $priceComparing,
+            $price,
+            'Product regular price on category page is not correct.'
+        );
     }
 
     /**
-     * Text of Visible in category assert
+     * Returns a string representation of the object.
      *
      * @return string
      */
     public function toString()
     {
-        return 'Product price on category page is not correct.';
+        return 'Product price on category page correct.';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInGrid.php
index dc126271b68a45e786be780f881a081dbf2e31d6..0b069ffcaff421e3f03344b5c964f882c346fa56 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInGrid.php
@@ -24,13 +24,12 @@
 
 namespace Magento\Catalog\Test\Constraint;
 
+use Mtf\Fixture\FixtureInterface;
 use Mtf\Constraint\AbstractConstraint;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
 
 /**
  * Class AssertProductInGrid
- *
  */
 class AssertProductInGrid extends AbstractConstraint
 {
@@ -42,27 +41,29 @@ class AssertProductInGrid extends AbstractConstraint
     protected $severeness = 'high';
 
     /**
-     * Assert product availability in Products Grid
+     * Assert product availability in products grid
      *
-     * @param CatalogProductSimple $product
-     * @param CatalogProductIndex $productPageGrid
+     * @param FixtureInterface $product
+     * @param CatalogProductIndex $productGrid
      * @return void
      */
-    public function processAssert(CatalogProductSimple $product, CatalogProductIndex $productPageGrid)
+    public function processAssert(FixtureInterface $product, CatalogProductIndex $productGrid)
     {
         $filter = ['sku' => $product->getSku()];
-        $productPageGrid->open();
+        $productGrid->open();
         \PHPUnit_Framework_Assert::assertTrue(
-            $productPageGrid->getProductGrid()->isRowVisible($filter),
+            $productGrid->getProductGrid()->isRowVisible($filter),
             'Product with sku \'' . $product->getSku() . '\' is absent in Products grid.'
         );
     }
 
     /**
-     * @inheritdoc
+     * Returns a string representation of the object.
+     *
+     * @return string
      */
     public function toString()
     {
-        return 'Product is present in Products grid.';
+        return 'Product is present in products grid.';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php
index c2899188b956847af44ceb51200a55f1e9e8a2ce..ebfff102de1dc69f6fac10dc3c98cdac0d8001cb 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductInStock.php
@@ -24,13 +24,12 @@
 
 namespace Magento\Catalog\Test\Constraint;
 
+use Mtf\Fixture\FixtureInterface;
 use Mtf\Constraint\AbstractConstraint;
 use Magento\Catalog\Test\Page\Product\CatalogProductView;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 
 /**
  * Class AssertProductInStock
- *
  */
 class AssertProductInStock extends AbstractConstraint
 {
@@ -50,11 +49,12 @@ class AssertProductInStock extends AbstractConstraint
      * Assert that In Stock status is displayed on product page
      *
      * @param CatalogProductView $catalogProductView
-     * @param CatalogProductSimple $product
+     * @param FixtureInterface $product
      * @return void
      */
-    public function processAssert(CatalogProductView $catalogProductView, CatalogProductSimple $product)
+    public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product)
     {
+        // TODO fix initialization url for frontend page
         $catalogProductView->init($product);
         $catalogProductView->open();
         \PHPUnit_Framework_Assert::assertEquals(
@@ -65,7 +65,7 @@ class AssertProductInStock extends AbstractConstraint
     }
 
     /**
-     * Text of In Stock assertion
+     * Returns a string representation of the object.
      *
      * @return string
      */
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php
index 28c575f0392aa119a93ae409fbafe6c953555bb7..bda4162dc0647a9b685565b33e4bbe525216e043 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductOutOfStock.php
@@ -24,13 +24,12 @@
 
 namespace Magento\Catalog\Test\Constraint;
 
+use Mtf\Fixture\FixtureInterface;
 use Mtf\Constraint\AbstractConstraint;
 use Magento\Catalog\Test\Page\Product\CatalogProductView;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 
 /**
  * Class AssertProductOutOfStock
- *
  */
 class AssertProductOutOfStock extends AbstractConstraint
 {
@@ -50,10 +49,10 @@ class AssertProductOutOfStock extends AbstractConstraint
      * Assert  that Out of Stock status is displayed on product page
      *
      * @param CatalogProductView $catalogProductView
-     * @param CatalogProductSimple $product
+     * @param FixtureInterface $product
      * @return void
      */
-    public function processAssert(CatalogProductView $catalogProductView, CatalogProductSimple $product)
+    public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product)
     {
         $catalogProductView->init($product);
         $catalogProductView->open();
@@ -65,7 +64,7 @@ class AssertProductOutOfStock extends AbstractConstraint
     }
 
     /**
-     * Text of Out of Stock assert
+     * Returns a string representation of the object.
      *
      * @return string
      */
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..90d03847b8e8ee5f0cfa7565cbae88f10d8f0b94
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php
@@ -0,0 +1,154 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+
+/**
+ * Class AssertProductPage
+ */
+class AssertProductPage extends AbstractConstraint
+{
+    /**
+     * Product fixture
+     *
+     * @var FixtureInterface
+     */
+    protected $product;
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assertion that the product page is displayed correctly
+     *
+     * @param CatalogProductView $catalogProductView
+     * @param FixtureInterface $product
+     * @return void
+     */
+    public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product)
+    {
+        $this->product = $product;
+        // TODO fix initialization url for frontend page
+        //Open product view page
+        $catalogProductView->init($product);
+        $catalogProductView->open();
+
+        //Process assertions
+        $this->assertOnProductView($catalogProductView);
+    }
+
+    /**
+     * Assert prices on the product view page
+     *
+     * @param CatalogProductView $catalogProductView
+     * @return void
+     */
+    protected function assertOnProductView(CatalogProductView $catalogProductView)
+    {
+        $viewBlock = $catalogProductView->getViewBlock();
+        $price = $viewBlock->getProductPriceBlock()->getPrice();
+        $errorsMessages = [
+            'name'              => '- product name on product view page is not correct.',
+            'sku'               => '- product sku on product view page is not correct.',
+            'regular_price'     => '- product regular price on product view page is not correct.',
+            'short_description' => '- product short description on product view page is not correct.',
+            'description'       => '- product description on product view page is not correct.'
+        ];
+        $dataOnPage = [
+            'name'          => $viewBlock->getProductName(),
+            'sku'           => $viewBlock->getProductSku(),
+            'regular_price' => $price['price_regular_price']
+        ];
+        $compareData = [
+            'name'          => $this->product->getName(),
+            'sku'           => $this->product->getSku(),
+            'regular_price' => number_format($this->product->getPrice(), 2),
+
+        ];
+
+        if ($productShortDescription = $this->product->getShortDescription()) {
+            $compareData['short_description'] = $productShortDescription;
+            $dataOnPage['short_description'] = $viewBlock->getProductShortDescription();
+        }
+        if ($productDescription = $this->product->getDescription()) {
+            $compareData['description'] = $productDescription;
+            $dataOnPage['description'] = $viewBlock->getProductDescription();
+        }
+
+        $badValues = array_diff($dataOnPage, $compareData);
+        $errorsMessages = array_merge(
+            $this->assertSpecialPrice($price),
+            array_intersect_key($errorsMessages, array_keys($badValues))
+        );
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($errorsMessages),
+            PHP_EOL . 'Found the following errors:' . PHP_EOL
+            . implode(' ' . PHP_EOL, $errorsMessages)
+        );
+    }
+
+    /**
+     * Checking the special product price
+     *
+     * @param array $price
+     * @return array
+     */
+    protected function assertSpecialPrice(array $price)
+    {
+        $priceComparing = false;
+        if ($specialPrice = $this->product->getSpecialPrice()) {
+            $priceComparing = $specialPrice;
+        }
+        if ($groupPrice = $this->product->getGroupPrice()) {
+            $groupPrice = reset($groupPrice);
+            $priceComparing = $groupPrice['price'];
+        }
+        if ($priceComparing && isset($price['price_special_price'])
+            && number_format($priceComparing, 2) !== $price['price_special_price']
+        ) {
+            return ['special_price' => '- product special price on product view page is not correct.'];
+        }
+
+        return [];
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product on product view page is not correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSaveMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSaveMessage.php
index a79f146ab5d265dcf702e3ad68f32fd671ad3baa..0c0795556a4689a9d383aaaf59e39206e8a12ac2 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSaveMessage.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSaveMessage.php
@@ -25,14 +25,16 @@
 namespace Magento\Catalog\Test\Constraint;
 
 use Mtf\Constraint\AbstractConstraint;
-use Magento\Catalog\Test\Page\Product\CatalogProductEdit;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit;
 
 /**
  * Class AssertProductSaveMessage
- *
  */
 class AssertProductSaveMessage extends AbstractConstraint
 {
+    /**
+     * Text value to be checked
+     */
     const SUCCESS_MESSAGE = 'You saved the product.';
 
     /**
@@ -61,7 +63,9 @@ class AssertProductSaveMessage extends AbstractConstraint
     }
 
     /**
-     * @inheritdoc
+     * Returns a string representation of the object.
+     *
+     * @return string
      */
     public function toString()
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php
index fdb1eae2c879d29e57b731284e46c1d372a21219..aff6b2713f390f2a85e62525b8bd7558f91b37bf 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php
@@ -24,14 +24,13 @@
 
 namespace Magento\Catalog\Test\Constraint;
 
+use Mtf\Fixture\FixtureInterface;
+use Magento\Cms\Test\Page\CmsIndex;
 use Mtf\Constraint\AbstractConstraint;
 use Magento\CatalogSearch\Test\Page\CatalogsearchResult;
-use Magento\Cms\Test\Page\CmsIndex;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 
 /**
  * Class AssertProductSearchableBySku
- *
  */
 class AssertProductSearchableBySku extends AbstractConstraint
 {
@@ -47,13 +46,13 @@ class AssertProductSearchableBySku extends AbstractConstraint
      *
      * @param CatalogsearchResult $catalogSearchResult
      * @param CmsIndex $cmsIndex
-     * @param CatalogProductSimple $product
+     * @param FixtureInterface $product
      * @return void
      */
     public function processAssert(
         CatalogsearchResult $catalogSearchResult,
         CmsIndex $cmsIndex,
-        CatalogProductSimple $product
+        FixtureInterface $product
     ) {
         $cmsIndex->open();
         $cmsIndex->getSearchBlock()->search($product->getSku());
@@ -64,7 +63,7 @@ class AssertProductSearchableBySku extends AbstractConstraint
     }
 
     /**
-     * Text of Searchable assert
+     * Returns a string representation of the object.
      *
      * @return string
      */
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductView.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductView.php
deleted file mode 100644
index 93e0c24e0065c8700966eaaac07fade19d081e2d..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductView.php
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Catalog\Test\Constraint;
-
-use Magento\Catalog\Test\Page\Product\CatalogProductView;
-use Magento\Checkout\Test\Page\CheckoutCart;
-use Mtf\Constraint\AbstractConstraint;
-use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
-use Magento\Cms\Test\Page\CmsIndex;
-use Magento\Catalog\Test\Fixture\Category;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
-
-/**
- * Class AssertProductView
- */
-class AssertProductView extends AbstractConstraint
-{
-    /**
-     * Constraint severeness
-     *
-     * @var string
-     */
-    protected $severeness = 'low';
-
-    /**
-     * @param CatalogProductView $catalogProductView
-     * @param CatalogProductSimple $product
-     */
-    public function processAssert(
-        CatalogProductView $catalogProductView,
-        CatalogProductSimple $product
-    ) {
-        //Open product view page
-        $catalogProductView->init($product);
-        $catalogProductView->open();
-
-        //Process assertions
-        $this->assertOnProductView($product, $catalogProductView);
-    }
-
-    /**
-     * Assert prices on the product view Page
-     *
-     * @param CatalogProductSimple $product
-     * @param CatalogProductView $catalogProductView
-     */
-    protected function assertOnProductView(CatalogProductSimple $product, CatalogProductView $catalogProductView)
-    {
-        /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple\Price $priceFixture */
-        $priceFixture = $product->getDataFieldConfig('price')['source'];
-        $pricePresetData = $priceFixture->getPreset();
-
-        if (isset($pricePresetData['product_special_price'])) {
-            $regularPrice = $catalogProductView->getViewBlock()->getProductPriceBlock()->getRegularPrice();
-            \PHPUnit_Framework_Assert::assertEquals(
-                $pricePresetData['product_price'],
-                $regularPrice,
-                'Product regular price on product view page is not correct.'
-            );
-
-            $specialPrice = $catalogProductView->getViewBlock()->getProductPriceBlock()->getSpecialPrice();
-            \PHPUnit_Framework_Assert::assertEquals(
-                $pricePresetData['product_special_price'],
-                $specialPrice,
-                'Product special price on product view page is not correct.'
-            );
-        } else {
-            $price = $catalogProductView->getViewBlock()->getProductPriceBlock()->getPrice();
-            \PHPUnit_Framework_Assert::assertContains(
-                (string)$price,
-                $pricePresetData['product_price'],
-                'Product price on product view page is not correct.'
-            );
-        }
-    }
-
-    /**
-     * Text of Visible in category assert
-     *
-     * @return string
-     */
-    public function toString()
-    {
-        return 'Product price on product view page is not correct.';
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php
index c2a58f7942f9124a6dbbcb1d72c8a68a8dcf7dac..db04ab19a913ad5344c0842d05d9109ee5868a61 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php
@@ -24,15 +24,14 @@
 
 namespace Magento\Catalog\Test\Constraint;
 
-use Mtf\Constraint\AbstractConstraint;
-use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+use Mtf\Fixture\FixtureInterface;
 use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
 use Magento\Catalog\Test\Fixture\Category;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
 
 /**
  * Class AssertProductVisibleInCategory
- *
  */
 class AssertProductVisibleInCategory extends AbstractConstraint
 {
@@ -48,26 +47,32 @@ class AssertProductVisibleInCategory extends AbstractConstraint
      *
      * @param CatalogCategoryView $catalogCategoryView
      * @param CmsIndex $cmsIndex
-     * @param CatalogProductSimple $product
+     * @param FixtureInterface $product
      * @param Category $category
      * @return void
      */
     public function processAssert(
         CatalogCategoryView $catalogCategoryView,
         CmsIndex $cmsIndex,
-        CatalogProductSimple $product,
+        FixtureInterface $product,
         Category $category
     ) {
         $cmsIndex->open();
         $cmsIndex->getTopmenu()->selectCategoryByName($category->getCategoryName());
+
+        $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName());
+        while (!$isProductVisible && $catalogCategoryView->getToolbar()->nextPage()) {
+            $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName());
+        }
+
         \PHPUnit_Framework_Assert::assertTrue(
-            $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName()),
+            $isProductVisible,
             'Product is absent on category page.'
         );
     }
 
     /**
-     * Text of Visible in category assert
+     * Returns a string representation of the object.
      *
      * @return string
      */
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..3bdec2b01e2bfa13d740cfcc112f2fc57b4f2b05
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+
+/**
+ * Class AssertSpecialPriceOnProductPage
+ */
+class AssertSpecialPriceOnProductPage extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that displayed special price on product page equals passed from fixture
+     *
+     * @param CatalogProductView $catalogProductView
+     * @param FixtureInterface $product
+     * @return void
+     */
+    public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product)
+    {
+        $catalogProductView->init($product);
+        $catalogProductView->open();
+        $fields = $product->getData();
+        $specialPrice = $catalogProductView->getViewBlock()->getProductPrice();
+        $specialPrice = isset($specialPrice['price_special_price']) ? $specialPrice['price_special_price'] : null;
+        if (!empty($fields['special_price'])) {
+            \PHPUnit_Framework_Assert::assertEquals(
+                $fields['special_price'],
+                $specialPrice,
+                'Assert that displayed special price on product page NOT equals passed from fixture.'
+            );
+        }
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Assert that displayed special price on product page equals passed from fixture";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php
new file mode 100644
index 0000000000000000000000000000000000000000..a7642631be0b996add74cedaa7206c56b4b82a45
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+
+/**
+ * Class AssertTierPriceOnProductPage
+ */
+class AssertTierPriceOnProductPage extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assertion that tier prices are displayed correctly
+     *
+     * @param CatalogProductView $catalogProductView
+     * @param FixtureInterface $product
+     * @return void
+     */
+    public function processAssert(CatalogProductView $catalogProductView, FixtureInterface $product)
+    {
+        // TODO fix initialization url for frontend page
+        //Open product view page
+        $catalogProductView->init($product);
+        $catalogProductView->open();
+
+        //Process assertions
+        $this->assertTierPrice($product, $catalogProductView);
+    }
+
+    /**
+     * Verify product tier price on product view page
+     *
+     * @param FixtureInterface $product
+     * @param CatalogProductView $catalogProductView
+     * @return void
+     */
+    protected function assertTierPrice(FixtureInterface $product, CatalogProductView $catalogProductView)
+    {
+        $noError = true;
+        $match = [];
+        $index = 1;
+        $viewBlock = $catalogProductView->getViewBlock();
+        $tierPrices = $product->getTierPrice();
+
+        foreach ($tierPrices as $tierPrice) {
+            $text = $viewBlock->getTierPrices($index++);
+            $noError = (bool)preg_match('#^[^\d]+(\d+)[^\d]+(\d+(?:(?:,\d+)*)+(?:.\d+)*).*#i', $text, $match);
+            if (!$noError) {
+                break;
+            }
+            if (count($match) < 2
+                && $match[1] != $tierPrice['price_qty']
+                || $match[2] !== number_format($tierPrice['price'], 2)
+            ) {
+                $noError = false;
+                break;
+            }
+        }
+
+        \PHPUnit_Framework_Assert::assertTrue($noError, 'Product tier price on product page is not correct.');
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Tier price is displayed on the product page';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.php
new file mode 100644
index 0000000000000000000000000000000000000000..395510caa90492316e8c04e0ebda12981d04ba4b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.php
@@ -0,0 +1,233 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class CatalogCategoryEntity
+ * Category fixture
+ */
+class CatalogCategoryEntity extends InjectableFixture
+{
+    /**
+     * @var string
+     */
+    protected $repositoryClass = 'Magento\Catalog\Test\Repository\CatalogCategoryEntity';
+
+    /**
+     * @var string
+     */
+    protected $handlerInterface = 'Magento\Catalog\Test\Handler\CatalogCategoryEntity\CatalogCategoryEntityInterface';
+
+    protected $defaultDataSet = [
+        'name' => 'Category%isolation%',
+        'path' => 'Default Category',
+        'url_key' => 'category%isolation%',
+        'is_active' => 'Yes',
+        'include_in_menu' => 'Yes',
+        'parent_id' => 2,
+    ];
+
+    protected $entity_id = [
+        'attribute_code' => 'entity_id',
+        'backend_type' => 'int',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $entity_type_id = [
+        'attribute_code' => 'entity_type_id',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $attribute_set_id = [
+        'attribute_code' => 'attribute_set_id',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $parent_id = [
+        'attribute_code' => 'parent_id',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $created_at = [
+        'attribute_code' => 'created_at',
+        'backend_type' => 'timestamp',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $updated_at = [
+        'attribute_code' => 'updated_at',
+        'backend_type' => 'timestamp',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $path = [
+        'attribute_code' => 'path',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $position = [
+        'attribute_code' => 'position',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $level = [
+        'attribute_code' => 'level',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $children_count = [
+        'attribute_code' => 'children_count',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $id = [
+        'attribute_code' => 'id',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $name = [
+        'attribute_code' => 'name',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $is_active = [
+        'attribute_code' => 'is_active',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $url_key = [
+        'attribute_code' => 'url_key',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $include_in_menu = [
+        'attribute_code' => 'include_in_menu',
+        'backend_type' => 'virtual',
+    ];
+
+    public function getEntityId()
+    {
+        return $this->getData('entity_id');
+    }
+
+    public function getEntityTypeId()
+    {
+        return $this->getData('entity_type_id');
+    }
+
+    public function getAttributeSetId()
+    {
+        return $this->getData('attribute_set_id');
+    }
+
+    public function getParentId()
+    {
+        return $this->getData('parent_id');
+    }
+
+    public function getCreatedAt()
+    {
+        return $this->getData('created_at');
+    }
+
+    public function getUpdatedAt()
+    {
+        return $this->getData('updated_at');
+    }
+
+    public function getPath()
+    {
+        return $this->getData('path');
+    }
+
+    public function getPosition()
+    {
+        return $this->getData('position');
+    }
+
+    public function getLevel()
+    {
+        return $this->getData('level');
+    }
+
+    public function getChildrenCount()
+    {
+        return $this->getData('children_count');
+    }
+
+    public function getId()
+    {
+        return $this->getData('id');
+    }
+
+    public function getName()
+    {
+        return $this->getData('name');
+    }
+
+    public function getIsActive()
+    {
+        return $this->getData('is_active');
+    }
+
+    public function getUrlKey()
+    {
+        return $this->getData('url_key');
+    }
+
+    public function getIncludeInMenu()
+    {
+        return $this->getData('include_in_menu');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cc8301ed27d50c14cc432154b384d0990a91709c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategoryEntity.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Catalog\Test\Fixture\CatalogCategoryEntity">
+    <module>Magento_Catalog</module>
+    <type>flat</type>
+    <entity_type>catalog_category_entity</entity_type>
+    <collection>Magento\Catalog\Model\Resource\Category\Collection</collection>
+    <fields>
+        <entity_id>
+            <attribute_code>entity_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input></input>
+        </entity_id>
+        <entity_type_id>
+            <attribute_code>entity_type_id</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </entity_type_id>
+        <attribute_set_id>
+            <attribute_code>attribute_set_id</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </attribute_set_id>
+        <parent_id>
+            <attribute_code>parent_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </parent_id>
+        <created_at>
+            <attribute_code>created_at</attribute_code>
+            <backend_type>timestamp</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </created_at>
+        <updated_at>
+            <attribute_code>updated_at</attribute_code>
+            <backend_type>timestamp</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </updated_at>
+        <path>
+            <attribute_code>path</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </path>
+        <position>
+            <attribute_code>position</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </position>
+        <level>
+            <attribute_code>level</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </level>
+        <children_count>
+            <attribute_code>children_count</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </children_count>
+        <id>
+            <attribute_code>id</attribute_code>
+            <backend_type>virtual</backend_type>
+        </id>
+        <name>
+            <attribute_code>name</attribute_code>
+            <backend_type>virtual</backend_type>
+        </name>
+        <is_active>
+            <attribute_code>is_active</attribute_code>
+            <backend_type>virtual</backend_type>
+        </is_active>
+        <url_key>
+            <attribute_code>url_key</attribute_code>
+            <backend_type>virtual</backend_type>
+        </url_key>
+        <include_in_menu>
+            <attribute_code>include_in_menu</attribute_code>
+            <backend_type>virtual</backend_type>
+        </include_in_menu>
+    </fields>
+    <repository_class>Magento\Catalog\Test\Repository\CatalogCategoryEntity</repository_class>
+    <handler_interface>Magento\Catalog\Test\Handler\CatalogCategoryEntity\CatalogCategoryEntityInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
index 670aaeb09b42e8ca6b74a06017cb3f945fd0038f..802363d4ba2292ffe2b42a6e10bb963aa703c500 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
@@ -32,7 +32,7 @@ use Mtf\Repository\RepositoryFactory;
 
 /**
  * Class CatalogProductSimple
- *
+ * Product Simple fixture
  */
 class CatalogProductSimple extends InjectableFixture
 {
@@ -90,14 +90,11 @@ class CatalogProductSimple extends InjectableFixture
     ];
 
     protected $defaultDataSet = [
-        'enable_googlecheckout' => null,
-        'msrp_display_actual_price_type' => null,
-        'msrp_enabled' => null,
-        'options_container' => null,
-        'quantity_and_stock_status' => null,
-        'status' => null,
-        'tax_class_id' => null,
-        'visibility' => null,
+        'name' => 'Test simple product %isolation%',
+        'sku' => 'test_simple_sku_%isolation%',
+        'price' => ['value' => 100.00],
+        'weight' => 12.0000,
+        'qty' => 10
     ];
 
     protected $category_ids = [
@@ -106,7 +103,7 @@ class CatalogProductSimple extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'text',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CategoryIds'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds',
     ];
 
     protected $color = [
@@ -171,14 +168,7 @@ class CatalogProductSimple extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'textarea',
-    ];
-
-    protected $enable_googlecheckout = [
-        'attribute_code' => 'enable_googlecheckout',
-        'backend_type' => 'int',
-        'is_required' => '0',
-        'default_value' => 'No',
-        'input' => 'select',
+        'group' => 'product-details',
     ];
 
     protected $gallery = [
@@ -204,7 +194,7 @@ class CatalogProductSimple extends InjectableFixture
         'default_value' => '',
         'input' => 'text',
         'group' => 'advanced-pricing',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions',
     ];
 
     protected $has_options = [
@@ -260,6 +250,7 @@ class CatalogProductSimple extends InjectableFixture
         'backend_type' => 'varchar',
         'is_required' => '0',
         'default_value' => '',
+        'group' => 'search-optimization',
         'input' => 'textarea',
     ];
 
@@ -268,6 +259,7 @@ class CatalogProductSimple extends InjectableFixture
         'backend_type' => 'text',
         'is_required' => '0',
         'default_value' => '',
+        'group' => 'search-optimization',
         'input' => 'textarea',
     ];
 
@@ -276,6 +268,7 @@ class CatalogProductSimple extends InjectableFixture
         'backend_type' => 'varchar',
         'is_required' => '0',
         'default_value' => '',
+        'group' => 'search-optimization',
         'input' => 'text',
     ];
 
@@ -299,7 +292,7 @@ class CatalogProductSimple extends InjectableFixture
         'attribute_code' => 'msrp_display_actual_price_type',
         'backend_type' => 'varchar',
         'is_required' => '0',
-        'default_value' => '',
+        'default_value' => 'Use config',
         'input' => 'select',
     ];
 
@@ -307,7 +300,7 @@ class CatalogProductSimple extends InjectableFixture
         'attribute_code' => 'msrp_enabled',
         'backend_type' => 'varchar',
         'is_required' => '0',
-        'default_value' => '',
+        'default_value' => 'In Cart',
         'input' => 'select',
     ];
 
@@ -348,7 +341,8 @@ class CatalogProductSimple extends InjectableFixture
         'attribute_code' => 'options_container',
         'backend_type' => 'varchar',
         'is_required' => '0',
-        'default_value' => '',
+        'default_value' => 'Block after Info Column',
+        'default_value' => 'Block after Info Column',
         'input' => 'select',
     ];
 
@@ -367,14 +361,14 @@ class CatalogProductSimple extends InjectableFixture
         'default_value' => '',
         'input' => 'price',
         'group' => 'product-details',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price',
     ];
 
     protected $quantity_and_stock_status = [
         'attribute_code' => 'quantity_and_stock_status',
         'backend_type' => 'int',
         'is_required' => '0',
-        'default_value' => '',
+        'default_value' => 'In Stock',
         'input' => 'select',
         'group' => 'product-details',
     ];
@@ -395,14 +389,6 @@ class CatalogProductSimple extends InjectableFixture
         'input' => 'text',
     ];
 
-    protected $short_description = [
-        'attribute_code' => 'short_description',
-        'backend_type' => 'text',
-        'is_required' => '0',
-        'default_value' => '',
-        'input' => 'textarea',
-    ];
-
     protected $sku = [
         'attribute_code' => 'sku',
         'backend_type' => 'static',
@@ -436,13 +422,22 @@ class CatalogProductSimple extends InjectableFixture
         'input' => 'date',
     ];
 
+    protected $short_description = [
+        'attribute_code' => 'short_description',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'textarea',
+        'group' => 'autosettings',
+    ];
+
     protected $special_price = [
         'attribute_code' => 'special_price',
         'backend_type' => 'decimal',
         'is_required' => '0',
         'default_value' => '',
         'input' => 'price',
-        'group' => 'advanced-pricing'
+        'group' => 'advanced-pricing',
     ];
 
     protected $special_to_date = [
@@ -457,7 +452,7 @@ class CatalogProductSimple extends InjectableFixture
         'attribute_code' => 'status',
         'backend_type' => 'int',
         'is_required' => '0',
-        'default_value' => '',
+        'default_value' => '1',
         'input' => 'select',
     ];
 
@@ -467,6 +462,7 @@ class CatalogProductSimple extends InjectableFixture
         'is_required' => '0',
         'default_value' => 'Taxable Goods',
         'input' => 'select',
+        'group' => 'product-details',
     ];
 
     protected $thumbnail = [
@@ -492,7 +488,7 @@ class CatalogProductSimple extends InjectableFixture
         'default_value' => '',
         'input' => 'text',
         'group' => 'advanced-pricing',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions',
     ];
 
     protected $updated_at = [
@@ -563,7 +559,7 @@ class CatalogProductSimple extends InjectableFixture
         'backend_type' => 'virtual',
         'is_required' => '0',
         'group' => 'customer-options',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
     ];
 
     public function getCategoryIds()
@@ -611,11 +607,6 @@ class CatalogProductSimple extends InjectableFixture
         return $this->getData('description');
     }
 
-    public function getEnableGooglecheckout()
-    {
-        return $this->getData('enable_googlecheckout');
-    }
-
     public function getGallery()
     {
         return $this->getData('gallery');
@@ -746,11 +737,6 @@ class CatalogProductSimple extends InjectableFixture
         return $this->getData('required_options');
     }
 
-    public function getShortDescription()
-    {
-        return $this->getData('short_description');
-    }
-
     public function getSku()
     {
         return $this->getData('sku');
@@ -771,6 +757,11 @@ class CatalogProductSimple extends InjectableFixture
         return $this->getData('special_from_date');
     }
 
+    public function getShortDescription()
+    {
+        return $this->getData('short_description');
+    }
+
     public function getSpecialPrice()
     {
         return $this->getData('special_price');
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
index 634973de5e923d6a1adbb62301308fe2dd23738f..d0fe5a35c437bf1d863d2170cec692eac5606abb 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
@@ -37,6 +37,7 @@
             <is_required>0</is_required>
             <default_value></default_value>
             <input>text</input>
+            <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds</fixture>
         </category_ids>
         <color>
             <attribute_code>color</attribute_code>
@@ -93,14 +94,8 @@
             <is_required>0</is_required>
             <default_value></default_value>
             <input>textarea</input>
+            <group>product-details</group>
         </description>
-        <enable_googlecheckout>
-            <attribute_code>enable_googlecheckout</attribute_code>
-            <backend_type>int</backend_type>
-            <is_required>0</is_required>
-            <default_value>1</default_value>
-            <input>select</input>
-        </enable_googlecheckout>
         <gallery>
             <attribute_code>gallery</attribute_code>
             <backend_type>varchar</backend_type>
@@ -171,6 +166,7 @@
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
+            <group>search-optimization</group>
             <input>textarea</input>
         </meta_description>
         <meta_keyword>
@@ -178,6 +174,7 @@
             <backend_type>text</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
+            <group>search-optimization</group>
             <input>textarea</input>
         </meta_keyword>
         <meta_title>
@@ -185,6 +182,7 @@
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
+            <group>search-optimization</group>
             <input>text</input>
         </meta_title>
         <minimal_price>
@@ -205,14 +203,14 @@
             <attribute_code>msrp_display_actual_price_type</attribute_code>
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
-            <default_value>4</default_value>
+            <default_value>Use config</default_value>
             <input>select</input>
         </msrp_display_actual_price_type>
         <msrp_enabled>
             <attribute_code>msrp_enabled</attribute_code>
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
-            <default_value>2</default_value>
+            <default_value>In Cart</default_value>
             <input>select</input>
         </msrp_enabled>
         <name>
@@ -221,7 +219,7 @@
             <is_required>1</is_required>
             <default_value></default_value>
             <input>text</input>
-            <group>product_info_tabs_product-details</group>
+            <group>product-details</group>
         </name>
         <news_from_date>
             <attribute_code>news_from_date</attribute_code>
@@ -248,7 +246,7 @@
             <attribute_code>options_container</attribute_code>
             <backend_type>varchar</backend_type>
             <is_required>0</is_required>
-            <default_value>container2</default_value>
+            <default_value>Block after Info Column</default_value>
             <input>select</input>
         </options_container>
         <page_layout>
@@ -264,16 +262,16 @@
             <is_required>1</is_required>
             <default_value></default_value>
             <input>price</input>
-            <group>product_info_tabs_product-details</group>
+            <group>product-details</group>
             <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\Price</fixture>
         </price>
         <quantity_and_stock_status>
             <attribute_code>quantity_and_stock_status</attribute_code>
             <backend_type>int</backend_type>
             <is_required>0</is_required>
-            <default_value>1</default_value>
+            <default_value>In Stock</default_value>
             <input>select</input>
-            <group>product_info_tabs_product-details</group>
+            <group>product-details</group>
         </quantity_and_stock_status>
         <recurring_profile>
             <attribute_code>recurring_profile</attribute_code>
@@ -289,20 +287,13 @@
             <default_value></default_value>
             <input>text</input>
         </required_options>
-        <short_description>
-            <attribute_code>short_description</attribute_code>
-            <backend_type>text</backend_type>
-            <is_required>0</is_required>
-            <default_value></default_value>
-            <input>textarea</input>
-        </short_description>
         <sku>
             <attribute_code>sku</attribute_code>
             <backend_type>static</backend_type>
             <is_required>1</is_required>
             <default_value></default_value>
             <input>text</input>
-            <group>product_info_tabs_product-details</group>
+            <group>product-details</group>
         </sku>
         <small_image>
             <attribute_code>small_image</attribute_code>
@@ -325,6 +316,14 @@
             <default_value></default_value>
             <input>date</input>
         </special_from_date>
+        <short_description>
+            <attribute_code>short_description</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+            <group>autosettings</group>
+        </short_description>
         <special_price>
             <attribute_code>special_price</attribute_code>
             <backend_type>decimal</backend_type>
@@ -351,8 +350,9 @@
             <attribute_code>tax_class_id</attribute_code>
             <backend_type>int</backend_type>
             <is_required>0</is_required>
-            <default_value>2</default_value>
+            <default_value>Taxable Goods</default_value>
             <input>select</input>
+            <group>product-details</group>
         </tax_class_id>
         <thumbnail>
             <attribute_code>thumbnail</attribute_code>
@@ -375,6 +375,7 @@
             <default_value></default_value>
             <input>text</input>
             <group>advanced-pricing</group>
+            <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions</fixture>
         </tier_price>
         <updated_at>
             <attribute_code>updated_at</attribute_code>
@@ -401,7 +402,7 @@
             <attribute_code>visibility</attribute_code>
             <backend_type>int</backend_type>
             <is_required>0</is_required>
-            <default_value>4</default_value>
+            <default_value>Catalog, Search</default_value>
             <input>select</input>
             <group>autosettings</group>
         </visibility>
@@ -411,7 +412,7 @@
             <is_required>0</is_required>
             <default_value></default_value>
             <input>weight</input>
-            <group>product_info_tabs_product-details</group>
+            <group>product-details</group>
         </weight>
         <id>
             <attribute_code>id</attribute_code>
@@ -428,13 +429,14 @@
         <qty>
             <attribute_code>qty</attribute_code>
             <input>input</input>
-            <group>product_info_tabs_product-details</group>
+            <group>product-details</group>
         </qty>
         <custom_options>
             <attribute_code>custom_options</attribute_code>
             <backend_type>virtual</backend_type>
             <group>product_info_tabs_customer_options</group>
             <is_required>0</is_required>
+            <group>customer-options</group>
             <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions</fixture>
         </custom_options>
     </fields>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CategoryIds.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php
similarity index 68%
rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CategoryIds.php
rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php
index ea8ca67823d19a016e9d6dc89786d4d9660af0a4..9c62c829c9565773ab83f4d5e5d161184a260afe 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CategoryIds.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CategoryIds.php
@@ -22,51 +22,57 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Catalog\Test\Fixture;
+namespace Magento\Catalog\Test\Fixture\CatalogProductSimple;
 
+use Magento\Catalog\Test\Fixture\CatalogCategoryEntity;
 use Mtf\Fixture\FixtureFactory;
 use Mtf\Fixture\FixtureInterface;
 
 /**
- * Class Price
- *
- * Data keys:
- *  - preset (Price verification preset name)
- *  - value (Price value)
- *
+ * Class CategoryIds
+ * Create and return Category
  */
 class CategoryIds implements FixtureInterface
 {
     /**
+     * Names and Ids of the created categories
+     *
      * @var array
      */
     protected $data;
 
     /**
-     * @var \Mtf\Fixture\FixtureFactory
-     */
-    protected $fixtureFactory;
-
-    /**
-     * @var Category
+     * New categories
+     *
+     * @var array
      */
     protected $category;
 
     /**
-     * @param Category $category
+     * @param FixtureFactory $fixtureFactory
      * @param array $params
      * @param array $data
      */
-    public function __construct(Category $category, array $params, array $data = [])
-    {
+    public function __construct(
+        FixtureFactory $fixtureFactory,
+        array $params,
+        array $data = []
+    ) {
         $this->params = $params;
         if (isset($data['presets']) && $data['presets'] !== '-') {
             $presets = explode(',', $data['presets']);
             foreach ($presets as $preset) {
-                $category->switchData($preset);
+                $category = $fixtureFactory->createByCode('catalogCategoryEntity', ['dataSet' => $preset]);
                 $category->persist();
-                $this->category = $category;
-                $this->data[] = $category->getCategoryId();
+
+                /** @var CatalogCategoryEntity $category */
+                $this->data = [
+                    [
+                        'id' => $category->getId(),
+                        'name' => $category->getName(),
+                    ],
+                ];
+                $this->category[] = $category;
             }
         }
     }
@@ -95,7 +101,7 @@ class CategoryIds implements FixtureInterface
     /**
      * Return data set configuration settings
      *
-     * @return string
+     * @return array
      */
     public function getDataConfig()
     {
@@ -103,9 +109,9 @@ class CategoryIds implements FixtureInterface
     }
 
     /**
-     * Retrieve source category fixture
+     * Return category array
      *
-     * @return Category
+     * @return array
      */
     public function getCategory()
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CustomOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CustomOptions.php
index c3c74aa45ad1c90cdafdd675eaea4eff50b8d002..7aead4aac117620523c674a96303668cd89d5ae5 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CustomOptions.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/CustomOptions.php
@@ -24,16 +24,15 @@
 
 namespace Magento\Catalog\Test\Fixture\CatalogProductSimple;
 
-use Mtf\Fixture\FixtureFactory;
 use Mtf\Fixture\FixtureInterface;
 
 /**
  * Class CustomOptions
+ * Custom options fixture
  *
  * Data keys:
  *  - preset (Custom options preset name)
  *  - products (comma separated sku identifiers)
- *
  */
 class CustomOptions implements FixtureInterface
 {
@@ -95,7 +94,7 @@ class CustomOptions implements FixtureInterface
             'MAGETWO-23062' => [
                 [
                     'title' => 'custom option drop down',
-                    'is_require' => true,
+                    'is_require' => 'Yes',
                     'type' => 'Drop-down',
                     'options' => [
                         [
@@ -110,7 +109,7 @@ class CustomOptions implements FixtureInterface
             'MAGETWO-23063' => [
                 [
                     'title' => 'custom option drop down',
-                    'is_require' => true,
+                    'is_require' => 'Yes',
                     'type' => 'Drop-down',
                     'options' => [
                         [
@@ -125,7 +124,7 @@ class CustomOptions implements FixtureInterface
             'MAGETWO-23066' => [
                 [
                     'title' => 'custom option drop down',
-                    'is_require' => true,
+                    'is_require' => 'Yes',
                     'type' => 'Drop-down',
                     'options' => [
                         [
@@ -140,7 +139,7 @@ class CustomOptions implements FixtureInterface
             'MAGETWO-23069' => [
                 [
                     'title' => 'custom option drop down',
-                    'is_require' => true,
+                    'is_require' => 'Yes',
                     'type' => 'Drop-down',
                     'options' => [
                         [
@@ -151,6 +150,72 @@ class CustomOptions implements FixtureInterface
                         ]
                     ]
                 ]
+            ],
+            'options-suite' => [
+                [
+                    'title' => 'Test1 option %isolation%',
+                    'is_require' => 'Yes',
+                    'type' => 'Field',
+                    'options' => [
+                        [
+                            'price' => 120.03,
+                            'price_type' => 'Fixed',
+                            'sku' => 'sku1_%isolation%',
+                            'max_characters' => 45
+                        ]
+                    ]
+                ],
+                [
+                    'title' => 'Test2 option %isolation%',
+                    'is_require' => 'Yes',
+                    'type' => 'Field',
+                    'options' => [
+                        [
+                            'price' => 120.03,
+                            'price_type' => 'Fixed',
+                            'sku' => 'sku1_%isolation%',
+                            'max_characters' => 45
+                        ]
+                    ]
+                ],
+                [
+                    'title' => 'Test3 option %isolation%',
+                    'is_require' => 'Yes',
+                    'type' => 'Drop-down',
+                    'options' => [
+                        [
+                            'title' => 'Test1 %isolation%',
+                            'price' => 10.01,
+                            'price_type' => 'Percent',
+                            'sku' => 'sku2_%isolation%'
+                        ],
+                        [
+                            'title' => 'Test2 %isolation%',
+                            'price' => 20.02,
+                            'price_type' => 'Fixed',
+                            'sku' => 'sku3_%isolation%'
+                        ]
+                    ]
+                ],
+                [
+                    'title' => 'Test4 option %isolation%',
+                    'is_require' => 'Yes',
+                    'type' => 'Drop-down',
+                    'options' => [
+                        [
+                            'title' => 'Test1 %isolation%',
+                            'price' => 10.01,
+                            'price_type' => 'Percent',
+                            'sku' => 'sku2_%isolation%'
+                        ],
+                        [
+                            'title' => 'Test2 %isolation%',
+                            'price' => 20.02,
+                            'price_type' => 'Fixed',
+                            'sku' => 'sku3_%isolation%'
+                        ]
+                    ]
+                ]
             ]
         ];
         if (!isset($presets[$name])) {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/GroupPriceOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/GroupPriceOptions.php
index 7319e7cbcecfcc081471d081a19fb725ff85d2ab..38d0010f5228d3bbc826c7a092dfcb91012263b2 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/GroupPriceOptions.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/GroupPriceOptions.php
@@ -87,21 +87,20 @@ class GroupPriceOptions implements FixtureInterface
 
     /**
      * @param string $name
-     * @return mixed
-     * @throws \Exception
+     * @return mixed|null
      */
     protected function getPreset($name)
     {
         $presets = [
             'MAGETWO-23055' => [
-                '0' => [
+                [
                     'price' => 90,
                     'website' => 'All Websites [USD]',
                     'customer_group' => 'NOT LOGGED IN'
                 ]
             ],
             'MAGETWO-23061' => [
-                '0' => [
+                [
                     'price' => 20,
                     'website' => 'All Websites [USD]',
                     'customer_group' => 'NOT LOGGED IN'
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TierPriceOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TierPriceOptions.php
index 2367f6ce970e66599f53c47e885d537fb61c4856..34445ea841fba00286293d12ec1a8e77fcef531b 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TierPriceOptions.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple/TierPriceOptions.php
@@ -24,7 +24,6 @@
 
 namespace Magento\Catalog\Test\Fixture\CatalogProductSimple;
 
-use Mtf\Fixture\FixtureFactory;
 use Mtf\Fixture\FixtureInterface;
 
 /**
@@ -37,11 +36,6 @@ use Mtf\Fixture\FixtureInterface;
  */
 class TierPriceOptions implements FixtureInterface
 {
-    /**
-     * @var \Mtf\Fixture\FixtureFactory
-     */
-    protected $fixtureFactory;
-
     /**
      * @param array $params
      * @param array $data
@@ -87,21 +81,35 @@ class TierPriceOptions implements FixtureInterface
 
     /**
      * @param string $name
-     * @return mixed
-     * @throws \Exception
+     * @return mixed|null
      */
     protected function getPreset($name)
     {
         $presets = [
+            'default' => [
+                0 => [
+                    'price' => 150,
+                    'website' => 'All Websites [USD]',
+                    'price_qty' => 3,
+                    'customer_group' => 'ALL GROUPS'
+                ],
+                1 => [
+                    'price' => 24,
+                    'website' => 'All Websites [USD]',
+                    'price_qty' => 15,
+                    'customer_group' => 'ALL GROUPS'
+                ]
+            ],
             'MAGETWO-23002' => [
-                '0' => [
+                0 => [
                     'price' => 90,
                     'website' => 'All Websites [USD]',
-                    'quantity' => '1',
+                    'price_qty' => 2,
                     'customer_group' => 'ALL GROUPS'
                 ]
             ]
         ];
+
         if (!isset($presets[$name])) {
             return null;
         }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductEdit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/CatalogCategoryEntityInterface.php
old mode 100755
new mode 100644
similarity index 79%
rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductEdit.php
rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/CatalogCategoryEntityInterface.php
index 04202e137db382a76061aa03c982acfb1c8c0bc7..27feac56803da6e35b0514c48d1d30711c739a37
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductEdit.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/CatalogCategoryEntityInterface.php
@@ -22,16 +22,14 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Catalog\Test\Page\Product;
+namespace Magento\Catalog\Test\Handler\CatalogCategoryEntity;
+
+use Mtf\Handler\HandlerInterface;
 
 /**
- * Class CatalogProductEdit
- * Edit product page
+ * Interface CatalogCategoryEntityInterface
  */
-class CatalogProductEdit extends CatalogProductNew
+interface CatalogCategoryEntityInterface extends HandlerInterface
 {
-    /**
-     * URL for product creation
-     */
-    const MCA = 'catalog/product/edit';
+    //
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..f814fe009e5fd0052af9c988d8e880905ca039b4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogCategoryEntity/Curl.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Handler\CatalogCategoryEntity;
+
+use Mtf\System\Config;
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Util\Protocol\CurlInterface;
+use Mtf\Util\Protocol\CurlTransport;
+use Mtf\Handler\Curl as AbstractCurl;
+use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
+
+/**
+ * Class Curl
+ * Create new category via curl
+ */
+class Curl extends AbstractCurl implements CatalogCategoryEntityInterface
+{
+    /**
+     * Data use config for category
+     *
+     * @var array
+     */
+    protected $dataUseConfig = [
+        'available_sort_by',
+        'default_sort_by',
+        'filter_price_range',
+    ];
+
+    /**
+     * Post request for creating Subcategory
+     *
+     * @param FixtureInterface $fixture [optional]
+     * @return mixed|string
+     */
+    public function persist(FixtureInterface $fixture = null)
+    {
+        $data['general'] = $fixture->getData();
+        foreach ($data['general'] as $key => $value) {
+            if ($value == 'Yes') {
+                $data['general'][$key] = 1;
+            }
+            if ($value == 'No') {
+                $data['general'][$key] = 0;
+            }
+        }
+
+        $diff = array_diff($this->dataUseConfig, array_keys($data['general']));
+        if (!empty($diff)) {
+            $data['use_config'] = $diff;
+        }
+        $parentCategoryId = $data['general']['parent_id'];
+
+        $url = $_ENV['app_backend_url'] . 'catalog/category/save/store/0/parent/' . $parentCategoryId . '/';
+        $curl = new BackendDecorator(new CurlTransport(), new Config);
+        $curl->write(CurlInterface::POST, $url, '1.0', array(), $data);
+        $response = $curl->read();
+        $curl->close();
+
+        preg_match('#http://.+/id/(\d+).+store/#m', $response, $matches);
+        $id = isset($matches[1]) ? $matches[1] : null;
+        return ['id' => $id];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php
index e6ba07e209ce8bbdb22e91d3ce175cd279a3fea3..17a11a39c6018e1b8c800fdf4fb077ee47448d93 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php
@@ -27,7 +27,6 @@ use Mtf\Handler\HandlerInterface;
 
 /**
  * Interface CatalogProductSimpleInterface
- *
  */
 interface CatalogProductSimpleInterface extends HandlerInterface
 {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
index 0c22de6fd4ee0a375f8bfc95956f70c48460a2d5..f88ff3ff58e74699d16d81b44022e5529f608cb4 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
@@ -35,6 +35,7 @@ use Mtf\System\Config;
 
 /**
  * Class CreateProduct
+ * Create new simple product via curl
  */
 class Curl extends AbstractCurl implements CatalogProductSimpleInterface
 {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Ui.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Ui.php
index 4e730c38da3aaff5d51e4b0b243f798b9b7c9b12..bbd64bfc12f6025b25d72dfc942b8597a756cde7 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Ui.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Ui.php
@@ -18,21 +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.
  *
- * @spi
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
 namespace Magento\Catalog\Test\Handler\CatalogProductSimple;
 
+use Mtf\Factory\Factory;
 use Mtf\Handler\Ui as AbstractUi;
 use Mtf\Fixture\FixtureInterface;
-use Mtf\Factory\Factory;
 
 /**
  * Class CreateProduct
  * Create a product
- *
  */
 class Ui extends AbstractUi implements CatalogProductSimpleInterface
 {
@@ -50,9 +48,9 @@ class Ui extends AbstractUi implements CatalogProductSimpleInterface
         $createProductPage->init($fixture);
         $createProductPage->open();
 
-        $productBlockForm = $createProductPage->getProductBlockForm();
-        $productBlockForm->fill($fixture);
-        $productBlockForm->save($fixture);
+        $productForm = $createProductPage->getProductForm();
+        $productForm->fill($fixture);
+        $createProductPage->getFormAction()->save();
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Ui/CreateProduct.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Ui/CreateProduct.php
index 5f35313e3c4d13f9c4b7949d2495a28937ea1555..e90e178902b60e3cc3d5a722f2cf9c5778c27791 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Ui/CreateProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/Ui/CreateProduct.php
@@ -18,21 +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.
  *
- * @spi
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
 namespace Magento\Catalog\Test\Handler\Ui;
 
-use Mtf\Fixture\FixtureInterface;
 use Mtf\Handler\Ui;
 use Mtf\Factory\Factory;
+use Mtf\Fixture\FixtureInterface;
 
 /**
  * Class CreateProduct
  * Create a product
- *
  */
 class CreateProduct extends Ui
 {
@@ -50,9 +48,9 @@ class CreateProduct extends Ui
         $createProductPage->init($fixture);
         $createProductPage->open();
 
-        $productBlockForm = $createProductPage->getProductBlockForm();
-        $productBlockForm->fill($fixture);
-        $productBlockForm->save($fixture);
+        $productForm = $createProductPage->getProductForm();
+        $productForm->fill($fixture);
+        $createProductPage->getFormAction()->save();
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f90fb29492d0ad33c34b3c979ae2b6affaa0fc6
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class CatalogCategoryIndex
+ * Category page on the Backend
+ */
+class CatalogCategoryIndex extends BackendPage
+{
+    const MCA = 'catalog/category/index/index'; // TODO: Fix after resolving issue with factory page generation
+
+    protected $_blocks = [
+        'treeCategories' => [
+            'name' => 'treeCategories',
+            'class' => 'Magento\Catalog\Test\Block\Adminhtml\Category\Tree',
+            'locator' => '[id="page:left"]',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Adminhtml\Category\Tree
+     */
+    public function getTreeCategories()
+    {
+        return $this->getBlockInstance('treeCategories');
+    }
+}
diff --git a/app/code/Magento/Persistent/view/frontend/js/components.phtml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.xml
similarity index 68%
rename from app/code/Magento/Persistent/view/frontend/js/components.phtml
rename to dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.xml
index 941db16146d1f6a33e7ffb817fd8e2d32e4b6029..d292e92a93c3557b86b618f716e9dd800615231e 100644
--- a/app/code/Magento/Persistent/view/frontend/js/components.phtml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogCategoryIndex.xml
@@ -1,4 +1,5 @@
-<?php
+<?xml version="1.0" ?>
+<!--
 /**
  * Magento
  *
@@ -21,18 +22,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-?>
-<script type="text/javascript">
-    (function($) {
-        "use strict";
-        /**
-         * Declaration of resources needed for defined components
-         */
-        $.mage.component({
-            rememberMePopup: [
-                '<?php echo $this->getViewFileUrl('Magento_Persistent::remember-me-popup.js')?>'
-            ]
-        });
-    })(jQuery);
-</script>
-<?php echo $this->getChildHtml() ?>
+-->
+<page mca="catalog/category/index">
+    <block>
+        <name>treeCategories</name>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Category\Tree</class>
+        <locator>[id="page:left"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b8c8adce318e20a426a802dfb74d0308ffa7711
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class CatalogProductEdit
+ */
+class CatalogProductEdit extends BackendPage
+{
+    const MCA = 'catalog/product/edit';
+
+    protected $_blocks = [
+        'form' => [
+            'name' => 'form',
+            'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\Form',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+        'productForm' => [
+            'name' => 'productForm',
+            'class' => 'Magento\Catalog\Test\Block\Backend\ProductForm',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+        'configurableProductForm' => [
+            'name' => 'configurableProductForm',
+            'class' => 'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+        'formAction' => [
+            'name' => 'formAction',
+            'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages .messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Backend\ProductForm
+     */
+    public function getProductForm()
+    {
+        return $this->getBlockInstance('productForm');
+    }
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Form
+     */
+    public function getForm()
+    {
+        return $this->getBlockInstance('form');
+    }
+
+    /**
+     * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm
+     */
+    public function getConfigurableProductForm()
+    {
+        return $this->getBlockInstance('configurableProductForm');
+    }
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions
+     */
+    public function getFormAction()
+    {
+        return $this->getBlockInstance('formAction');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e4817fb8507618ddc2e6808f41f433c5afb53821
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductEdit.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="catalog/product/edit" >
+    <block>
+        <name>form</name>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Product\Form</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>productForm</name>
+        <class>Magento\Catalog\Test\Block\Backend\ProductForm</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>configurableProductForm</name>
+        <class>Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>formAction</name>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages .messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.php
index c4f5e80a6e89d43ef497b1d826a3cd6d5f378663..8513d19dc21d89c9a44a58ecd87fa1351fc38eb2 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.php
@@ -28,7 +28,7 @@ use Mtf\Page\BackendPage;
 
 /**
  * Class CatalogProductIndex
- *
+ * Products page on the Backend
  */
 class CatalogProductIndex extends BackendPage
 {
@@ -37,12 +37,12 @@ class CatalogProductIndex extends BackendPage
     protected $_blocks = [
         'productGrid' => [
             'name' => 'productGrid',
-            'class' => 'Magento\Catalog\Test\Block\Backend\ProductGrid',
+            'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\Grid',
             'locator' => '#productGrid',
             'strategy' => 'css selector',
         ],
-        'messageBlock' => [
-            'name' => 'messageBlock',
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
             'class' => 'Magento\Core\Test\Block\Messages',
             'locator' => '#messages',
             'strategy' => 'css selector',
@@ -68,7 +68,7 @@ class CatalogProductIndex extends BackendPage
     ];
 
     /**
-     * @return \Magento\Catalog\Test\Block\Backend\ProductGrid
+     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Grid
      */
     public function getProductGrid()
     {
@@ -78,9 +78,9 @@ class CatalogProductIndex extends BackendPage
     /**
      * @return \Magento\Core\Test\Block\Messages
      */
-    public function getMessageBlock()
+    public function getMessagesBlock()
     {
-        return $this->getBlockInstance('messageBlock');
+        return $this->getBlockInstance('messagesBlock');
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml
index c1e62e819fe1a105e3e36db40dfb2050b8706065..b5c18b67a09443a40f373f49acabdbf36b6ef7c1 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductIndex.xml
@@ -26,12 +26,12 @@
 <page mca="catalog/product/index" >
     <block>
         <name>productGrid</name>
-        <class>Magento\Catalog\Test\Block\Backend\ProductGrid</class>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Product\Grid</class>
         <locator>#productGrid</locator>
         <strategy>css selector</strategy>
     </block>
     <block>
-        <name>messageBlock</name>
+        <name>messagesBlock</name>
         <class>Magento\Core\Test\Block\Messages</class>
         <locator>#messages</locator>
         <strategy>css selector</strategy>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.php
new file mode 100644
index 0000000000000000000000000000000000000000..18ce4f877aa34ea51f37326cd7cc50cfbae48f87
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+use Mtf\Fixture\FixtureInterface;
+
+/**
+ * Class CatalogProductNew
+ */
+class CatalogProductNew extends BackendPage
+{
+    const MCA = 'catalog/product/new';
+
+    protected $_blocks = [
+        'form' => [
+            'name' => 'form',
+            'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\Form',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+        'productForm' => [
+            'name' => 'productForm',
+            'class' => 'Magento\Catalog\Test\Block\Backend\ProductForm',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+        'configurableProductForm' => [
+            'name' => 'configurableProductForm',
+            'class' => 'Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm',
+            'locator' => 'body',
+            'strategy' => 'css selector',
+        ],
+        'formAction' => [
+            'name' => 'formAction',
+            'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'affectedAttributeSetForm' => [
+            'name' => 'affectedAttributeSetForm',
+            'class' => 'Magento\Catalog\Test\Block\Adminhtml\Product\AffectedAttributeSetForm',
+            'locator' => '#affected-attribute-set-form',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages .messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * Custom constructor
+     */
+    protected function _init()
+    {
+        $this->_url = $_ENV['app_backend_url'] . static::MCA;
+    }
+
+    /**
+     *
+     * @param FixtureInterface $fixture
+     */
+    public function init(FixtureInterface $fixture)
+    {
+        $dataConfig = $fixture->getDataConfig();
+
+        $params = isset($dataConfig['create_url_params']) ? $dataConfig['create_url_params'] : array();
+        foreach ($params as $paramName => $paramValue) {
+            $this->_url .= '/' . $paramName . '/' . $paramValue;
+        }
+    }
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Backend\ProductForm
+     */
+    public function getProductForm()
+    {
+        return $this->getBlockInstance('productForm');
+    }
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Form
+     */
+    public function getForm()
+    {
+        return $this->getBlockInstance('form');
+    }
+
+    /**
+     * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm
+     */
+    public function getConfigurableProductForm()
+    {
+        return $this->getBlockInstance('configurableProductForm');
+    }
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions
+     */
+    public function getFormAction()
+    {
+        return $this->getBlockInstance('formAction');
+    }
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\AffectedAttributeSetForm
+     */
+    public function getAffectedAttributeSetForm()
+    {
+        return $this->getBlockInstance('affectedAttributeSetForm');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+
+    /**
+     * Switch back to main page from iframe
+     */
+    public function switchToMainPage()
+    {
+        $this->_browser->switchToFrame();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a9b7418dceb49fbf3bbb2f2e6081a4bd9f45ec5c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Adminhtml/CatalogProductNew.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="catalog/product/new" >
+    <block>
+        <name>form</name>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Product\Form</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>productForm</name>
+        <class>Magento\Catalog\Test\Block\Backend\ProductForm</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>configurableProductForm</name>
+        <class>Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>formAction</name>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Product\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>affectedAttributeSetForm</name>
+        <class>Magento\Catalog\Test\Block\Adminhtml\Product\AffectedAttributeSetForm</class>
+        <locator>#affected-attribute-set-form</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages .messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategory.php
index 0632320983ec3dd7b766790a958aad1f0edd0a3b..168a44778ccb6acc05e8d9f9576c8842b10e3476 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategory.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategory.php
@@ -59,7 +59,7 @@ class CatalogCategory extends Page
      *
      * @var string
      */
-    protected $messageBlock = '#messages .messages';
+    protected $messagesBlock = '#messages .messages';
 
     /**
      * Backend abstract block
@@ -118,10 +118,10 @@ class CatalogCategory extends Page
      *
      * @return \Magento\Core\Test\Block\Messages
      */
-    public function getMessageBlock()
+    public function getMessagesBlock()
     {
         return Factory::getBlockFactory()->getMagentoCoreMessages(
-            $this->_browser->find($this->messageBlock, Locator::SELECTOR_CSS)
+            $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS)
         );
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryEdit.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryEdit.php
index 94ddb2661bae22b3138c8ce9738b2438871f74e2..3dc39db826d97bd342ef86dc6c6d6cc60b53eb5e 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryEdit.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryEdit.php
@@ -60,7 +60,7 @@ class CatalogCategoryEdit extends Page
      *
      * @var string
      */
-    protected $messageBlock = '#messages .messages';
+    protected $messagesBlock = '#messages .messages';
 
     /**
      * Backend abstract block
@@ -126,10 +126,10 @@ class CatalogCategoryEdit extends Page
      *
      * @return \Magento\Core\Test\Block\Messages
      */
-    public function getMessageBlock()
+    public function getMessagesBlock()
     {
         return Factory::getBlockFactory()->getMagentoCoreMessages(
-            $this->_browser->find($this->messageBlock, Locator::SELECTOR_CSS)
+            $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS)
         );
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.php
index 0110e2280afc89496b3cc40bfd9ba3f86e1e5d5e..d0376a8e0f048e35d5e0a2856aa64136f30d561a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.php
@@ -24,84 +24,72 @@
 
 namespace Magento\Catalog\Test\Page\Category;
 
-use Mtf\Client\Element\Locator;
-use Mtf\Factory\Factory;
-use Mtf\Page\Page;
+use Mtf\Page\FrontendPage;
 
 /**
  * Class CatalogCategoryView
- * Category page on frontend
- *
+ * Catalog Category page
  */
-class CatalogCategoryView extends Page
+class CatalogCategoryView extends FrontendPage
 {
-    /**
-     * URL for category page
-     */
     const MCA = 'catalog/category/view';
 
-    /**
-     * List of results of product search
-     *
-     * @var string
-     */
-    protected $listProductBlock = '.products.wrapper.grid';
-
-    /**
-     * MAP popup
-     *
-     * @var string
-     */
-    protected $mapBlock = '#map-popup-content';
-
-    /**
-     * Layered navigation block
-     *
-     * @var string
-     */
-    protected $layeredNavigationBlock = '.block.filter';
+    protected $_blocks = [
+        'listProductBlock' => [
+            'name' => 'listProductBlock',
+            'class' => 'Magento\Catalog\Test\Block\Product\ListProduct',
+            'locator' => '.products.wrapper.grid',
+            'strategy' => 'css selector',
+        ],
+        'mapBlock' => [
+            'name' => 'mapBlock',
+            'class' => 'Magento\Catalog\Test\Block\Product\Price',
+            'locator' => '#map-popup-content',
+            'strategy' => 'css selector',
+        ],
+        'layeredNavigationBlock' => [
+            'name' => 'layeredNavigationBlock',
+            'class' => 'Magento\LayeredNavigation\Test\Block\Navigation',
+            'locator' => '.block.filter',
+            'strategy' => 'css selector',
+        ],
+        'toolbar' => [
+            'name' => 'toolbar',
+            'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Toolbar',
+            'locator' => '.pages .items',
+            'strategy' => 'css selector',
+        ],
+    ];
 
     /**
-     * Custom constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_frontend_url'] . self::MCA;
-    }
-
-    /**
-     * Get product list block
-     *
      * @return \Magento\Catalog\Test\Block\Product\ListProduct
      */
     public function getListProductBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductListProduct(
-            $this->_browser->find($this->listProductBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('listProductBlock');
     }
 
     /**
-     * Get product price block
-     *
      * @return \Magento\Catalog\Test\Block\Product\Price
      */
     public function getMapBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductPrice(
-            $this->_browser->find($this->mapBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('mapBlock');
     }
 
     /**
-     * Get layered navigation block
-     *
-     * @return \Magento\Search\Test\Block\Catalog\Layer\View
+     * @return \Magento\LayeredNavigation\Test\Block\Navigation
      */
     public function getLayeredNavigationBlock()
     {
-        return Factory::getBlockFactory()->getMagentoSearchCatalogLayerView(
-            $this->_browser->find($this->layeredNavigationBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('layeredNavigationBlock');
+    }
+
+    /**
+     * @return \Magento\Catalog\Test\Block\Product\ProductList\Toolbar
+     */
+    public function getToolbar()
+    {
+        return $this->getBlockInstance('toolbar');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml
new file mode 100644
index 0000000000000000000000000000000000000000..659960ed355e0f155dfc83f202d60cc06ba32fe0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Category/CatalogCategoryView.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="catalog/category/view" >
+    <block>
+        <name>listProductBlock</name>
+        <class>Magento\Catalog\Test\Block\Product\ListProduct</class>
+        <locator>.products.wrapper.grid</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>mapBlock</name>
+        <class>Magento\Catalog\Test\Block\Product\Price</class>
+        <locator>#map-popup-content</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>layeredNavigationBlock</name>
+        <class>Magento\LayeredNavigation\Test\Block\Navigation</class>
+        <locator>.block.filter</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>toolbar</name>
+        <class>\Magento\Catalog\Test\Block\Product\ProductList\Toolbar</class>
+        <locator>.pages .items</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductNew.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductNew.php
deleted file mode 100644
index 75e58fa2993586804aed5a6b16598b6e89c66a66..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductNew.php
+++ /dev/null
@@ -1,173 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Catalog\Test\Page\Product;
-
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
-use Mtf\Fixture\FixtureInterface;
-use Mtf\Client\Element\Locator;
-
-/**
- * Class CatalogProductNew
- * Create product page
- *
- */
-class CatalogProductNew extends Page
-{
-    /**
-     * URL for product creation
-     */
-    const MCA = 'catalog/product/new';
-
-    /**
-     * New attribute selector
-     *
-     * @var string
-     */
-    protected $newAttribute = 'body';
-
-    /**
-     * New attribute frame selector
-     *
-     * @var string
-     */
-    protected $newAttributeFrame = '#create_new_attribute_container';
-
-    /**
-     * Product form block
-     *
-     * @var string
-     */
-    protected $productFormBlock = 'body';
-
-    /**
-     * Global messages block
-     *
-     * @var string
-     */
-    protected $messagesBlock = '#messages .messages';
-
-    /**
-     * Custom constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_backend_url'] . static::MCA;
-    }
-
-    /**
-     * @param FixtureInterface $fixture
-     */
-    public function init(FixtureInterface $fixture)
-    {
-        $dataConfig = $fixture->getDataConfig();
-
-        $params = isset($dataConfig['create_url_params']) ? $dataConfig['create_url_params'] : array();
-        foreach ($params as $paramName => $paramValue) {
-            $this->_url .= '/' . $paramName . '/' . $paramValue;
-        }
-    }
-
-    /**
-     * Get product form block
-     *
-     * @return \Magento\Catalog\Test\Block\Backend\ProductForm
-     */
-    public function getProductBlockForm()
-    {
-        return Factory::getBlockFactory()->getMagentoCatalogBackendProductForm(
-            $this->_browser->find($this->productFormBlock, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get product form block
-     *
-     * @return \Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\ProductForm
-     */
-    public function getConfigurableBlockForm()
-    {
-        return Factory::getBlockFactory()->getMagentoConfigurableProductAdminhtmlProductProductForm(
-            $this->_browser->find($this->productFormBlock, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get global messages block
-     *
-     * @return \Magento\Core\Test\Block\Messages
-     */
-    public function getMessagesBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCoreMessages(
-            $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get attribute edit block
-     *
-     * @return \Magento\Catalog\Test\Block\Backend\Product\Attribute\Edit
-     */
-    public function getAttributeEditBlock()
-    {
-        $this->_browser->switchToFrame(new Locator($this->newAttributeFrame));
-        return Factory::getBlockFactory()->getMagentoCatalogBackendProductAttributeEdit(
-            $this->_browser->find($this->newAttribute, Locator::SELECTOR_TAG_NAME)
-        );
-    }
-
-    /**
-     * Switch back to main page from iframe
-     */
-    public function switchToMainPage()
-    {
-        $this->_browser->switchToFrame();
-    }
-
-    /**
-     * Get upsell block
-     *
-     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Upsell
-     */
-    public function getUpsellBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCatalogAdminhtmlProductEditTabUpsell(
-            $this->_browser->find('up_sell_product_grid', Locator::SELECTOR_ID)
-        );
-    }
-
-    /**
-     * Get the backend catalog product block
-     *
-     * @return \Magento\Catalog\Test\Block\Adminhtml\Product\Edit\Tab\Related
-     */
-    public function getRelatedBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCatalogAdminhtmlProductEditTabRelated(
-            $this->_browser->find('related_product_grid', Locator::SELECTOR_ID)
-        );
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php
index 89aea218d17fabb10f8087993dcc6991e8a9813e..a6e377dee180bb8ff9052050bdc77f49c4f4437d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php
@@ -93,7 +93,7 @@ class CatalogProductReview extends Page
      *
      * @return \Magento\Core\Test\Block\Messages
      */
-    public function getMessageBlock()
+    public function getMessagesBlock()
     {
         return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messageWrapperSelector));
     }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php
index 9a8a91f830004d7e06accadbe7bb9aecf5ae3243..3ed4bb16f8448df85939b1771acd294207cbe178 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php
@@ -24,126 +24,90 @@
 
 namespace Magento\Catalog\Test\Page\Product;
 
-use Magento\GiftCard\Test\Block\Catalog\Product\View\Type\GiftCard;
-use Magento\Catalog\Test\Block\Product\ProductList\Crosssell;
-use Magento\Catalog\Test\Block\Product\Price;
-use Magento\Catalog\Test\Block\Product\ProductList\Related;
-use Magento\Catalog\Test\Block\Product\ProductList\Upsell;
-use Magento\Catalog\Test\Block\Product\View;
-use Magento\Catalog\Test\Block\Product\View\Options;
-use Magento\Catalog\Test\Block\Product\View\CustomOptions;
-use Magento\Downloadable\Test\Block\Catalog\Product\Links;
-use Magento\Review\Test\Block\Product\View\Summary;
-use Magento\Review\Test\Block\Form;
-use Magento\Review\Test\Block\Product\View as ReviewView;
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
+use Mtf\Page\FrontendPage;
 use Mtf\Fixture\FixtureInterface;
-use Mtf\Client\Element\Locator;
 
 /**
  * Class CatalogProductView
  * Frontend product view page
- *
  */
-class CatalogProductView extends Page
+class CatalogProductView extends FrontendPage
 {
-    /**
-     * URL for catalog product grid
-     */
     const MCA = 'catalog/product/view';
 
-    /**
-     * Review summary selector
-     *
-     * @var string
-     */
-    protected $reviewSummarySelector = '.product.reviews.summary';
-
-    /**
-     * Review form
-     *
-     * @var string
-     */
-    protected $reviewFormBlock = '#review-form';
-
-    /**
-     * Customer reviews block
-     *
-     * @var string
-     */
-    protected $customerReviewBlock = '#customer-reviews';
-
-    /**
-     * Messages selector
-     *
-     * @var string
-     */
-    protected $messagesSelector = '.page.messages .messages';
-
-    /**
-     * Product View block
-     *
-     * @var string
-     */
-    protected $viewBlock = '.column.main';
-
-    /**
-     * Product options block
-     *
-     * @var string
-     */
-    protected $optionsBlock = '#product-options-wrapper';
-
-    /**
-     * Related product selector
-     *
-     * @var string
-     */
-    protected $relatedProductSelector = '.block.related';
-
-    /**
-     * Upsell selector
-     *
-     * @var string
-     */
-    protected $upsellSelector = '.block.upsell';
-
-    /**
-     * Gift Card Block selector
-     *
-     * @var string
-     */
-    protected $giftCardBlockSelector = '[data-container-for=giftcard_info]';
-
-    /**
-     * Gift Card Amount Block selector
-     *
-     * @var string
-     */
-    protected $giftCardBlockAmountSelector = '.fieldset.giftcard.amount';
-
-    /**
-     * Cross-sell selector
-     *
-     * @var string
-     */
-    protected $crosssellSelector = '.block.crosssell';
-
-    /**
-     * @var string
-     */
-    protected $downloadableLinksSelector = '[data-container-for=downloadable-links]';
-
-    /**
-     * MAP popup
-     *
-     * @var string
-     */
-    protected $mapBlock = '#map-popup';
+    protected $_blocks = [
+        'viewBlock' => [
+            'name' => 'viewBlock',
+            'class' => 'Magento\Catalog\Test\Block\Product\View',
+            'locator' => '#maincontent',
+            'strategy' => 'css selector',
+        ],
+        'customOptionsBlock' => [
+            'name' => 'customOptionsBlock',
+            'class' => 'Magento\Catalog\Test\Block\Product\View\CustomOptions',
+            'locator' => '#product-options-wrapper',
+            'strategy' => 'css selector',
+        ],
+        'relatedProductBlock' => [
+            'name' => 'relatedProductBlock',
+            'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Related',
+            'locator' => '.block.related',
+            'strategy' => 'css selector',
+        ],
+        'upsellBlock' => [
+            'name' => 'upsellBlock',
+            'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Upsell',
+            'locator' => '.block.upsell',
+            'strategy' => 'css selector',
+        ],
+        'crosssellBlock' => [
+            'name' => 'crosssellBlock',
+            'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Crosssell',
+            'locator' => '.block.crosssell',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '.page.messages .messages',
+            'strategy' => 'css selector',
+        ],
+        'reviewSummary' => [
+            'name' => 'reviewSummary',
+            'class' => 'Magento\Review\Test\Block\Product\View\Summary',
+            'locator' => '.product.reviews.summary',
+            'strategy' => 'css selector',
+        ],
+        'reviewFormBlock' => [
+            'name' => 'reviewFormBlock',
+            'class' => 'Magento\Review\Test\Block\Form',
+            'locator' => '#review-form',
+            'strategy' => 'css selector',
+        ],
+        'customerReviewBlock' => [
+            'name' => 'customerReviewBlock',
+            'class' => 'Magento\Review\Test\Block\Product\View',
+            'locator' => '#customer-reviews',
+            'strategy' => 'css selector',
+        ],
+        'downloadableLinksBlock' => [
+            'name' => 'downloadableLinksBlock',
+            'class' => 'Magento\Downloadable\Test\Block\Catalog\Product\Links',
+            'locator' => '[data-container-for=downloadable-links]',
+            'strategy' => 'css selector',
+        ],
+        'mapBlock' => [
+            'name' => 'mapBlock',
+            'class' => 'Magento\Catalog\Test\Block\Product\Price',
+            'locator' => '#map-popup',
+            'strategy' => 'css selector',
+        ]
+    ];
 
     /**
      * Custom constructor
+     *
+     * @return void
      */
     protected function _init()
     {
@@ -154,6 +118,7 @@ class CatalogProductView extends Page
      * Page initialization
      *
      * @param FixtureInterface $fixture
+     * @return void
      */
     public function init(FixtureInterface $fixture)
     {
@@ -161,166 +126,90 @@ class CatalogProductView extends Page
     }
 
     /**
-     * Get product view block
-     *
-     * @return View
+     * @return \Magento\Catalog\Test\Block\Product\View
      */
     public function getViewBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductView(
-            $this->_browser->find($this->viewBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('viewBlock');
     }
 
     /**
-     * Get product options block
-     *
-     * @return View
+     * @return \Magento\Catalog\Test\Block\Product\View\CustomOptions
      */
-    public function getOptionsBlock()
+    public function getCustomOptionsBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductViewOptions(
-            $this->_browser->find($this->optionsBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('customOptionsBlock');
     }
 
     /**
-     * Get product options block
-     *
-     * @return Options
+     * @return \Magento\Catalog\Test\Block\Product\ProductList\Related
      */
-    public function getCustomOptionBlock()
+    public function getRelatedProductBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductViewCustomOptions(
-            $this->_browser->find('#product-options-wrapper')
-        );
+        return $this->getBlockInstance('relatedProductBlock');
     }
 
     /**
-     * Get customer reviews block
-     *
-     * @return CustomOptions
+     * @return \Magento\Review\Test\Block\Form
      */
     public function getReviewFormBlock()
     {
-        return Factory::getBlockFactory()->getMagentoReviewForm($this->_browser->find($this->reviewFormBlock));
+        return $this->getBlockInstance('reviewFormBlock');
     }
 
     /**
-     * Get customer reviews block
-     *
-     * @return Form
+     * @return \Magento\Review\Test\Block\Product\View
      */
     public function getCustomerReviewBlock()
     {
-        return Factory::getBlockFactory()->getMagentoReviewProductView(
-            $this->_browser->find($this->customerReviewBlock)
-        );
+        return $this->getBlockInstance('customerReviewBlock');
     }
 
     /**
-     * Get review summary block
-     *
-     * @return ReviewView
-     */
-    public function getReviewSummaryBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoReviewProductViewSummary(
-            $this->_browser->find($this->reviewSummarySelector, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get upsell block
-     *
-     * @return Summary
+     * @return \Magento\Core\Test\Block\Messages
      */
-    public function getUpsellProductBlock()
+    public function getMessagesBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductProductListUpsell(
-            $this->_browser->find($this->upsellSelector, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('messagesBlock');
     }
 
     /**
-     * Get messages block
-     *
-     * @return Upsell
+     * @return \Magento\Review\Test\Block\Product\View\Summary
      */
-    public function getMessagesBlock()
+    public function getReviewSummaryBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCoreMessages(
-            $this->_browser->find($this->messagesSelector, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('reviewSummary');
     }
 
     /**
-     * Get related product block
-     *
-     * @return GiftCard
+     * @return \Magento\Catalog\Test\Block\Product\ProductList\Upsell
      */
-    public function getRelatedProductBlock()
+    public function getUpsellBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductProductListRelated(
-            $this->_browser->find($this->relatedProductSelector, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('upsellBlock');
     }
 
     /**
-     * Get gift card options block
-     *
-     * @return Related
+     * @return \Magento\Catalog\Test\Block\Product\ProductList\Crosssell
      */
-    public function getGiftCardBlock()
+    public function getCrosssellBlock()
     {
-        return Factory::getBlockFactory()->getMagentoGiftCardCatalogProductViewTypeGiftCard(
-            $this->_browser->find($this->giftCardBlockSelector, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('crosssellBlock');
     }
 
     /**
-     * @return Links
+     * @return \Magento\Downloadable\Test\Block\Catalog\Product\Links
      */
     public function getDownloadableLinksBlock()
     {
-        return Factory::getBlockFactory()->getMagentoDownloadableCatalogProductLinks(
-            $this->_browser->find($this->downloadableLinksSelector)
-        );
+        return $this->getBlockInstance('downloadableLinksBlock');
     }
 
     /**
-     * Get product price block
-     *
-     * @return Price
+     * @return \Magento\Catalog\Test\Block\Product\Price
      */
     public function getMapBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductPrice(
-            $this->_browser->find($this->mapBlock, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Retrieve cross-sell block
-     *
-     * @return Crosssell
-     */
-    public function getCrosssellBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCatalogProductProductListCrosssell(
-            $this->_browser->find($this->crosssellSelector, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get gift card amount block
-     *
-     * @return GiftCard
-     */
-    public function getGiftCardAmountBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoGiftCardCatalogProductViewTypeGiftCard(
-            $this->_browser->find($this->giftCardBlockAmountSelector, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('mapBlock');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dc483885bca92c98f50f24239f29fc2ed76a41a4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="catalog/product/view">
+    <block>
+        <name>viewBlock</name>
+        <class>Magento\Catalog\Test\Block\Product\View</class>
+        <locator>#maincontent</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>customOptionsBlock</name>
+        <class>Magento\Catalog\Test\Block\Product\View\CustomOptions</class>
+        <locator>#product-options-wrapper</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>relatedProductBlock</name>
+        <class>Magento\Catalog\Test\Block\Product\ProductList\Related</class>
+        <locator>.block.related</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>upsellBlock</name>
+        <class>Magento\Catalog\Test\Block\Product\ProductList\Upsell</class>
+        <locator>.block.upsell</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>crosssellBlock</name>
+        <class>Magento\Catalog\Test\Block\Product\ProductList\Crosssell</class>
+        <locator>.block.crosssell</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>downloadableLinksBlock</name>
+        <class>Magento\Downloadable\Test\Block\Catalog\Product\Links</class>
+        <locator>[data-container-for=downloadable-links]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>mapBlock</name>
+        <class>Magento\Catalog\Test\Block\Product\Price</class>
+        <locator>#map-popup</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>.page.messages .messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>reviewSummary</name>
+        <class>Magento\Review\Test\Block\Product\View\Summary</class>
+        <locator>.product.reviews.summary</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>customerReviewBlock</name>
+        <class>Magento\Review\Test\Block\Product\View</class>
+        <locator>#customer-reviews</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>reviewFormBlock</name>
+        <class>Magento\Review\Test\Block\Form</class>
+        <locator>#review-form</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategoryEntity.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategoryEntity.php
new file mode 100644
index 0000000000000000000000000000000000000000..d46e139e67524016e90d71a20a7f5124dd0d0f0f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategoryEntity.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Repository;
+
+use Mtf\Repository\AbstractRepository;
+
+/**
+ * Class CatalogCategoryEntity
+ * Data for creation Category
+ */
+class CatalogCategoryEntity extends AbstractRepository
+{
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
+    {
+        $this->_data['default_subcategory'] = [
+            'name' => 'Subcategory%isolation%',
+            'path' => 'Default Category',
+            'parent_id' => 2,
+            'is_active' => 'Yes',
+            'include_in_menu' => 'Yes',
+        ];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
index adce7b1b968c6d8bbc37e3391a8e5e434f8f1f5a..c07b521f749c54a64eca45af2681f3b905c63160 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
@@ -28,7 +28,7 @@ use Mtf\Repository\AbstractRepository;
 
 /**
  * Class CatalogProductSimple
- *
+ * Data for creation Catalog Product Simple
  */
 class CatalogProductSimple extends AbstractRepository
 {
@@ -55,13 +55,11 @@ class CatalogProductSimple extends AbstractRepository
         ];
 
         $this->_data['100_dollar_product'] = [
-            'sku' => '100_dollar_product',
-            'name' => '100_dollar_product',
+            'sku' => '100_dollar_product%isolation%',
+            'name' => '100_dollar_product%isolation%',
             'type_id' => 'simple',
             'attribute_set_id' => '4',
             'price' => ['value' => 100, 'preset' => '-'],
-            'id' => '2',
-            'mtf_dataset_name' => '100_dollar_product'
         ];
 
         $this->_data['40_dollar_product'] = [
@@ -82,7 +80,16 @@ class CatalogProductSimple extends AbstractRepository
             'price' => ['value' => 100, 'preset' => 'MAGETWO-23036'],
             'id' => '3',
             'category_ids' => ['presets' => 'default'],
-            'mtf_dataset_name' => 'simple_with_category',
+            'mtf_dataset_name' => 'simple_with_category'
+        ];
+
+        $this->_data['product_with_category'] = [
+            'sku' => 'simple_product_with_category_%isolation%',
+            'name' => 'Simple product with category %isolation%',
+            'type_id' => 'simple',
+            'attribute_set_id' => '4',
+            'price' => ['value' => 100, 'preset' => ''],
+            'category_ids' => ['presets' => 'default_subcategory']
         ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php
index 19f43d8217b760efe05781227ad273c08e22a31a..06d357e7ee368b494589056e9ba9978714be95f1 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/AssignProductTest.php
@@ -59,7 +59,7 @@ class AssignProductTest extends Functional
         $catalogCategoryEditPage = Factory::getPageFactory()->getCatalogCategoryEditId();
         $treeBlock = $catalogCategoryPage->getTreeBlock();
         $formBlock = $catalogCategoryPage->getFormBlock();
-        $messageBlock = $catalogCategoryPage->getMessageBlock();
+        $messagesBlock = $catalogCategoryPage->getMessagesBlock();
         $actionsBlock = $catalogCategoryEditPage->getPageActionsBlock();
         //Steps
         Factory::getApp()->magentoBackendLoginUser();
@@ -73,7 +73,7 @@ class AssignProductTest extends Functional
             $categoryProductsGrid->searchAndSelect(['sku' => $product->getProductSku()]);
         }
         $actionsBlock->save();
-        $messageBlock->assertSuccessMessage();
+        $messagesBlock->assertSuccessMessage();
         //Clean Cache
         $cachePage = Factory::getPageFactory()->getAdminCache();
         $cachePage->open();
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateTest.php
index daebae20ca7ce0780c6f5501b246eb3757ae88d7..0e1da3da5f99ee506731258b0e7b6ad5cb8e476f 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateTest.php
@@ -52,7 +52,7 @@ class CreateTest extends Functional
         $treeBlockEdit = $catalogCategoryEditPage->getTreeBlock();
         $formBlock = $catalogCategoryEditPage->getFormBlock();
         $actionsBlock = $catalogCategoryEditPage->getPageActionsBlock();
-        $messageBlock = $catalogCategoryEditPage->getMessageBlock();
+        $messagesBlock = $catalogCategoryEditPage->getMessagesBlock();
         //Steps
         Factory::getApp()->magentoBackendLoginUser();
         $catalogCategoryPage->open();
@@ -61,7 +61,7 @@ class CreateTest extends Functional
         $formBlock->fill($category);
         $actionsBlock->save();
         //Verifying
-        $messageBlock->assertSuccessMessage();
+        $messagesBlock->assertSuccessMessage();
         //Flush cache
         $cachePage = Factory::getPageFactory()->getAdminCache();
         $cachePage->open();
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/CreateWithAttributeTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/CreateWithAttributeTest.php
index f8dc029048054c75a79a1d689aa62c5eaa28bd61..2faf3d85e14f51419ead55ed3981b5959f87aba3 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/CreateWithAttributeTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/CreateWithAttributeTest.php
@@ -31,13 +31,15 @@ use Magento\Catalog\Test\Fixture\ProductAttribute;
 use Magento\Catalog\Test\Fixture\ConfigurableProduct;
 
 /**
+ * Class CreateWithAttributeTest
  * Configurable product with creating new category and new attribute
- *
  */
 class CreateWithAttributeTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -48,6 +50,7 @@ class CreateWithAttributeTest extends Functional
      * Creating configurable product with creating new category and new attribute (required fields only)
      *
      * @ZephyrId MAGETWO-13361
+     * @return void
      */
     public function testCreateConfigurableProductWithNewAttribute()
     {
@@ -77,36 +80,38 @@ class CreateWithAttributeTest extends Functional
      * Fill required fields for simple product with category creation
      *
      * @param Product $product
+     * @return void
      */
     protected function fillSimpleProductWithNewCategory($product)
     {
         //Page & Blocks
         $manageProductsGrid = Factory::getPageFactory()->getCatalogProductIndex();
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getProductForm();
 
         //Steps
         $manageProductsGrid->open();
         $manageProductsGrid->getProductBlock()->addProduct();
-        $productBlockForm->fill($product);
-        $productBlockForm->openTab(Product::GROUP_PRODUCT_DETAILS);
-        $productBlockForm->addNewCategory($product);
+        $productForm->fill($product);
+        $productForm->openTab(Product::GROUP_PRODUCT_DETAILS);
+        $productForm->addNewCategory($product);
     }
 
     /**
      * Add new attribute to product
      *
      * @param ProductAttribute $attribute
+     * @return void
      */
     protected function addNewAttribute(ProductAttribute $attribute)
     {
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
 
-        $productBlockForm = $createProductPage->getProductBlockForm();
-        $productBlockForm->openVariationsTab();
-        $productBlockForm->clickCreateNewVariationSet();
+        $productForm = $createProductPage->getConfigurableProductForm();
+        $productForm->openVariationsTab();
+        $productForm->clickCreateNewVariationSet();
 
-        $newAttributeForm = $createProductPage->getAttributeEditBlock();
+        $newAttributeForm = $productForm->getConfigurableAttributeEditBlock();
         $this->assertTrue($newAttributeForm->isVisible(), '"New attribute" window is not opened');
 
         $newAttributeForm->openFrontendProperties();
@@ -119,17 +124,20 @@ class CreateWithAttributeTest extends Functional
      * Fill product variations and save product
      *
      * @param ConfigurableProduct $variations
+     * @return void
      */
     protected function fillProductVariationsAndSave(ConfigurableProduct $variations)
     {
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
-        $productBlockForm = $createProductPage->getProductBlockForm();
-        $productBlockForm->fillVariations($variations);
-        $productBlockForm->save($variations);
+        $createProductPage->getProductForm()
+            ->fillVariations($variations);
+        $createProductPage->getFormAction()->saveProduct($createProductPage, $variations);
     }
 
     /**
      * Assert product was saved
+     *
+     * @return void
      */
     protected function assertProductSaved()
     {
@@ -145,6 +153,7 @@ class CreateWithAttributeTest extends Functional
      * Assert existing product on backend product grid
      *
      * @param Product $product
+     * @return void
      */
     protected function assertOnGrid(Product $product)
     {
@@ -163,6 +172,7 @@ class CreateWithAttributeTest extends Functional
      *
      * @param Product $product
      * @param ConfigurableProduct $variations
+     * @return void
      */
     protected function assertOnFrontend(Product $product, ConfigurableProduct $variations)
     {
@@ -187,9 +197,10 @@ class CreateWithAttributeTest extends Functional
             $productViewBlock->getProductName(),
             'Product name does not correspond to specified.'
         );
+        $price = $productViewBlock->getProductPrice();
         $this->assertEquals(
-            $product->getProductPrice(),
-            $productViewBlock->getProductPrice(),
+            number_format($product->getProductPrice(), 2),
+            $price['price_regular_price'],
             'Product price does not correspond to specified.'
         );
         $this->assertTrue(
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/EditConfigurableTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/EditConfigurableTest.php
index 8f21bfef21909dbdb30f586cddd1d06ad4065b26..8c687f37ca0459b8febb5523ca030c85fb5bc5f0 100755
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/EditConfigurableTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/Configurable/EditConfigurableTest.php
@@ -24,13 +24,12 @@
 
 namespace Magento\Catalog\Test\TestCase\Product\Configurable;
 
-use Magento\Catalog\Test\TestCase\Product\CreateConfigurableTest;
 use Mtf\Factory\Factory;
+use Magento\Catalog\Test\TestCase\Product\CreateConfigurableTest;
 
 /**
  * Class EditConfigurableTest
  * Edit Configurable product
- *
  */
 class EditConfigurableTest extends CreateConfigurableTest
 {
@@ -38,6 +37,7 @@ class EditConfigurableTest extends CreateConfigurableTest
      * Edit configurable product and add new options to attribute
      *
      * @ZephyrId MAGETWO-12840
+     * @return void
      */
     public function testCreateConfigurableProduct()
     {
@@ -51,7 +51,7 @@ class EditConfigurableTest extends CreateConfigurableTest
         $editProduct = $configurable->getEditData();
         //Steps
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getProductForm();
         //Login
         Factory::getApp()->magentoBackendLoginUser();
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
@@ -59,8 +59,8 @@ class EditConfigurableTest extends CreateConfigurableTest
         //Search and open original configurable product
         $productGridPage->getProductGrid()->searchAndOpen(array('sku' => $productSku));
         //Editing product options
-        $productBlockForm->fill($editProduct);
-        $productBlockForm->save($editProduct);
+        $productForm->fill($editProduct);
+        $createProductPage->getFormAction()->save();
         //Verifying
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         //Flush cache
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateConfigurableTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateConfigurableTest.php
index 7b96fb862c578a6866522448da0c56aedfef9926..f33fb2cdf623d4f60871d95a38acbf0c27ecfb44 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateConfigurableTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateConfigurableTest.php
@@ -31,12 +31,13 @@ use Magento\Catalog\Test\Fixture\ConfigurableProduct;
 /**
  * Class CreateConfigurableTest
  * Configurable product
- *
  */
 class CreateConfigurableTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -47,6 +48,7 @@ class CreateConfigurableTest extends Functional
      * Creating configurable product and assigning it to category
      *
      * @ZephyrId MAGETWO-12620
+     * @return void
      */
     public function testCreateConfigurableProduct()
     {
@@ -56,12 +58,12 @@ class CreateConfigurableTest extends Functional
         //Page & Blocks
         $manageProductsGrid = Factory::getPageFactory()->getCatalogProductIndex();
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
-        $productBlockForm = $createProductPage->getProductBlockForm();
         //Steps
         $manageProductsGrid->open();
         $manageProductsGrid->getProductBlock()->addProduct('configurable');
-        $productBlockForm->fill($product);
-        $productBlockForm->save($product);
+        $productForm = $createProductPage->getProductForm();
+        $productForm->fill($product);
+        $createProductPage->getFormAction()->saveProduct($createProductPage, $product);
         //Verifying
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         //Flush cache
@@ -78,6 +80,7 @@ class CreateConfigurableTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param ConfigurableProduct $product
+     * @return void
      */
     protected function assertOnGrid($product)
     {
@@ -90,7 +93,7 @@ class CreateConfigurableTest extends Functional
         //Page & Block
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $productGridPage->open();
-        /** @var \Magento\Catalog\Test\Block\Backend\ProductGrid */
+        /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid */
         $gridBlock = $productGridPage->getProductGrid();
         //Assertion
         $this->assertTrue($gridBlock->isRowVisible($configurableSearch), 'Configurable product was not found.');
@@ -106,6 +109,7 @@ class CreateConfigurableTest extends Functional
      * Assert configurable product on Frontend
      *
      * @param ConfigurableProduct $product
+     * @return void
      */
     protected function assertOnFrontend(ConfigurableProduct $product)
     {
@@ -130,9 +134,11 @@ class CreateConfigurableTest extends Functional
             $productViewBlock->getProductName(),
             'Product name does not correspond to specified.'
         );
+        $price = $product->getProductPrice();
+        $blockPrice = $productViewBlock->getProductPrice();
         $this->assertEquals(
-            $product->getProductPrice(),
-            $productViewBlock->getProductPrice(),
+            number_format($price, 2),
+            number_format($blockPrice['price_regular_price'], 2),
             'Product price does not correspond to specified.'
         );
         $this->assertTrue($productViewBlock->verifyProductOptions($product), 'Added configurable options are absent');
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateGroupedTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateGroupedTest.php
index 8dc5b49e71424b7c16fdb06fb86b9a6bd8da40a2..6b264249942c2983731daf7f4856cfb6dd92183f 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateGroupedTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateGroupedTest.php
@@ -37,6 +37,8 @@ class CreateGroupedTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -47,6 +49,7 @@ class CreateGroupedTest extends Functional
      * Creating Grouped product and assigning it to category
      *
      * @ZephyrId MAGETWO-13610
+     * @return void
      */
     public function testCreateGroupedProduct()
     {
@@ -56,12 +59,12 @@ class CreateGroupedTest extends Functional
         //Page & Blocks
         $manageProductsGrid = Factory::getPageFactory()->getCatalogProductIndex();
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getProductForm();
         //Steps
         $manageProductsGrid->open();
         $manageProductsGrid->getProductBlock()->addProduct('grouped');
-        $productBlockForm->fill($product);
-        $productBlockForm->save($product);
+        $productForm->fill($product);
+        $createProductPage->getFormAction()->save();
         //Verifying
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         // Flush cache
@@ -77,6 +80,7 @@ class CreateGroupedTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param GroupedProduct $product
+     * @return void
      */
     protected function assertOnGrid($product)
     {
@@ -88,7 +92,7 @@ class CreateGroupedTest extends Functional
         //Page & Block
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $productGridPage->open();
-        /** @var \Magento\Catalog\Test\Block\Backend\ProductGrid */
+        /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid $gridBlock */
         $gridBlock = $productGridPage->getProductGrid();
         //Assertion
         $this->assertTrue($gridBlock->isRowVisible($search), 'Grouped product was not found.');
@@ -98,6 +102,7 @@ class CreateGroupedTest extends Functional
      * Assert Grouped product on Frontend
      *
      * @param GroupedProduct $product
+     * @return void
      */
     protected function assertOnFrontend(GroupedProduct $product)
     {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateProductTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateProductTest.php
index 2530d9a787e3f57f29faa96528dfe120e002158d..d4c90ab961796f0da4ba89838dce4d60d323add1 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateProductTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateProductTest.php
@@ -29,13 +29,15 @@ use Mtf\TestCase\Functional;
 use Magento\Catalog\Test\Fixture\SimpleProduct;
 
 /**
- * Create product
- *
+ * Class CreateProductTest
+ * Create product test
  */
 class CreateProductTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -46,6 +48,7 @@ class CreateProductTest extends Functional
      * Create simple product with settings in advanced inventory tab
      *
      * @ZephyrId MAGETWO-12914
+     * @return void
      */
     public function testCreateProductAdvancedInventory()
     {
@@ -54,11 +57,11 @@ class CreateProductTest extends Functional
         //Data
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
         $createProductPage->init($product);
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getProductForm();
         //Steps
         $createProductPage->open();
-        $productBlockForm->fill($product);
-        $productBlockForm->save($product);
+        $productForm->fill($product);
+        $createProductPage->getFormAction()->save();
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         //Flush cache
         $cachePage = Factory::getPageFactory()->getAdminCache();
@@ -74,8 +77,9 @@ class CreateProductTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param SimpleProduct $product
+     * @return void
      */
-    protected function assertOnGrid($product)
+    protected function assertOnGrid(SimpleProduct $product)
     {
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $productGridPage->open();
@@ -87,8 +91,9 @@ class CreateProductTest extends Functional
      * Assert product data on category and product pages
      *
      * @param SimpleProduct $product
+     * @return void
      */
-    protected function assertOnCategory($product)
+    protected function assertOnCategory(SimpleProduct $product)
     {
         //Pages
         $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex();
@@ -104,6 +109,7 @@ class CreateProductTest extends Functional
         //Verification on product detail page
         $productViewBlock = $productPage->getViewBlock();
         $this->assertEquals($product->getProductName(), $productViewBlock->getProductName());
-        $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice());
+        $price = $productViewBlock->getProductPrice();
+        $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCategoryTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCategoryTest.php
index c0b855d4d1bfbd36da305f2b892fccb3e17e82b6..c4b06bd2cc27101a94321fb4c5b24c44929bcc76 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCategoryTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCategoryTest.php
@@ -31,12 +31,13 @@ use Magento\Catalog\Test\Fixture\SimpleProduct;
 /**
  * Class CreateSimpleWithCategoryTest
  * Test simple product and category creation
- *
  */
 class CreateSimpleWithCategoryTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -47,6 +48,7 @@ class CreateSimpleWithCategoryTest extends Functional
      * Test product create
      *
      * @ZephyrId MAGETWO-13345
+     * @return void
      */
     public function testCreateProduct()
     {
@@ -58,14 +60,14 @@ class CreateSimpleWithCategoryTest extends Functional
         $productListPage = Factory::getPageFactory()->getCatalogProductIndex();
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
         $addProductBlock = $productListPage->getProductBlock();
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getProductForm();
 
         //Steps
         $productListPage->open();
         $addProductBlock->addProduct();
-        $productBlockForm->addNewCategory($product);
-        $productBlockForm->fill($product);
-        $productBlockForm->save($product);
+        $productForm->addNewCategory($product);
+        $productForm->fill($product);
+        $createProductPage->getFormAction()->save();
 
         //Verifying
         $this->assertSuccessMessage("You saved the product.");
@@ -98,6 +100,7 @@ class CreateSimpleWithCategoryTest extends Functional
      * Assert simple product on Frontend
      *
      * @param SimpleProduct $product
+     * @return void
      */
     protected function assertProductOnFrontend(SimpleProduct $product)
     {
@@ -120,6 +123,7 @@ class CreateSimpleWithCategoryTest extends Functional
         $productViewBlock = $productPage->getViewBlock();
         $productListBlock->openProductViewPage($product->getProductName());
         $this->assertEquals($product->getProductName(), $productViewBlock->getProductName());
-        $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice());
+        $price = $productViewBlock->getProductPrice();
+        $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCustomOptionsAndCategoryTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCustomOptionsAndCategoryTest.php
index 78979b322e657c7ccf35add6a7fcaeadccf61cd4..b649e5c9ff70e3d4f4fbb8499d0959f4ed1317cd 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCustomOptionsAndCategoryTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateSimpleWithCustomOptionsAndCategoryTest.php
@@ -29,13 +29,15 @@ use Mtf\TestCase\Functional;
 use Magento\Catalog\Test\Fixture\Product;
 
 /**
+ * Class CreateSimpleWithCustomOptionsAndCategoryTest
  * Create simple product with custom options
- *
  */
 class CreateSimpleWithCustomOptionsAndCategoryTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -46,6 +48,7 @@ class CreateSimpleWithCustomOptionsAndCategoryTest extends Functional
      * Creating simple product with custom options and assigning it to the category
      *
      * @ZephyrId MAGETWO-12703
+     * @return void
      */
     public function testCreateProduct()
     {
@@ -54,11 +57,11 @@ class CreateSimpleWithCustomOptionsAndCategoryTest extends Functional
         //Data
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
         $createProductPage->init($product);
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getForm();
         //Steps
         $createProductPage->open();
-        $productBlockForm->fill($product);
-        $productBlockForm->save($product);
+        $productForm->fillProduct($product);
+        $createProductPage->getFormAction()->save();
         //Verifying
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         // Flush cache
@@ -74,12 +77,13 @@ class CreateSimpleWithCustomOptionsAndCategoryTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param Product $product
+     * @return void
      */
     protected function assertOnGrid($product)
     {
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $productGridPage->open();
-        //@var Magento\Catalog\Test\Block\Backend\ProductGrid
+        /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid $gridBlock */
         $gridBlock = $productGridPage->getProductGrid();
         $this->assertTrue($gridBlock->isRowVisible(array('sku' => $product->getProductSku())));
     }
@@ -88,6 +92,7 @@ class CreateSimpleWithCustomOptionsAndCategoryTest extends Functional
      * Assert product data on category and product pages
      *
      * @param Product $product
+     * @return void
      */
     protected function assertOnCategory($product)
     {
@@ -105,12 +110,14 @@ class CreateSimpleWithCustomOptionsAndCategoryTest extends Functional
         //Verification on product detail page
         $productViewBlock = $productPage->getViewBlock();
         $this->assertEquals($product->getProductName(), $productViewBlock->getProductName());
-        $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice());
+        $price = $productViewBlock->getProductPrice();
+        $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']);
 
-        $productOptionsBlock = $productPage->getCustomOptionBlock();
+        $productOptionsBlock = $productPage->getCustomOptionsBlock();
         $fixture = $product->getData('fields/custom_options/value');
-        $actualOptions = $productOptionsBlock->get();
+        $actualOptions = $productOptionsBlock->getOptions();
         $this->assertCount(count($fixture), $actualOptions);
-        $this->assertEquals($fixture[0]['title'], $actualOptions[0]['title']);
+        $this->assertTrue(isset($actualOptions[$fixture[0]['title']]['title']));
+        $this->assertEquals($fixture[0]['title'], $actualOptions[$fixture[0]['title']]['title']);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateTest.php
index dc88247e53ded20cc0f0e0a477667a0c7dc50ddb..b9b0eae2e3fac8140e9f856f82208677c5c916f7 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateTest.php
@@ -29,13 +29,15 @@ use Mtf\TestCase\Functional;
 use Magento\Catalog\Test\Fixture\SimpleProduct;
 
 /**
+ * Class CreateTest
  * Create simple product for BAT
- *
  */
 class CreateTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -46,6 +48,7 @@ class CreateTest extends Functional
      * Creating simple product and assigning it to category
      *
      * @ZephyrId MAGETWO-12514
+     * @return void
      */
     public function testCreateProduct()
     {
@@ -54,11 +57,11 @@ class CreateTest extends Functional
         //Data
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
         $createProductPage->init($product);
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getProductForm();
         //Steps
         $createProductPage->open();
-        $productBlockForm->fill($product);
-        $productBlockForm->save($product);
+        $productForm->fill($product);
+        $createProductPage->getFormAction()->save();
         //Verifying
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         //Flush cache
@@ -75,12 +78,13 @@ class CreateTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param SimpleProduct $product
+     * @return void
      */
-    protected function assertOnGrid($product)
+    protected function assertOnGrid(SimpleProduct $product)
     {
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $productGridPage->open();
-        //@var Magento\Catalog\Test\Block\Backend\ProductGrid
+        /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid $gridBlock */
         $gridBlock = $productGridPage->getProductGrid();
         $this->assertTrue($gridBlock->isRowVisible(array('sku' => $product->getProductSku())));
     }
@@ -89,8 +93,9 @@ class CreateTest extends Functional
      * Assert product data on category and product pages
      *
      * @param SimpleProduct $product
+     * @return void
      */
-    protected function assertOnCategory($product)
+    protected function assertOnCategory(SimpleProduct $product)
     {
         //Pages
         $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex();
@@ -106,6 +111,7 @@ class CreateTest extends Functional
         //Verification on product detail page
         $productViewBlock = $productPage->getViewBlock();
         $this->assertEquals($product->getProductName(), $productViewBlock->getProductName());
-        $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice());
+        $price = $productViewBlock->getProductPrice();
+        $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualTest.php
index 201e02f43c9588280171fb0ae37581d4ec341c56..c2d9d56316fb7599859623e0502eb1de990df3f6 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualTest.php
@@ -31,12 +31,13 @@ use Magento\Catalog\Test\Fixture\VirtualProduct;
 /**
  * Class CreateTest
  * Test product creation
- *
  */
 class CreateVirtualTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -47,6 +48,7 @@ class CreateVirtualTest extends Functional
      * Creating Virtual product with required fields only and assign it to the category
      *
      * @ZephyrId MAGETWO-13593
+     * @return void
      */
     public function testCreateProduct()
     {
@@ -55,11 +57,11 @@ class CreateVirtualTest extends Functional
         //Data
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
         $createProductPage->init($product);
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getProductForm();
         //Steps
         $createProductPage->open();
-        $productBlockForm->fill($product);
-        $productBlockForm->save($product);
+        $productForm->fill($product);
+        $createProductPage->getFormAction()->save();
         //Verifying
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
         //Flush cache
@@ -76,12 +78,13 @@ class CreateVirtualTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param VirtualProduct $product
+     * @return void
      */
-    protected function assertOnGrid($product)
+    protected function assertOnGrid(VirtualProduct $product)
     {
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $productGridPage->open();
-        //@var Magento\Catalog\Test\Block\Backend\ProductGrid
+        /** @var \Magento\Catalog\Test\Block\Adminhtml\Product\Grid $gridBlock */
         $gridBlock = $productGridPage->getProductGrid();
         $this->assertTrue($gridBlock->isRowVisible(array('sku' => $product->getProductSku())));
     }
@@ -90,8 +93,9 @@ class CreateVirtualTest extends Functional
      * Assert product data on category and product pages
      *
      * @param VirtualProduct $product
+     * @return void
      */
-    protected function assertOnCategory($product)
+    protected function assertOnCategory(VirtualProduct $product)
     {
         //Pages
         $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex();
@@ -107,6 +111,7 @@ class CreateVirtualTest extends Functional
         $productPage = Factory::getPageFactory()->getCatalogProductView();
         $productViewBlock = $productPage->getViewBlock();
         $this->assertEquals($product->getProductName(), $productViewBlock->getProductName());
-        $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice());
+        $price = $productViewBlock->getProductPrice();
+        $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/EditSimpleProductTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/EditSimpleProductTest.php
index 66fa1d5934cfd57a62a14ec38580221dd112a083..e9fb1f950368ff86e0ef2f6a251abe870543070e 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/EditSimpleProductTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/EditSimpleProductTest.php
@@ -36,6 +36,8 @@ class EditSimpleProductTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -46,6 +48,7 @@ class EditSimpleProductTest extends Functional
      * Edit simple product
      *
      * @ZephyrId MAGETWO-12428
+     * @return void
      */
     public function testEditProduct()
     {
@@ -58,7 +61,7 @@ class EditSimpleProductTest extends Functional
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $gridBlock = $productGridPage->getProductGrid();
         $editProductPage = Factory::getPageFactory()->getCatalogProductEdit();
-        $productBlockForm = $editProductPage->getProductBlockForm();
+        $productForm = $editProductPage->getProductForm();
         $cachePage = Factory::getPageFactory()->getAdminCache();
 
         $productGridPage->open();
@@ -68,8 +71,8 @@ class EditSimpleProductTest extends Functional
                 'type' => 'Simple Product'
             )
         );
-        $productBlockForm->fill($editProduct);
-        $productBlockForm->save($editProduct);
+        $productForm->fill($editProduct);
+        $editProductPage->getFormAction()->save();
         //Verifying
         $editProductPage->getMessagesBlock()->assertSuccessMessage();
         // Flush cache
@@ -85,8 +88,9 @@ class EditSimpleProductTest extends Functional
      * Assert existing product on admin product grid
      *
      * @param SimpleProduct $product
+     * @return void
      */
-    protected function assertOnGrid($product)
+    protected function assertOnGrid(SimpleProduct $product)
     {
         $productGridPage = Factory::getPageFactory()->getCatalogProductIndex();
         $productGridPage->open();
@@ -99,8 +103,9 @@ class EditSimpleProductTest extends Functional
      *
      * @param SimpleProduct $product
      * @param string $categoryName
+     * @return void
      */
-    protected function assertOnCategoryPage($product, $categoryName)
+    protected function assertOnCategoryPage(SimpleProduct $product, $categoryName)
     {
         //Pages
         $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex();
@@ -119,8 +124,9 @@ class EditSimpleProductTest extends Functional
      *
      * @param SimpleProduct $productOld
      * @param SimpleProduct $productEdited
+     * @return void
      */
-    protected function assertOnProductPage($productOld, $productEdited)
+    protected function assertOnProductPage(SimpleProduct $productOld, SimpleProduct $productEdited)
     {
         $productPage = Factory::getPageFactory()->getCatalogProductView();
         $productPage->init($productOld);
@@ -128,6 +134,7 @@ class EditSimpleProductTest extends Functional
 
         $productViewBlock = $productPage->getViewBlock();
         $this->assertEquals($productEdited->getProductName(), $productViewBlock->getProductName());
-        $this->assertEquals($productEdited->getProductPrice(), $productViewBlock->getProductPrice());
+        $price = $productViewBlock->getProductPrice();
+        $this->assertEquals(number_format($productEdited->getProductPrice(), 2), $price['price_regular_price']);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UnassignCategoryTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UnassignCategoryTest.php
index 9d49fd1baaf5865971a8588d4b546a570b862bc7..9d75889bb72ba45a692cf4c24ae8b019ac481beb 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UnassignCategoryTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UnassignCategoryTest.php
@@ -29,13 +29,15 @@ use Mtf\TestCase\Functional;
 use Magento\Catalog\Test\Fixture\Product;
 
 /**
+ * Class UnassignCategoryTest
  * Unassign product from category on Product page
- *
  */
 class UnassignCategoryTest extends Functional
 {
     /**
      * Login into backend area before test
+     *
+     * @return void
      */
     protected function setUp()
     {
@@ -46,6 +48,7 @@ class UnassignCategoryTest extends Functional
      * Unassigning products from the category on Product Information page
      *
      * @ZephyrId MAGETWO-12417
+     * @return void
      */
     public function testUnassignOnProductPage()
     {
@@ -56,8 +59,9 @@ class UnassignCategoryTest extends Functional
         //Steps
         $editProductPage = Factory::getPageFactory()->getCatalogProductEdit();
         $editProductPage->open(array('id' => $simple->getProductId()));
-        $editProductPage->getProductBlockForm()->clearCategorySelect();
-        $editProductPage->getProductBlockForm()->save($simple);
+        $productForm = $editProductPage->getProductForm();
+        $productForm->clearCategorySelect();
+        $editProductPage->getFormAction()->save();
         //Verifying
         $editProductPage->getMessagesBlock()->assertSuccessMessage();
         //Flush cache
@@ -73,8 +77,9 @@ class UnassignCategoryTest extends Functional
      * Assert absence product on category page (frontend)
      *
      * @param Product $product
+     * @return void
      */
-    protected function assertAbsenceOnCategory($product)
+    protected function assertAbsenceOnCategory(Product $product)
     {
         //Pages
         $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex();
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml
index 330a2ed29cd00c028c2afb548a9a4f7ae69332b3..a9767c006017e0ebfa48a5bae0c0a6900638239a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml
@@ -25,4 +25,5 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/Magento/Framework/ObjectManager/etc/config.xsd">
     <preference for="Magento\Catalog\Test\Handler\CatalogProductSimple\CatalogProductSimpleInterface" type="\Magento\Catalog\Test\Handler\CatalogProductSimple\Curl" />
+    <preference for="Magento\Catalog\Test\Handler\CatalogCategoryEntity\CatalogCategoryEntityInterface" type="\Magento\Catalog\Test\Handler\CatalogCategoryEntity\Curl" />
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml
index 4393f757e174fec8dec45af7d3bc7a6da3f61135..f2055f359c4d91101d82f6c6d9e998fd7a1c112d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml
@@ -27,28 +27,28 @@
     <assertProductInGrid module="Magento_Catalog">
         <severeness>high</severeness>
         <require>
-            <manageProductsPage class="Magento\Catalog\Test\Page\Product\CatalogProductIndex" />
-            <product class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
+            <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" />
+            <product class="Mtf\Fixture\FixtureInterface" />
         </require>
     </assertProductInGrid>
     <assertProductSaveMessage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <productPage class="Magento\Catalog\Test\Page\Product\CatalogProductEdit" />
+            <productPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit" />
         </require>
     </assertProductSaveMessage>
     <assertProductOutOfStock module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
             <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <simple class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
+            <product class="Mtf\Fixture\FixtureInterface" />
         </require>
     </assertProductOutOfStock>
     <assertProductInStock module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
             <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <simple class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
+            <product class="Mtf\Fixture\FixtureInterface" />
         </require>
     </assertProductInStock>
     <assertProductVisibleInCategory module="Magento_Catalog">
@@ -57,7 +57,7 @@
             <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
             <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
             <category class="Magento\Catalog\Test\Fixture\Category" />
-            <simple class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
+            <product class="Mtf\Fixture\FixtureInterface" />
         </require>
     </assertProductVisibleInCategory>
     <assertProductSearchableBySku module="Magento_Catalog">
@@ -65,7 +65,7 @@
         <require>
             <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult" />
             <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <simple class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
+            <product class="Mtf\Fixture\FixtureInterface" />
         </require>
     </assertProductSearchableBySku>
     <assertProductInCategory module="Magento_Catalog">
@@ -73,7 +73,7 @@
         <require>
             <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
             <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <product class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
+            <product class="Mtf\Fixture\FixtureInterface" />
             <category class="Magento\Catalog\Test\Fixture\Category" />
         </require>
     </assertProductInCategory>
@@ -81,15 +81,55 @@
         <severeness>low</severeness>
         <require>
             <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
+            <product class="Mtf\Fixture\FixtureInterface" />
         </require>
     </assertProductView>
     <assertProductInCart module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
             <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
+            <product class="Mtf\Fixture\FixtureInterface" />
             <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart" />
         </require>
     </assertProductInCart>
+    <assertProductPage module="Magento_Catalog">
+        <severeness>low</severeness>
+        <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+        <product class="Mtf\Fixture\FixtureInterface" />
+    </assertProductPage>
+    <assertGroupedPriceOnProductPage module="Magento_Catalog">
+        <severeness>low</severeness>
+        <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+        <product class="Mtf\Fixture\FixtureInterface" />
+    </assertGroupedPriceOnProductPage>
+    <assertSpecialPriceOnProductPage module="Magento_Catalog">
+        <severeness>low</severeness>
+        <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+        <product class="Mtf\Fixture\FixtureInterface" />
+    </assertSpecialPriceOnProductPage>
+    <assertTierPriceOnProductPage module="Magento_Catalog">
+        <severeness>low</severeness>
+        <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+        <product class="Mtf\Fixture\FixtureInterface" />
+    </assertTierPriceOnProductPage>
+    <assertCustomOptionsOnProductPage module="Magento_Catalog">
+        <severeness>low</severeness>
+        <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+        <product class="Mtf\Fixture\FixtureInterface" />
+    </assertCustomOptionsOnProductPage>
+    <assertProductForm module="Magento_Catalog">
+        <severeness>low</severeness>
+        <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+        <product class="Mtf\Fixture\FixtureInterface" />
+    </assertProductForm>
+    <assertAddToCartButtonAbsent module="Magento_Catalog">
+        <severeness>low</severeness>
+        <require>
+        </require>
+    </assertAddToCartButtonAbsent>
+    <assertAddToCartButtonPresent module="Magento_Catalog">
+        <severeness>low</severeness>
+        <require>
+        </require>
+    </assertAddToCartButtonPresent>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml
index 2da82fdd737cbe241b80b9bed9ac2fa4e245db3b..05f1ac8cb595d2caccbd54aa98472c2ec939d580 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml
@@ -169,4 +169,9 @@
             <input_prefix>product</input_prefix>
         </data_config>
     </catalogProductGrouped>
+    <catalogCategoryEntity module="Magento_Catalog">
+        <type>flat</type>
+        <entity_type>catalog_category_entity</entity_type>
+        <collection>Magento\Catalog\Model\Resource\Category\Collection</collection>
+    </catalogCategoryEntity>
 </fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/page.xml
index 8dae4a2d026da36816db038162f7a351f67676c9..6fb0c3f0a4de23d542d09052c5c8b44cfcf5a680 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/page.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/page.xml
@@ -29,4 +29,24 @@
         <area>adminhtml</area>
         <class>Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex</class>
     </catalogProductIndex>
+    <catalogProductNew>
+        <mca>catalog/product/new</mca>
+        <area>adminhtml</area>
+        <class>Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew</class>
+    </catalogProductNew>
+    <catalogProductEdit>
+        <mca>catalog/product/edit</mca>
+        <area>adminhtml</area>
+        <class>Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit</class>
+    </catalogProductEdit>
+    <catalogProductViewPage>
+        <mca>catalog/product/view</mca>
+        <area>product</area>
+        <class>Magento\Catalog\Test\Page\Product\CatalogProductView</class>
+    </catalogProductViewPage>
+    <catalogCategoryView>
+        <mca>catalog/category/view</mca>
+        <area>category</area>
+        <class>Magento\Catalog\Test\Page\Category\CatalogCategoryView</class>
+    </catalogCategoryView>
 </page>
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
index 0e68574feb801bf84e38e31b6ab818f7e40d3322..8b5a513031685e80f942eee96881e1783a52f073 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Block/Cart.php
@@ -35,7 +35,6 @@ use Magento\Checkout\Test\Block\Onepage\Link;
 /**
  * Class Cart
  * Shopping cart block
- *
  */
 class Cart extends Block
 {
@@ -88,12 +87,23 @@ class Cart extends Block
         return $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->getText();
     }
 
+    /**
+     * Get sub-total for the specified item in the cart by product name
+     *
+     * @param string $productName
+     * @return string
+     */
+    public function getCartItemSubTotalByProductName($productName)
+    {
+        $selector = '//tr[normalize-space(td)="' . $productName . '"]' . $this->itemSubTotalSelector;
+        return $this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->getText();
+    }
+
     /**
      * Get unit price for the specified item in the cart
      *
      * @param Product $product
      * @param string $currency
-     *
      * @return float
      */
     public function getCartItemUnitPrice($product, $currency = '$')
@@ -113,7 +123,7 @@ class Cart extends Block
      * Get product options in the cart
      *
      * @param Product $product
-     * @return array|string
+     * @return string
      */
     public function getCartItemOptions($product)
     {
@@ -127,6 +137,40 @@ class Cart extends Block
         return $optionsBlock->getText();
     }
 
+    /**
+     * Get product options value in the cart by product name
+     *
+     * @param string $productName
+     * @return string
+     */
+    public function getCartItemOptionsNameByProductName($productName)
+    {
+        $selector = '//tr[string(td/div/strong/a)="' . $productName . '"]//dl[@class="cart item options"]//dt';
+
+        $optionsBlock = $this->_rootElement->find($selector, Locator::SELECTOR_XPATH);
+        if (!$optionsBlock->isVisible()) {
+            return '';
+        }
+        return $optionsBlock->getText();
+    }
+
+    /**
+     * Get product options value in the cart by product name
+     *
+     * @param string $productName
+     * @return string
+     */
+    public function getCartItemOptionsValueByProductName($productName)
+    {
+        $selector = '//tr[string(td/div/strong/a)="' . $productName . '"]//dl[@class="cart item options"]//dd';
+
+        $optionsBlock = $this->_rootElement->find($selector, Locator::SELECTOR_XPATH);
+        if (!$optionsBlock->isVisible()) {
+            return '';
+        }
+        return $optionsBlock->getText();
+    }
+
     /**
      * Get proceed to checkout block
      *
@@ -141,6 +185,8 @@ class Cart extends Block
 
     /**
      * Press 'Check out with PayPal' button
+     *
+     * @return void
      */
     public function paypalCheckout()
     {
@@ -170,6 +216,8 @@ class Cart extends Block
 
     /**
      * Clear shopping cart
+     *
+     * @return void
      */
     public function clearShoppingCart()
     {
diff --git a/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.php b/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.php
index 09a1fb34b02b6900c2bfd6f0dd2688aeb6ed3eff..93aaab1e0e27eae6d809149d59db8447306f11a8 100644
--- a/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.php
+++ b/dev/tests/functional/tests/app/Magento/Checkout/Test/Page/CheckoutCart.php
@@ -85,7 +85,7 @@ class CheckoutCart extends Page
      *
      * @return Messages
      */
-    public function getMessageBlock()
+    public function getMessagesBlock()
     {
         return Factory::getBlockFactory()->getMagentoCoreMessages(
             $this->_browser->find('.messages .messages', Locator::SELECTOR_CSS)
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.php
index 87209ae47c0c9f5bbd28607170ae87e7a7a92b70..bb5ac47b01c9ab79f906ff52d21b5320cb6fd997 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.php
@@ -24,139 +24,101 @@
 
 namespace Magento\Cms\Test\Page;
 
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
-use Mtf\Client\Element\Locator;
+use Mtf\Page\FrontendPage;
 
 /**
  * Class CmsIndex
- * Home page for frontend
  *
+ * @package Magento\Cms\Test\Page
  */
-class CmsIndex extends Page
+class CmsIndex extends FrontendPage
 {
-    /**
-     * URL for home page
-     */
     const MCA = 'cms/index/index';
 
-    /**
-     * Search block
-     *
-     * @var string
-     */
-    protected $searchBlock = '#search_mini_form';
-
-    /**
-     * Top menu navigation block
-     *
-     * @var string
-     */
-    protected $topmenuBlock = '[role=navigation]';
-
-    /**
-     * Page title block
-     *
-     * @var string
-     */
-    protected $titleBlock = '.page.title';
-
-    /**
-     * Footer block
-     *
-     * @var string
-     */
-    protected $footerBlock = 'footer.footer';
-
-    /**
-     * Page Top Links block
-     *
-     * @var string
-     */
-    protected $linksBlock = '.header .links';
-
-    /**
-     * Store switcher block path
-     */
-    private $storeSwitcherBlock = '//*[@data-ui-id="language-switcher"]';
-
-    /**
-     * Custom constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_frontend_url'];
-    }
+    protected $_blocks = [
+        'searchBlock' => [
+            'name' => 'searchBlock',
+            'class' => 'Magento\Catalog\Test\Block\Search',
+            'locator' => '#search_mini_form',
+            'strategy' => 'css selector',
+        ],
+        'topmenu' => [
+            'name' => 'topmenu',
+            'class' => 'Magento\Theme\Test\Block\Html\Topmenu',
+            'locator' => '[role=navigation]',
+            'strategy' => 'css selector',
+        ],
+        'titleBlock' => [
+            'name' => 'titleBlock',
+            'class' => 'Magento\Theme\Test\Block\Html\Title',
+            'locator' => '.page.title',
+            'strategy' => 'css selector',
+        ],
+        'footerBlock' => [
+            'name' => 'footerBlock',
+            'class' => 'Magento\Theme\Test\Block\Html\Footer',
+            'locator' => 'footer.footer',
+            'strategy' => 'css selector',
+        ],
+        'linksBlock' => [
+            'name' => 'linksBlock',
+            'class' => 'Magento\Theme\Test\Block\Links',
+            'locator' => '.header .links',
+            'strategy' => 'css selector',
+        ],
+        'storeSwitcherBlock' => [
+            'name' => 'storeSwitcherBlock',
+            'class' => 'Magento\Store\Test\Block\Switcher',
+            'locator' => '[data-ui-id="language-switcher"]',
+            'strategy' => 'css selector',
+        ],
+    ];
 
     /**
-     * Get the search block
-     *
      * @return \Magento\Catalog\Test\Block\Search
      */
     public function getSearchBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogSearch(
-            $this->_browser->find($this->searchBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('searchBlock');
     }
 
     /**
-     * Get category title block
-     *
      * @return \Magento\Theme\Test\Block\Html\Topmenu
      */
     public function getTopmenu()
     {
-        return Factory::getBlockFactory()->getMagentoThemeHtmlTopmenu(
-            $this->_browser->find($this->topmenuBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('topmenu');
     }
 
     /**
-     * Get title block
-     *
      * @return \Magento\Theme\Test\Block\Html\Title
      */
     public function getTitleBlock()
     {
-        return Factory::getBlockFactory()->getMagentoThemeHtmlTitle(
-            $this->_browser->find($this->titleBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('titleBlock');
     }
 
     /**
-     * Get footer block
-     *
      * @return \Magento\Theme\Test\Block\Html\Footer
      */
     public function getFooterBlock()
     {
-        return Factory::getBlockFactory()->getMagentoThemeHtmlFooter(
-            $this->_browser->find($this->footerBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('footerBlock');
     }
 
     /**
-     * Get Top Links block
-     *
      * @return \Magento\Theme\Test\Block\Links
      */
     public function getLinksBlock()
     {
-        return Factory::getBlockFactory()->getMagentoThemeLinks(
-            $this->_browser->find($this->linksBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('linksBlock');
     }
 
     /**
-     * Get store switcher
-     *
      * @return \Magento\Store\Test\Block\Switcher
      */
     public function getStoreSwitcherBlock()
     {
-        return Factory::getBlockFactory()->getMagentoStoreSwitcher(
-            $this->_browser->find($this->storeSwitcherBlock, Locator::SELECTOR_XPATH)
-        );
+        return $this->getBlockInstance('storeSwitcherBlock');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a28d9698d8828060d9895992d55a369c8a6b0943
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Page/CmsIndex.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="cms/index/index">
+    <block>
+        <name>searchBlock</name>
+        <class>Magento\Catalog\Test\Block\Search</class>
+        <locator>#search_mini_form</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>topmenu</name>
+        <class>Magento\Theme\Test\Block\Html\Topmenu</class>
+        <locator>[role=navigation]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>titleBlock</name>
+        <class>Magento\Theme\Test\Block\Html\Title</class>
+        <locator>.page.title</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>footerBlock</name>
+        <class>Magento\Theme\Test\Block\Html\Footer</class>
+        <locator>footer.footer</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>linksBlock</name>
+        <class>Magento\Theme\Test\Block\Links</class>
+        <locator>.header .links</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>storeSwitcherBlock</name>
+        <class>Magento\Store\Test\Block\Switcher</class>
+        <locator>//*[@data-ui-id="language-switcher"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php
index 327063cec25750f241ad0fc397e9fd7a68daa67a..d01ea227cc65cbeb788233cafc344e2b194abfa4 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php
@@ -31,7 +31,6 @@ use Mtf\Client\Element\Locator;
 /**
  * Class Attribute
  * Attribute block in Variation section
- *
  */
 class Attribute extends Block
 {
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
index 03c6023a915defe46c47219447c5df4c823e75e8..0a5f9f8a3099fa60bd3b620be93b9449081ba4b8 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
@@ -31,7 +31,6 @@ use Magento\Backend\Test\Block\Widget\Tab;
 /**
  * Class Variations
  * Adminhtml catalog super product configurable tab
- *
  */
 class Config extends Tab
 {
@@ -61,7 +60,7 @@ class Config extends Tab
      *
      * @var string
      */
-    protected $loader = '[data-role=loader]';
+    protected $loader = './ancestor::body//*[contains(@data-role,"loader")]';
 
     /**
      * Attribute Opened
@@ -75,7 +74,7 @@ class Config extends Tab
      *
      * @var string
      */
-    protected $attributeTab = '//*[@data-role="configurable-attribute"]//*[text()="%attributeTab%"]';
+    protected $attributeTab = './/*[@data-role="configurable-attribute"]//*[text()="%attributeTab%"]';
 
     /**
      * Get attribute block
@@ -111,19 +110,18 @@ class Config extends Tab
      */
     public function generateVariations()
     {
-        $browser = $this->_rootElement;
-        $browser->find($this->generateVariations, Locator::SELECTOR_CSS)->click();
-        $this->waitForElementVisible($this->matrixBlock);
+        $this->_rootElement->find($this->generateVariations, Locator::SELECTOR_CSS)->click();
+        $this->waitForElementVisible($this->matrixBlock, Locator::SELECTOR_CSS);
     }
 
     /**
      * Fill variations fieldset
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
-    public function fillFormTab(array $fields, Element $element)
+    public function fillFormTab(array $fields, Element $element = null)
     {
         if (!isset($fields['configurable_attributes_data'])) {
             return $this;
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php
index f7f62a664b2a4b8bfb205bf1f41d7a85ea8fd6e9..60f6e94fbde699b37a61612effb813bfcb3ba91e 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php
@@ -31,7 +31,6 @@ use Mtf\Client\Element\Locator;
 /**
  * Class Matrix
  * Product variations matrix block
- *
  */
 class Matrix extends Form
 {
@@ -39,6 +38,7 @@ class Matrix extends Form
      * Fill qty to current variations
      *
      * @param array $variations
+     * @return void
      */
     public function fillVariation(array $variations)
     {
@@ -60,7 +60,7 @@ class Matrix extends Form
      * Define row that clarifies which line in Current Variations grid will be used
      *
      * @param array $variationData
-     * @return Element
+     * @return string
      */
     private function getVariationRow(array $variationData)
     {
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
index 8dd63b07b65e15738a8dae116d7f4866b8af77d6..ea902660a7da43eabe921662ed9bb53d6c79072a 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
@@ -28,18 +28,18 @@ use Mtf\Block\Mapper;
 use Mtf\Client\Element;
 use Mtf\Client\Browser;
 use Mtf\Factory\Factory;
+use Mtf\Util\XmlConverter;
+use Mtf\Block\BlockFactory;
 use Mtf\Client\Element\Locator;
 use Mtf\Fixture\FixtureInterface;
 use Magento\Catalog\Test\Fixture\Product;
 use Magento\Catalog\Test\Fixture\Category;
 use Magento\Backend\Test\Block\Widget\Tab;
 use Magento\Backend\Test\Block\Widget\FormTabs;
-use Mtf\Util\XmlConverter;
 
 /**
  * Class ProductForm
  * Product creation form
- *
  */
 class ProductForm extends FormTabs
 {
@@ -128,6 +128,8 @@ class ProductForm extends FormTabs
     protected $advancedTabPanel = '[role="tablist"] [role="tabpanel"][aria-expanded="true"]:not("overflow")';
 
     /**
+     * Category fixture
+     *
      * @var Category
      */
     protected $category;
@@ -143,16 +145,18 @@ class ProductForm extends FormTabs
      * @param Element $element
      * @param Mapper $mapper
      * @param XmlConverter $xmlConverter
+     * @param BlockFactory $blockFactory
      * @param Browser $browser
      */
     public function __construct(
         Element $element,
         Mapper $mapper,
         XmlConverter $xmlConverter,
+        BlockFactory $blockFactory,
         Browser $browser
     ) {
         $this->browser = $browser;
-        parent::__construct($element, $mapper, $xmlConverter);
+        parent::__construct($element, $mapper, $blockFactory, $xmlConverter);
     }
 
     /**
@@ -181,7 +185,10 @@ class ProductForm extends FormTabs
     }
 
     /**
+     * Initialization categories before use in the form of
+     *
      * @param Category $category
+     * @return void
      */
     public function setCategory(Category $category)
     {
@@ -192,7 +199,7 @@ class ProductForm extends FormTabs
      * Fill the product form
      *
      * @param FixtureInterface $fixture
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
     public function fill(FixtureInterface $fixture, Element $element = null)
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/AffectedAttributeSet.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/AffectedAttributeSet.php
index 8febd8571095c7693a713f86c79a5c01677b08c7..53fa7fbd1b59222b86f73b29dd2b346694a07765 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/AffectedAttributeSet.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/AffectedAttributeSet.php
@@ -32,7 +32,6 @@ use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
 /**
  * Class AffectedAttributeSet
  * Choose affected attribute set dialog popup window
- *
  */
 class AffectedAttributeSet extends Block
 {
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/Attribute/Edit.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/Attribute/Edit.php
index ca9aa487fc4fe4361531b2cdb47bcca6db3e3815..81a2926052b8fe5679056cd2252d8386d44cdfae 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/Attribute/Edit.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Backend/Product/Attribute/Edit.php
@@ -24,15 +24,13 @@
 
 namespace Magento\ConfigurableProduct\Test\Block\Backend\Product\Attribute;
 
-use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
-use Mtf\Fixture\FixtureInterface;
 use Mtf\Client\Element;
 use Magento\Backend\Test\Block\Widget\Form;
-use Mtf\Factory\Factory;
+use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
 
 /**
+ * Class Edit
  * Product attribute edit page
- *
  */
 class Edit extends Form
 {
@@ -66,6 +64,8 @@ class Edit extends Form
 
     /**
      * Open frontend properties
+     *
+     * @return void
      */
     public function openFrontendProperties()
     {
@@ -74,6 +74,8 @@ class Edit extends Form
 
     /**
      * Save attribute
+     *
+     * @return void
      */
     public function saveAttribute()
     {
@@ -83,9 +85,10 @@ class Edit extends Form
     /**
      * Fill attribute options
      *
-     * @param $data
+     * @param array $data
+     * @return void
      */
-    public function fillAttributeOption($data)
+    public function fillAttributeOption(array $data)
     {
         $this->_rootElement->find('#attribute_label')
             ->setValue($data['attribute_options']['attribute_label']);
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php
index 612f3d535c1ebaf0c9abb7e83e68ab3e136be168..70953f1bde5b6861ae50787821920424280d36dc 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php
@@ -24,10 +24,9 @@
 
 namespace Magento\ConfigurableProduct\Test\Constraint;
 
-use Magento\Catalog\Test\Page\Product\CatalogProductView;
-use Magento\Checkout\Test\Page\CheckoutCart;
 use Mtf\Constraint\AbstractConstraint;
-use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+use Magento\Checkout\Test\Page\CheckoutCart;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
 use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
 
 /**
@@ -43,9 +42,12 @@ class AssertConfigurableInCart extends AbstractConstraint
     protected $severeness = 'low';
 
     /**
+     * Assert configurable product, corresponds to the product in the cart
+     *
      * @param CatalogProductView $catalogProductView
      * @param CatalogProductConfigurable $configurable
      * @param CheckoutCart $checkoutCart
+     * @return void
      */
     public function processAssert(
         CatalogProductView $catalogProductView,
@@ -57,10 +59,10 @@ class AssertConfigurableInCart extends AbstractConstraint
         $catalogProductView->open();
         $productOptions = $configurable->getConfigurableOptions();
         if ($productOptions) {
-            $configurableOption = $catalogProductView->getOptionsBlock();
-            $options = $configurableOption->getProductCustomOptions();
+            $configurableOption = $catalogProductView->getCustomOptionsBlock();
+            $options = $configurableOption->getOptions();
             $key = $productOptions['value']['label']['value'];
-            $configurableOption->selectProductCustomOption($options[$key][1]);
+            $configurableOption->selectProductCustomOption(reset($options[$key]['value']));
         }
         $catalogProductView->getViewBlock()->clickAddToCart();
 
@@ -72,6 +74,7 @@ class AssertConfigurableInCart extends AbstractConstraint
      *
      * @param CatalogProductConfigurable $configurable
      * @param CheckoutCart $checkoutCart
+     * @return void
      */
     protected function assertOnShoppingCart(CatalogProductConfigurable $configurable, CheckoutCart $checkoutCart)
     {
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php
index af0866f3aeb8bd5869df43667ed26f36ebc7abf1..52dabb996b5e990a09b03b69858ba93f40a89712 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php
@@ -43,10 +43,13 @@ class AssertConfigurableInCategory extends AbstractConstraint
     protected $severeness = 'low';
 
     /**
+     * Assert configurable product, corresponds to the category page
+     *
      * @param CatalogCategoryView $catalogCategoryView
      * @param CmsIndex $cmsIndex
      * @param CatalogProductConfigurable $configurable
      * @param Category $category
+     * @return void
      */
     public function processAssert(
         CatalogCategoryView $catalogCategoryView,
@@ -67,6 +70,7 @@ class AssertConfigurableInCategory extends AbstractConstraint
      *
      * @param CatalogProductConfigurable $configurable
      * @param CatalogCategoryView $catalogCategoryView
+     * @return void
      */
     protected function assertPrice(
         CatalogProductConfigurable $configurable,
@@ -100,8 +104,8 @@ class AssertConfigurableInCategory extends AbstractConstraint
             $price = $catalogCategoryView->getListProductBlock()
                 ->getProductPriceBlock($configurable->getName())
                 ->getPrice();
-            \PHPUnit_Framework_Assert::assertContains(
-                (string)$price,
+            \PHPUnit_Framework_Assert::assertEquals(
+                '$' . $price['price_regular_price'],
                 $pricePresetData['category_price'],
                 'Product price on category page is not correct.'
             );
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInGrid.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInGrid.php
index 455e55dfb681c286e839fa3682541dc14ac4a360..a127b5bfe5fb2d7a3cb480d4f5c5a5029c8f82db 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInGrid.php
@@ -25,12 +25,11 @@
 namespace Magento\ConfigurableProduct\Test\Constraint;
 
 use Mtf\Constraint\AbstractConstraint;
-use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
 
 /**
  * Class AssertConfigurableInGrid
- *
  */
 class AssertConfigurableInGrid extends AbstractConstraint
 {
@@ -42,24 +41,26 @@ class AssertConfigurableInGrid extends AbstractConstraint
     protected $severeness = 'high';
 
     /**
-     * Assert product availability in Products Grid
+     * Assert product availability in products grid
      *
-     * @param CatalogProductConfigurable $configurable
+     * @param CatalogProductConfigurable $product
      * @param CatalogProductIndex $productPageGrid
      * @return void
      */
-    public function processAssert(CatalogProductConfigurable $configurable, CatalogProductIndex $productPageGrid)
+    public function processAssert(CatalogProductConfigurable $product, CatalogProductIndex $productPageGrid)
     {
-        $filter = ['sku' => $configurable->getSku()];
+        $filter = ['sku' => $product->getSku()];
         $productPageGrid->open();
         \PHPUnit_Framework_Assert::assertTrue(
             $productPageGrid->getProductGrid()->isRowVisible($filter),
-            'Product with sku \'' . $configurable->getSku() . '\' is absent in Products grid.'
+            'Product with sku \'' . $product->getSku() . '\' is absent in Products grid.'
         );
     }
 
     /**
-     * @inheritdoc
+     * Returns a string representation of the object.
+     *
+     * @return string
      */
     public function toString()
     {
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableView.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableView.php
index ce11af86f4265b025ac2dc7f480ec329b6d2cd80..6a047a0f2ea089678c83b32f9986187b9252a13b 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableView.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableView.php
@@ -24,10 +24,8 @@
 
 namespace Magento\ConfigurableProduct\Test\Constraint;
 
-use Magento\Catalog\Test\Page\Product\CatalogProductView;
-use Magento\Checkout\Test\Page\CheckoutCart;
 use Mtf\Constraint\AbstractConstraint;
-use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
 use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
 
 /**
@@ -43,8 +41,11 @@ class AssertConfigurableView extends AbstractConstraint
     protected $severeness = 'low';
 
     /**
+     * Assert configurable product, corresponds to the product page
+     *
      * @param CatalogProductView $catalogProductView
      * @param CatalogProductConfigurable $configurable
+     * @return void
      */
     public function processAssert(
         CatalogProductView $catalogProductView,
@@ -63,6 +64,7 @@ class AssertConfigurableView extends AbstractConstraint
      *
      * @param CatalogProductConfigurable $configurable
      * @param CatalogProductView $catalogProductView
+     * @return void
      */
     protected function assertOnProductView(
         CatalogProductConfigurable $configurable,
@@ -87,11 +89,14 @@ class AssertConfigurableView extends AbstractConstraint
                 'Product special price on product view page is not correct.'
             );
         } else {
-            $price = $catalogProductView->getViewBlock()->getProductPriceBlock()->getPrice();
-            \PHPUnit_Framework_Assert::assertContains(
-                (string)$price,
+            //Price verification
+            $price = $catalogProductView->getViewBlock()
+                ->getProductPriceBlock($configurable->getName())
+                ->getPrice();
+            \PHPUnit_Framework_Assert::assertEquals(
+                '$' . $price['price_regular_price'],
                 $pricePresetData['product_price'],
-                'Product price on product view page is not correct.'
+                'Product price on category page is not correct.'
             );
         }
     }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php
index e97c27b63d50d29aa641f0235a4754b56535e1f0..3edae23277f7ce1fa0d30f326590fee8317923ac 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php
@@ -96,7 +96,7 @@ class CatalogProductConfigurable extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'text',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CategoryIds'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds'
     ];
 
     protected $color = [
@@ -194,7 +194,7 @@ class CatalogProductConfigurable extends InjectableFixture
         'default_value' => '',
         'input' => 'text',
         'group' => 'advanced-pricing',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions'
     ];
 
     protected $has_options = [
@@ -357,7 +357,7 @@ class CatalogProductConfigurable extends InjectableFixture
         'default_value' => '',
         'input' => 'price',
         'group' => 'product-details',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price'
     ];
 
     protected $quantity_and_stock_status = [
@@ -482,7 +482,7 @@ class CatalogProductConfigurable extends InjectableFixture
         'default_value' => '',
         'input' => 'text',
         'group' => 'advanced-pricing',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions'
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions'
     ];
 
     protected $updated_at = [
@@ -559,7 +559,7 @@ class CatalogProductConfigurable extends InjectableFixture
         'backend_type' => 'virtual',
         'is_required' => '0',
         'group' => 'customer-options',
-        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
     ];
 
     protected $configurable_options = [
@@ -568,7 +568,7 @@ class CatalogProductConfigurable extends InjectableFixture
         'is_required' => '0',
         'input' => 'variations',
         'group' => 'product-details',
-        'fixture' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\ConfigurableOptions',
+        'source' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\ConfigurableOptions',
     ];
 
     protected $attribute_options = [
@@ -577,7 +577,7 @@ class CatalogProductConfigurable extends InjectableFixture
         'is_required' => '0',
         'input' => 'variations',
         'group' => 'product-details',
-        'fixture' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\AttributeOptions',
+        'source' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\AttributeOptions',
     ];
 
     public function getCategoryIds()
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php
index 72f6331c95729746886566ba3fe81dcf61b8cf76..0562cf4341d6340947bf60de171bd51e2309a7a3 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php
@@ -26,9 +26,9 @@ namespace Magento\ConfigurableProduct\Test\TestCase\Product;
 
 use Mtf\TestCase\Injectable;
 use Magento\Catalog\Test\Fixture\Category;
-use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
-use Magento\Catalog\Test\Page\Product\CatalogProductNew;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew;
 use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
 
 /**
  * Test Coverage for CreateConfigurableProductEntity
@@ -46,16 +46,22 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
 class CreateConfigurableEntityTest extends Injectable
 {
     /**
+     * Category fixture
+     *
      * @var Category
      */
     protected $category;
 
     /**
+     * Backend catalog page (product grid)
+     *
      * @var CatalogProductIndex
      */
     protected $productPageGrid;
 
     /**
+     * Product page (product form)
+     *
      * @var CatalogProductNew
      */
     protected $newProductPage;
@@ -89,19 +95,21 @@ class CreateConfigurableEntityTest extends Injectable
     }
 
     /**
+     * Run create configurable product test
+     *
      * @param CatalogProductConfigurable $configurable
      * @param Category $category
+     * @return void
      */
     public function testCreate(CatalogProductConfigurable $configurable, Category $category)
     {
         // Steps
         $this->productPageGrid->open();
         $this->productPageGrid->getProductBlock()->addProduct('configurable');
-
-        $productBlockForm = $this->newProductPage->getConfigurableBlockForm();
-
+        // Fill form
+        $productBlockForm = $this->newProductPage->getConfigurableProductForm();
         $productBlockForm->setCategory($category);
         $productBlockForm->fill($configurable);
-        $productBlockForm->save($configurable);
+        $this->newProductPage->getFormAction()->saveProduct($this->newProductPage, $configurable);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php b/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php
index 51c9f99e6dc4c823b5cdf97c5f16b3b726583c43..b1319eceb45a614a35d3289396bfe67d1f583f9c 100644
--- a/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Block/Messages.php
@@ -40,6 +40,13 @@ class Messages extends Block
      */
     protected $successMessage = '[data-ui-id$=message-success]';
 
+    /**
+     * Message link
+     *
+     * @var string
+     */
+    protected $messageLink = "//a[contains(.,'%s')]";
+
     /**
      * Error message selector.
      *
@@ -87,6 +94,36 @@ class Messages extends Block
             ->getText();
     }
 
+    /**
+     * Click on link in the messages which are present on the page
+     *
+     * @param string $messageType
+     * @param string $linkText
+     * @return void
+     */
+    public function clickLinkInMessages($messageType, $linkText)
+    {
+        if ($this->isVisibleMessage($messageType)) {
+            $this->_rootElement
+                ->find($this->{$messageType . 'Message'}, Locator::SELECTOR_CSS)
+                ->find(sprintf($this->messageLink, $linkText), Locator::SELECTOR_XPATH)
+                ->click();
+        }
+    }
+
+    /**
+     * Check is visible messages
+     *
+     * @param string $messageType
+     * @return bool
+     */
+    public function isVisibleMessage($messageType)
+    {
+        return $this->_rootElement
+            ->find($this->{$messageType . 'Message'}, Locator::SELECTOR_CSS)
+            ->isVisible();
+    }
+
     /**
      * Check for error message
      *
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Menu.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Links.php
similarity index 71%
rename from dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Menu.php
rename to dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Links.php
index 56bd1d430a451d0b454dcd54c0ea04de96d02d79..b3163a3227b6478fc43617cae798413978b5833d 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Menu.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Account/Links.php
@@ -18,7 +18,6 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @spi
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
@@ -29,23 +28,26 @@ use Mtf\Block\Block;
 use Mtf\Client\Element\Locator;
 
 /**
- * Menu block
- *
+ * Class Links
+ * Links block on customer account page
  */
-class Menu extends Block
+class Links extends Block
 {
     /**
-     * Address book link selector
+     * XPath locator for account navigation on customer page
      *
      * @var string
      */
-    protected $addressBook = '//li/a[text()[normalize-space()="Address Book"]]';
+    protected $menuItem = '//*[contains(@class,"item")]/a[contains(.,"%s")]';
 
     /**
-     * Click on address book menu item
+     * Select link in menu
+     *
+     * @param string $link
+     * @return void
      */
-    public function goToAddressBook()
+    public function openMenuItem($link)
     {
-        $this->_rootElement->find($this->addressBook, Locator::SELECTOR_XPATH)->click();
+        $this->_rootElement->find(sprintf($this->menuItem, $link), Locator::SELECTOR_XPATH)->click();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.php
index 0d4c89a9b2bea2dd4fe3ec74f430de4e3a2d9649..4b0170c6b5d222479de718204f6a1dc9b1573a1f 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.php
@@ -26,6 +26,7 @@ namespace Magento\Customer\Test\Block\Adminhtml\Edit;
 
 use Mtf\Fixture\FixtureInterface;
 use Magento\Backend\Test\Block\Widget\FormTabs;
+use Mtf\Fixture\InjectableFixture;
 
 /**
  * Class Form
@@ -43,8 +44,10 @@ class Form extends FormTabs
      */
     public function fillCustomer(FixtureInterface $customer, $address = null)
     {
-        parent::fill($customer);
-
+        $isHasData = ($customer instanceof InjectableFixture) ? $customer->hasData() : true;
+        if ($isHasData) {
+            parent::fill($customer);
+        }
         if (null !== $address) {
             $this->openTab('addresses');
             $this->getTabElement('addresses')->fillAddresses($address);
@@ -54,21 +57,42 @@ class Form extends FormTabs
     }
 
     /**
-     * Verify Customer information, addresses on tabs.
+     * Update Customer forms on tabs by customer, addresses data
+     *
+     * @param FixtureInterface $customer
+     * @param FixtureInterface|FixtureInterface[]|null $address
+     * @return $this
+     */
+    public function updateCustomer(FixtureInterface $customer, $address = null)
+    {
+        $isHasData = ($customer instanceof InjectableFixture) ? $customer->hasData() : true;
+        if ($isHasData) {
+            parent::fill($customer);
+        }
+        if (null !== $address) {
+            $this->openTab('addresses');
+            $this->getTabElement('addresses')->updateAddresses($address);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get data of Customer information, addresses on tabs.
      *
      * @param FixtureInterface $customer
      * @param FixtureInterface|FixtureInterface[]|null $address
-     * @return bool
+     * @return array
      */
-    public function verifyCustomer(FixtureInterface $customer, $address = null)
+    public function getDataCustomer(FixtureInterface $customer, $address = null)
     {
-        $isVerify = parent::verify($customer);
+        $data = ['customer' => $customer->hasData() ? parent::getData($customer) : parent::getData()];
 
         if (null !== $address) {
             $this->openTab('addresses');
-            $isVerify = $isVerify && $this->getTabElement('addresses')->verifyAddresses($address);
+            $data['addresses'] = $this->getTabElement('addresses')->getDataAddresses($address);
         }
 
-        return $isVerify;
+        return $data;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.xml
index 2ca9a0395044cb1aee7e505ff379b41c244dd0bc..d2b2bf419058d00c41720d877fb4c6e5324d3a00 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Form.xml
@@ -36,6 +36,9 @@
             <group_id>
                 <input>select</input>
             </group_id>
+            <firstname/>
+            <lastname/>
+            <email/>
             <gender>
                 <input>select</input>
             </gender>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.php
index 7293761596a612a69755b9029d432d83f1673a77..9bee1e823f4d2f4624efc3294d6ac154f84bfade 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.php
@@ -27,6 +27,7 @@ namespace Magento\Customer\Test\Block\Adminhtml\Edit\Tab;
 use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
 use Mtf\Fixture\FixtureInterface;
+use Magento\Customer\Test\Fixture\AddressInjectable;
 use Magento\Backend\Test\Block\Widget\Tab;
 
 /**
@@ -50,48 +51,115 @@ class Addresses extends Tab
      */
     protected $customerAddress = '//*[@id="address_list"]/li[%d]/a';
 
+    /**
+     * Magento loader
+     *
+     * @var string
+     */
+    protected $loader = '//ancestor::body/div[@data-role="loader"]';
+
     /**
      * Fill customer addresses
      *
-     * @param FixtureInterface|FixtureInterface[]|null $address
+     * @param FixtureInterface|FixtureInterface[] $address
      * @return $this
      */
     public function fillAddresses($address)
     {
-        if (null !== $address) {
-            $addresses = is_array($address) ? $address : [$address];
-
-            foreach ($addresses as $address) {
-                if ($address->hasData()) {
-                    $this->addNewAddress();
-                    $this->fillFormTab($address->getData(), $this->_rootElement);
-                }
+        $addresses = is_array($address) ? $address : [$address];
+        foreach ($addresses as $address) {
+            $this->addNewAddress();
+
+            /* Fix switch between region_id and region */
+            /** @var AddressInjectable $address */
+            $countryId = $address->getCountryId();
+            if ($countryId && $this->mapping['country_id']) {
+                $this->_fill($this->dataMapping(['country_id' => $countryId]));
+                $this->waitForElementNotVisible($this->loader, Locator::SELECTOR_XPATH);
             }
+
+            $this->fillFormTab($address->getData(), $this->_rootElement);
         }
 
         return $this;
     }
 
     /**
-     * Verify customer addresses
+     * Update customer addresses
+     *
+     * @param FixtureInterface|FixtureInterface[] $address
+     * @return $this
+     * @throws \Exception
+     */
+    public function updateAddresses($address)
+    {
+        $addresses = is_array($address) ? $address : [1 => $address];
+        foreach ($addresses as $addressNumber => $address) {
+            /* Throw exception if isn't exist previous customer address. */
+            if (1 < $addressNumber && !$this->isVisibleCustomerAddress($addressNumber - 1)) {
+                throw new \Exception("Invalid argument: can't update customer address #{$addressNumber}");
+            }
+
+            if (!$this->isVisibleCustomerAddress($addressNumber)) {
+                $this->addNewAddress();
+            }
+            $this->openCustomerAddress($addressNumber);
+
+            /* Fix switch between region_id and region */
+            /** @var AddressInjectable $address */
+            $countryId = $address->getCountryId();
+            if ($countryId && $this->mapping['country_id']) {
+                $this->_fill($this->dataMapping(['country_id' => $countryId]));
+                $this->waitForElementNotVisible($this->loader, Locator::SELECTOR_XPATH);
+            }
+            $this->fillFormTab($address->getData(), $this->_rootElement);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get data of Customer addresses
      *
      * @param FixtureInterface|FixtureInterface[]|null $address
-     * @return bool
+     * @return array
+     * @throws \Exception
      */
-    public function verifyAddresses($address)
+    public function getDataAddresses($address = null)
     {
+        $data = [];
         $addresses = is_array($address) ? $address : [1 => $address];
 
         foreach ($addresses as $addressNumber => $address) {
-            if ($address->hasData()) {
+            $isHasData = (null === $address) || $address->hasData();
+            $isVisibleCustomerAddress = $this->isVisibleCustomerAddress($addressNumber);
+
+            if ($isHasData && !$isVisibleCustomerAddress) {
+                throw new \Exception("Invalid argument: can't get data from customer address #{$addressNumber}");
+            }
+
+            if (!$isHasData && !$isVisibleCustomerAddress) {
+                $data[$addressNumber] = [];
+            } else {
                 $this->openCustomerAddress($addressNumber);
-                if (!$this->verifyFormTab($address->getData(), $this->_rootElement)) {
-                    return false;
-                }
+                $data[$addressNumber] = $this->getData($address, $this->_rootElement);
             }
         }
 
-        return true;
+        return $data;
+    }
+
+    /**
+     * Get data to fields on tab
+     *
+     * @param array|null $fields
+     * @param Element|null $element
+     * @return array
+     */
+    public function getDataFormTab($fields = null, Element $element = null)
+    {
+        /* Skip get data for standard method. Use getDataAddresses. */
+        return [];
     }
 
     /**
@@ -120,4 +188,19 @@ class Addresses extends Tab
         }
         $addressTab->click();
     }
+
+    /**
+     * Check is visible customer address
+     *
+     * @param int $addressNumber
+     * @return bool
+     */
+    protected function isVisibleCustomerAddress($addressNumber)
+    {
+        $addressTab = $this->_rootElement->find(
+            sprintf($this->customerAddress, $addressNumber),
+            Locator::SELECTOR_XPATH
+        );
+        return $addressTab->isVisible();
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml
index bc7fe100f89e2957eb68b1712611d025221d4508..0dad9cbefbe0de6260968a7864d53eedcb502487 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Edit/Tab/Addresses.xml
@@ -25,14 +25,30 @@
 -->
 <mapping strict="0">
     <fields>
+        <prefix>
+            <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[prefix]"]</selector>
+            <strategy>css selector</strategy>
+        </prefix>
         <firstname>
             <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[firstname]"]</selector>
             <strategy>css selector</strategy>
         </firstname>
+        <middlename>
+            <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[middlename]"]</selector>
+            <strategy>css selector</strategy>
+        </middlename>
         <lastname>
             <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[lastname]"]</selector>
             <strategy>css selector</strategy>
         </lastname>
+        <suffix>
+            <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[suffix]"]</selector>
+            <strategy>css selector</strategy>
+        </suffix>
+        <company>
+            <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[company]"]</selector>
+            <strategy>css selector</strategy>
+        </company>
         <street>
             <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[street][0]"]</selector>
             <strategy>css selector</strategy>
@@ -51,6 +67,10 @@
             <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[region_id]"]</selector>
             <strategy>css selector</strategy>
         </region_id>
+        <region>
+            <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[region]"]</selector>
+            <strategy>css selector</strategy>
+        </region>
         <postcode>
             <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[postcode]"]</selector>
             <strategy>css selector</strategy>
@@ -59,5 +79,13 @@
             <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[telephone]"]</selector>
             <strategy>css selector</strategy>
         </telephone>
+        <fax>
+            <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[fax]"]</selector>
+            <strategy>css selector</strategy>
+        </fax>
+        <vat_id>
+            <selector>#address_form_container [aria-hidden="false"] [name^="address"][name$="[vat_id]"]</selector>
+            <strategy>css selector</strategy>
+        </vat_id>
     </fields>
 </mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/SpecialOption.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/CustomerGroupGrid.php
similarity index 68%
rename from dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/SpecialOption.php
rename to dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/CustomerGroupGrid.php
index 6a985b014869f9a5b058ab86b5fb6f11b886b654..c34b09d69dc753d26c54043fab386806fee5f7e7 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/AdvancedPricingTab/SpecialOption.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/CustomerGroupGrid.php
@@ -22,26 +22,26 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Catalog\Test\Block\Adminhtml\Product\Edit\AdvancedPricingTab;
+namespace Magento\Customer\Test\Block\Adminhtml\Group;
 
-use Mtf\Client\Element;
-use Mtf\Client\Element\Locator;
-use Mtf\Block\Block;
+use Magento\Backend\Test\Block\Widget\Grid;
 
 /**
- * Select Type
+ * Class CustomerGroupGrid
+ * Adminhtml customer group grid
+ *
+ * @package  Magento\Customer\Test\Block\Adminhtml\Group
  */
-class SpecialOption extends Block
+class CustomerGroupGrid extends Grid
 {
     /**
-     * Fill
+     * Initialize block elements
      *
-     * @param array $data
+     * @var array $filters
      */
-    public function fill($data)
-    {
-        if (isset($data['value'])) {
-            $this->_rootElement->find('#special_price', Locator::SELECTOR_CSS)->setValue($data['value']);
-        }
-    }
+    protected $filters = [
+        'code' => [
+            'selector' => '#customerGroupGrid_filter_type'
+        ]
+    ];
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e9fa7036e16194d7dd129e9000c660ef8a83491
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Block\Adminhtml\Group\Edit;
+
+use Magento\Backend\Test\Block\Widget\Form as AbstractForm;
+
+/**
+ * Class Form
+ * Customer group edit form
+ *
+ * @package Magento\Customer\Test\Block\Adminhtml\Group\Edit
+ */
+class Form extends AbstractForm
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.xml
new file mode 100644
index 0000000000000000000000000000000000000000..98d30a134b2dc258748aa53c83e9e9be805d218e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Adminhtml/Group/Edit/Form.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <code />
+        <tax_class_id>
+            <selector>#tax_class_id</selector>
+            <input>select</input>
+        </tax_class_id>
+        <customer_group_code>
+            <selector>#customer_group_code</selector>
+        </customer_group_code>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Login.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Login.php
index 5b429bdcd7ef43224346b2d126b9cd9e61b971ca..c9881283b0c0137e5a2fd9b0443f06754fbcfbc6 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Login.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Form/Login.php
@@ -27,12 +27,11 @@ namespace Magento\Customer\Test\Block\Form;
 use Mtf\Block\Form;
 use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
-use Magento\Customer\Test\Fixture\Customer;
+use Mtf\Fixture\FixtureInterface;
 
 /**
  * Class Login
  * Form for frontend login
- *
  */
 class Login extends Form
 {
@@ -53,11 +52,11 @@ class Login extends Form
     /**
      * Login customer in the Frontend
      *
-     * @param Customer $fixture
+     * @param FixtureInterface $customer
      */
-    public function login(Customer $fixture)
+    public function login(FixtureInterface $customer)
     {
-        $this->fill($fixture);
+        $this->fill($customer);
         $this->submit();
         $this->waitForElementNotVisible($this->loginButton, Locator::SELECTOR_CSS);
     }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerForm.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerForm.php
index 9fa15d1de4a8aa003236b1593bb8e7ce59d81a49..ddeb6b47b4aec1cc48df2c105a4d27a908b8e4b5 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerForm.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerForm.php
@@ -31,7 +31,7 @@ use Magento\Customer\Test\Page\Adminhtml\CustomerIndex;
 use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit;
 
 /**
- * Class AssertCustomerInGrid
+ * Class AssertCustomerForm
  *
  */
 class AssertCustomerForm extends AbstractConstraint
@@ -43,6 +43,18 @@ class AssertCustomerForm extends AbstractConstraint
      */
     protected $severeness = 'middle';
 
+    /**
+     * Skipped fields for verify data
+     *
+     * @var array
+     */
+    protected $customerSkippedFields = [
+        'id',
+        'password',
+        'password_confirmation',
+        'is_subscribed',
+    ];
+
     /**
      * Assert that displayed customer data on edit page(backend) equals passed from fixture
      *
@@ -50,24 +62,73 @@ class AssertCustomerForm extends AbstractConstraint
      * @param CustomerIndex $pageCustomerIndex
      * @param CustomerIndexEdit $pageCustomerIndexEdit
      * @param AddressInjectable $address [optional]
+     * @param CustomerInjectable $initialCustomer [optional]
      * @return void
      */
     public function processAssert(
         CustomerInjectable $customer,
         CustomerIndex $pageCustomerIndex,
         CustomerIndexEdit $pageCustomerIndexEdit,
-        AddressInjectable $address = null
+        AddressInjectable $address = null,
+        CustomerInjectable $initialCustomer = null
     ) {
-        $filter = ['email' => $customer->getEmail()];
+        $data = [];
+        $filter = [];
+
+        if ($initialCustomer) {
+            $data['customer'] = $customer->hasData()
+                ? array_merge($initialCustomer->getData(), $customer->getData())
+                : $initialCustomer->getData();
+        } else {
+            $data['customer'] = $customer->getData();
+        }
+        if ($address) {
+            $data['addresses'][1] = $address->hasData() ? $address->getData() : [];
+        } else {
+            $data['addresses'] = [];
+        }
+        $filter['email'] = $data['customer']['email'];
 
         $pageCustomerIndex->open();
         $pageCustomerIndex->getCustomerGridBlock()->searchAndOpen($filter);
+        $dataForm = $pageCustomerIndexEdit->getCustomerForm()->getDataCustomer($customer, $address);
+        $dataDiff = $this->verify($data, $dataForm);
         \PHPUnit_Framework_Assert::assertTrue(
-            $pageCustomerIndexEdit->getCustomerForm()->verifyCustomer($customer, $address),
+            empty($dataDiff),
             'Customer data on edit page(backend) not equals to passed from fixture.'
+            . "\nFailed values: " . implode(', ', $dataDiff)
         );
     }
 
+    /**
+     * Verify data in form equals to passed from fixture
+     *
+     * @param array $dataFixture
+     * @param array $dataForm
+     * @return array
+     */
+    protected function verify(array $dataFixture, array $dataForm)
+    {
+        $result = [];
+
+        $customerDiff = array_diff_assoc($dataFixture['customer'], $dataForm['customer']);
+        foreach ($customerDiff as $name => $value) {
+            if (in_array($name, $this->customerSkippedFields)) {
+                continue;
+            }
+            $result[] = "\ncustomer {$name}: \"{$dataForm['customer'][$name]}\" instead of \"{$value}\"";
+        }
+        foreach ($dataFixture['addresses'] as $key => $address) {
+            $addressDiff = array_diff($address, $dataForm['addresses'][$key]);
+            foreach ($addressDiff as $name => $value) {
+                $result[] = "\naddress #{$key} {$name}: \"{$dataForm['addresses'][$key][$name]}"
+                . "\" instead of \"{$value}\"";
+            }
+        }
+
+        return $result;
+    }
+
     /**
      * Text success verify Customer form
      *
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupAlreadyExists.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupAlreadyExists.php
new file mode 100644
index 0000000000000000000000000000000000000000..469dda30552d171967f4932dc75c350718f39217
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupAlreadyExists.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Constraint;
+
+use Magento\Customer\Test\Page\Adminhtml\CustomerGroupNew;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertCustomerGroupAlreadyExists
+ *
+ * @package Magento\Customer\Test\Constraint
+ */
+class AssertCustomerGroupAlreadyExists extends AbstractConstraint
+{
+    const SUCCESS_MESSAGE = 'Customer Group already exists.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that customer group already exist
+     *
+     * @param CustomerGroupNew $customerGroupNew
+     * @return void
+     */
+    public function processAssert(CustomerGroupNew $customerGroupNew)
+    {
+        $actualMessage = $customerGroupNew->getMessagesBlock()->getErrorMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $actualMessage,
+            'Wrong error message is displayed.'
+        );
+    }
+
+    /**
+     * Success assert of customer group already exist
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Customer group already exist.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupInGrid.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..3cebe3e3c456579b2bd57025ac08c656ad5430b7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupInGrid.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Constraint;
+
+use Magento\Customer\Test\Fixture\CustomerGroupInjectable;
+use Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertCustomerGroupInGrid
+ */
+class AssertCustomerGroupInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that customer group in grid
+     *
+     * @param CustomerGroupInjectable $customerGroup
+     * @param CustomerGroupIndex $customerGroupIndex
+     * @return void
+     */
+    public function processAssert(
+        CustomerGroupInjectable $customerGroup,
+        CustomerGroupIndex $customerGroupIndex
+    ) {
+        $customerGroupIndex->open();
+        $filter = ['code' => $customerGroup->getCustomerGroupCode()];
+        \PHPUnit_Framework_Assert::assertTrue(
+            $customerGroupIndex->getCustomerGroupGrid()->isRowVisible($filter),
+            'Group with type \'' . $customerGroup->getCustomerGroupCode() . '\'is absent in customer groups grid.'
+        );
+    }
+
+    /**
+     * Success assert of  customer group in grid
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Customer group in grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupNotInGrid.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupNotInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..46cb28896ae754f1c75ccf200e6ca2ba59f8115e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupNotInGrid.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Constraint;
+
+use Magento\Customer\Test\Fixture\CustomerGroupInjectable;
+use Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertCustomerGroupNotInGrid
+ */
+class AssertCustomerGroupNotInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that customer group not in grid
+     *
+     * @param CustomerGroupInjectable $customerGroup
+     * @param CustomerGroupIndex $customerGroupIndex
+     * @return void
+     */
+    public function processAssert(
+        CustomerGroupInjectable $customerGroup,
+        CustomerGroupIndex $customerGroupIndex
+    ) {
+        $customerGroupIndex->open();
+        $filter = ['code' => $customerGroup->getCustomerGroupCode()];
+        \PHPUnit_Framework_Assert::assertFalse(
+            $customerGroupIndex->getCustomerGroupGrid()->isRowVisible($filter),
+            'Group with name \'' . $customerGroup->getCustomerGroupCode() . '\' in customer groups grid.'
+        );
+    }
+
+    /**
+     * Success assert of  customer group not in grid.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Customer group not in grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCustomerForm.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCustomerForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a61edc9c015f0f8f8e1523cc1e5532f2f6a11bf
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCustomerForm.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Constraint;
+
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Customer\Test\Page\Adminhtml\CustomerIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Customer\Test\Fixture\CustomerGroupInjectable;
+use Magento\Customer\Test\Page\Adminhtml\CustomerIndexNew;
+use Mtf\Fixture\FixtureFactory;
+
+/**
+ * Class AssertCustomerGroupOnCustomerForm
+ */
+class AssertCustomerGroupOnCustomerForm extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that customer group find on account information page
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @param CustomerGroupInjectable $customerGroup
+     * @param CustomerIndexNew $customerIndexNew
+     * @param CustomerIndex $customerIndex
+     * @return void
+     */
+    public function processAssert(
+        FixtureFactory $fixtureFactory,
+        CustomerGroupInjectable $customerGroup,
+        CustomerIndexNew $customerIndexNew,
+        CustomerIndex $customerIndex
+    ) {
+        /** @var CustomerInjectable $customer */
+        $customer = $fixtureFactory->createByCode(
+            'customerInjectable',
+            [
+                'dataSet' => 'defaultBackend',
+                'data' => ['group_id' => $customerGroup->getCustomerGroupCode()]
+            ]
+        );
+        $filter = ['email' => $customer->getEmail()];
+
+        $customerIndexNew->open();
+        $customerIndexNew->getCustomerForm()->fillCustomer($customer);
+        $customerIndexNew->getPageActionsBlock()->save();
+        $customerIndex->getCustomerGridBlock()->searchAndOpen($filter);
+        $customerFormData = $customerIndexNew->getCustomerForm()->getData($customer);
+        $customerFixtureData = $customer->getData();
+        $diff = array_diff($customerFixtureData, $customerFormData);
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($diff),
+            "Customer group {$customerGroup->getCustomerGroupCode()} not in customer form."
+        );
+    }
+
+    /**
+     * Success assert of customer group find on account information page
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Customer group find on account information page.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupSuccessCreateMessage.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupSuccessCreateMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..dfe1501cb5804be19b1f30abcdf7d5d21e709ba8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupSuccessCreateMessage.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex;
+
+/**
+ * Class AssertCustomerGroupSuccessCreateMessage
+ *
+ * @package Magento\Customer\Test\Constraint
+ */
+class AssertCustomerGroupSuccessCreateMessage extends AbstractConstraint
+{
+    const SUCCESS_MESSAGE = 'The customer group has been saved.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that success message is displayed after customer group save
+     *
+     * @param CustomerGroupIndex $customerGroupIndex
+     * @return void
+     */
+    public function processAssert(CustomerGroupIndex $customerGroupIndex)
+    {
+        $actualMessage = $customerGroupIndex->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Success assert of created customer group success message.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Customer group success save message is present.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInGrid.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInGrid.php
index 1cf54322d872a21fe0e4afe3fae06adb0dd8219f..dc229c13a6101ccd65ff5f3f274ae8e5bdd743ee 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerInGrid.php
@@ -46,18 +46,29 @@ class AssertCustomerInGrid extends AbstractConstraint
      *
      * @param CustomerInjectable $customer
      * @param CustomerIndex $pageCustomerIndex
+     * @param CustomerInjectable $initialCustomer [optional]
      * @return void
      */
-    public function processAssert(CustomerInjectable $customer, CustomerIndex $pageCustomerIndex)
-    {
-        $name = ($customer->hasData('prefix') ? $customer->getPrefix() . ' ' : '')
-            . $customer->getFirstname()
-            . ($customer->hasData('middlename') ? ' ' . $customer->getMiddlename() : '')
-            . ' ' . $customer->getLastname()
-            . ($customer->hasData('suffix') ? ' ' . $customer->getSuffix() : '');
+    public function processAssert(
+        CustomerInjectable $customer,
+        CustomerIndex $pageCustomerIndex,
+        CustomerInjectable $initialCustomer = null
+    ) {
+        if ($initialCustomer) {
+            $customer = $customer->hasData()
+                ? array_merge($initialCustomer->getData(), $customer->getData())
+                : $initialCustomer->getData();
+        } else {
+            $customer = $customer->getData();
+        }
+        $name = (isset($customer['prefix']) ? $customer['prefix'] . ' ' : '')
+            . $customer['firstname']
+            . (isset($customer['middlename']) ? ' ' . $customer['middlename'] : '')
+            . ' ' . $customer['lastname']
+            . (isset($customer['suffix']) ? ' ' . $customer['suffix'] : '');
         $filter = [
             'name' => $name,
-            'email' => $customer->getEmail(),
+            'email' => $customer['email'],
         ];
 
         $pageCustomerIndex->open();
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessRegisterMessage.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessRegisterMessage.php
index d7e8defda2d430b7f8fff6364be23350465bfbda..8d7a4ecd3ae431e0064dbf7f11927264277349d0 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessRegisterMessage.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessRegisterMessage.php
@@ -50,7 +50,7 @@ class AssertCustomerSuccessRegisterMessage extends AbstractConstraint
      */
     public function processAssert(CustomerAccountCreate $registerPage)
     {
-        $actualMessage = $registerPage->getMessageBlock()->getSuccessMessages();
+        $actualMessage = $registerPage->getMessagesBlock()->getSuccessMessages();
         \PHPUnit_Framework_Assert::assertEquals(
             self::SUCCESS_MESSAGE,
             $actualMessage,
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroup/TaxClassIds.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroup/TaxClassIds.php
new file mode 100644
index 0000000000000000000000000000000000000000..838822246a20206277ad63ca8219e6abc666d2b4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroup/TaxClassIds.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Fixture\CustomerGroup;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+
+/**
+ * Class TaxClass
+ * @package Magento\Customer\Test\Fixture
+ */
+class TaxClassIds implements FixtureInterface
+{
+    /** @var string Data */
+    protected $data;
+
+    /**
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(
+        FixtureFactory $fixtureFactory,
+        array $params,
+        array $data
+    ) {
+        $this->params = $params;
+        if (isset($data['dataSet']) && $data['dataSet'] !== '-') {
+            $dataSet = $data['dataSet'];
+            /** @var \Magento\Tax\Test\Fixture\TaxClass $taxClass */
+            $taxClass = $fixtureFactory->createByCode('taxClass', ['dataSet' => $dataSet]);
+            if (!$taxClass->hasData('id')) {
+                $taxClass->persist();
+            }
+            $this->data = $taxClass->getClassName();
+        }
+    }
+
+    /**
+     * Persist custom selections products
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param $key [optional]
+     * @return mixed
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return string
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.php
new file mode 100644
index 0000000000000000000000000000000000000000..07ba892a115e67d714bcebf8233400a3b1c220c2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class CustomerGroupInjectable
+ */
+class CustomerGroupInjectable extends InjectableFixture
+{
+    protected $defaultDataSet = [
+        'customer_group_code' => 'customer_code_%isolation%',
+        'tax_class_id' => 'Retail Customer',
+    ];
+
+    protected $customer_group_code = [
+        'attribute_code' => 'code',
+        'backend_type' => 'varchar',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $tax_class_id = [
+        'attribute_code' => 'tax_class',
+        'backend_type' => 'varchar',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'select',
+        'source' => 'Magento\Customer\Test\Fixture\CustomerGroup\TaxClassIds',
+    ];
+
+    public function getCustomerGroupCode()
+    {
+        return $this->getData('customer_group_code');
+    }
+
+    public function getTaxClassId()
+    {
+        return $this->getData('tax_class_id');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7a57153862b0aa19ec9b10a1f27473475b35f8f4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerGroupInjectable.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Customer\Test\Fixture\CustomerGroup">
+    <module>Magento_Customer</module>
+    <type>flat</type>
+    <entity_type>customer_group</entity_type>
+    <collection>Magento\Customer\Model\Resource\Group\Collection</collection>
+    <fields>
+        <customer_group_code>
+            <attribute_code>code</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>1</is_required>
+            <default_value>customer_code_%isolation%</default_value>
+            <input>text</input>
+        </customer_group_code>
+        <tax_class_id>
+            <attribute_code>tax_class</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>1</is_required>
+            <default_value>Retail Customer</default_value>
+            <input>select</input>
+        </tax_class_id>
+    </fields>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.php
index 81aad2818c74fef9115f0259018389e84a01b016..cbeb35f7767d5e88eb336bd51afcb4e859481c5d 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.php
@@ -28,7 +28,7 @@ use Mtf\Fixture\InjectableFixture;
 
 /**
  * Class CustomerInjectable
- *
+ * Customer fixture
  */
 class CustomerInjectable extends InjectableFixture
 {
@@ -46,6 +46,8 @@ class CustomerInjectable extends InjectableFixture
         'firstname' => 'John',
         'lastname' => 'Doe',
         'email' => 'John.Doe%isolation%@example.com',
+        'password' => '123123q',
+        'password_confirmation' => '123123q',
     ];
 
     protected $confirmation = [
@@ -200,6 +202,7 @@ class CustomerInjectable extends InjectableFixture
         'is_required' => '1',
         'default_value' => '',
         'input' => 'select',
+        'group' => 'account_information',
     ];
 
     protected $suffix = [
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.xml
index d644d70feca043a195be3e2173f469646e2c7c9f..439a6cb0d5d27662a3af8c24ebc08e5312eea0d3 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Fixture/CustomerInjectable.xml
@@ -165,6 +165,7 @@
             <is_required>1</is_required>
             <default_value></default_value>
             <input>select</input>
+            <group>account_information</group>
         </store_id>
         <suffix>
             <attribute_code>suffix</attribute_code>
@@ -203,6 +204,5 @@
             <backend_type>virtual</backend_type>
         </password_confirmation>
     </fields>
-    <repository_class>Magento\Customer\Test\Repository\CustomerInjectable</repository_class>
     <handler_interface>Magento\Customer\Test\Handler\CustomerInjectable\CustomerInjectableInterface</handler_interface>
 </fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/Curl.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee6b0900557ddca3eb32491395fc1185359f7b8d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/Curl.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Handler\CustomerInjectable;
+
+use Mtf\System\Config;
+use Mtf\Handler\Curl as AbstractCurl;
+use Mtf\Util\Protocol\CurlInterface;
+use Mtf\Util\Protocol\CurlTransport;
+use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
+use Mtf\Fixture\FixtureInterface;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+
+/**
+ * Class Curl
+ * Curl handler for creating customer through registration page.
+ */
+class Curl extends AbstractCurl implements CustomerInjectableInterface
+{
+    /**
+     * Post request for creating customer in frontend
+     *
+     * @param FixtureInterface|null $customer
+     * @return array
+     * @throws \Exception
+     */
+    public function persist(FixtureInterface $customer = null)
+    {
+        /** @var CustomerInjectable $customer */
+        $url = $_ENV['app_frontend_url'] . 'customer/account/createpost/?nocookie=true';
+        $data = $customer->getData();
+        $curl = new CurlTransport();
+
+        $curl->write(CurlInterface::POST, $url, '1.0', array(), $data);
+        $response = $curl->read();
+        $curl->close();
+        if (!strpos($response, 'data-ui-id="global-messages-message-success"')) {
+            throw new \Exception("Customer entity creating  by curl handler was not successful! Response: $response");
+        }
+
+        return ['id' => $this->getCustomerId($customer->getEmail())];
+    }
+
+    /**
+     * Get customer id by email
+     *
+     * @param string $email
+     * @return int|null
+     */
+    protected function getCustomerId($email)
+    {
+        $filter = ['email' => $email];
+        $url = $_ENV['app_backend_url'] . 'customer/index/grid/filter/' . $this->encodeFilter($filter);
+        $curl = new BackendDecorator(new CurlTransport(), new Config());
+
+        $curl->write(CurlInterface::GET, $url, '1.0');
+        $response = $curl->read();
+        $curl->close();
+
+        preg_match('/data-column="entity_id"[^>]*>\s*([0-9]+)\s*</', $response, $match);
+        return empty($match[1]) ? null : $match[1];
+    }
+
+    /**
+     * Encoded filter parameters
+     *
+     * @param array $filter
+     * @return string
+     */
+    protected function encodeFilter(array $filter)
+    {
+        $result = [];
+        foreach ($filter as $name => $value) {
+            $result[] = "{$name}={$value}";
+        }
+        $result = implode('&', $result);
+
+        return base64_encode($result);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/CustomerInjectableInterface.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/CustomerInjectableInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..e7218de7541d711fa53511f81da33e61e38a2f63
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Handler/CustomerInjectable/CustomerInjectableInterface.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Handler\CustomerInjectable;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface CustomerInjectableInterface
+ *
+ * @package Magento\Customer\Test\Handler\CustomerInjectable
+ */
+interface CustomerInjectableInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..15ce7e19b5b684ee94a9051d5aaa020517ea9ef0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class CustomerGroupIndex
+ *
+ * @package Magento\Customer\Test\Page\Adminhtml
+ */
+class CustomerGroupIndex extends BackendPage
+{
+    const MCA = 'customer/group/index';
+
+    protected $_blocks = [
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages .messages',
+            'strategy' => 'css selector',
+        ],
+        'gridPageActions' => [
+            'name' => 'gridPageActions',
+            'class' => 'Magento\Backend\Test\Block\GridPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'customerGroupGrid' => [
+            'name' => 'customerGroupGrid',
+            'class' => 'Magento\Customer\Test\Block\Adminhtml\Group\CustomerGroupGrid',
+            'locator' => '#customerGroupGrid',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+
+    /**
+     * @return \Magento\Backend\Test\Block\GridPageActions
+     */
+    public function getGridPageActions()
+    {
+        return $this->getBlockInstance('gridPageActions');
+    }
+
+    /**
+     * @return \Magento\Customer\Test\Block\Adminhtml\Group\CustomerGroupGrid
+     */
+    public function getCustomerGroupGrid()
+    {
+        return $this->getBlockInstance('customerGroupGrid');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f3b4512fc8dac97fe105a8f8841f469b848a7ca9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupIndex.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="customer/group/index">
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages .messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>gridPageActions</name>
+        <class>Magento\Backend\Test\Block\GridPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>customerGroupGrid</name>
+        <class>Magento\Customer\Test\Block\Adminhtml\Group\CustomerGroupGrid</class>
+        <locator>#customerGroupGrid</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.php
new file mode 100644
index 0000000000000000000000000000000000000000..4e69b6f77d5ee24d8042a0fe146629039d84d2e1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class CustomerGroupNew
+ *
+ * @package Magento\Customer\Test\Page\Adminhtml
+ */
+class CustomerGroupNew extends BackendPage
+{
+    const MCA = 'customer/group/new';
+
+    protected $_blocks = [
+        'pageMainActions' => [
+            'name' => 'pageMainActions',
+            'class' => 'Magento\Backend\Test\Block\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'pageMainForm' => [
+            'name' => 'pageMainForm',
+            'class' => 'Magento\Customer\Test\Block\Adminhtml\Group\Edit\Form',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Backend\Test\Block\FormPageActions
+     */
+    public function getPageMainActions()
+    {
+        return $this->getBlockInstance('pageMainActions');
+    }
+
+    /**
+     * @return \Magento\Customer\Test\Block\Adminhtml\Group\Edit\Form
+     */
+    public function getPageMainForm()
+    {
+        return $this->getBlockInstance('pageMainForm');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.xml
new file mode 100644
index 0000000000000000000000000000000000000000..17794ef92a6d63e40e01bbb744e219677f1ef86e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/Adminhtml/CustomerGroupNew.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="customer/group/new" >
+    <block>
+        <name>pageMainActions</name>
+        <class>Magento\Backend\Test\Block\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>pageMainForm</name>
+        <class>Magento\Customer\Test\Block\Adminhtml\Group\Edit\Form</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.php
index 0f0ddda8ecba071d62b555b465fdf23014f5b702..767b36ee76280d9155ef02c82291978d687645cf 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.php
@@ -41,8 +41,8 @@ class CustomerAccountCreate extends FrontendPage
             'locator' => '#form-validate',
             'strategy' => 'css selector',
         ],
-        'messageBlock' => [
-            'name' => 'messageBlock',
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
             'class' => 'Magento\Core\Test\Block\Messages',
             'locator' => '.page.messages',
             'strategy' => 'css selector',
@@ -60,8 +60,8 @@ class CustomerAccountCreate extends FrontendPage
     /**
      * @return \Magento\Core\Test\Block\Messages
      */
-    public function getMessageBlock()
+    public function getMessagesBlock()
     {
-        return $this->getBlockInstance('messageBlock');
+        return $this->getBlockInstance('messagesBlock');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml
index 62e0f9fa87c0abf5e2a0f6628ad7209062ead436..bfa92b466f367c0f327714ea96f0b02dcd466546 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountCreate.xml
@@ -31,7 +31,7 @@
         <strategy>css selector</strategy>
     </block>
     <block>
-        <name>messageBlock</name>
+        <name>messagesBlock</name>
         <class>Magento\Core\Test\Block\Messages</class>
         <locator>.page.messages</locator>
         <strategy>css selector</strategy>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.php
index 214582417afda21c8e353b70f9c32adcb553e998..ca68f19c111f3ed9bb2715144268538e4cf798cf 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.php
@@ -25,99 +25,74 @@
 
 namespace Magento\Customer\Test\Page;
 
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
+use Mtf\Page\FrontendPage;
 
 /**
- * Frontend Customer Dashboard page
- *
+ * Class CustomerAccountIndex
+ * Page of customer account
  */
-class CustomerAccountIndex extends Page
+class CustomerAccountIndex extends FrontendPage
 {
-    /**
-     * URL for customer Dashboard
-     */
     const MCA = 'customer/account/index';
 
-    /**
-     * Messages block
-     *
-     * @var string
-     */
-    protected $messagesBlock = '.page.messages';
-
-    /**
-     * Address Book block
-     *
-     * @var string
-     */
-    protected $dashboardAddressBlock = '.block.dashboard.addresses';
-
-    /**
-     * Dashboard title
-     *
-     * @var string
-     */
-    protected $titleBlock = '.page.title';
-
-    /**
-     * Account menu selector
-     *
-     * @var string
-     */
-    protected $accountMenuSelector = '.nav.items';
+    protected $_blocks = [
+        'messages' => [
+            'name' => 'messages',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '.page.messages',
+            'strategy' => 'css selector',
+        ],
+        'dashboardAddress' => [
+            'name' => 'dashboardAddress',
+            'class' => 'Magento\Customer\Test\Block\Account\Dashboard\Address',
+            'locator' => '.block.dashboard.addresses',
+            'strategy' => 'css selector',
+        ],
+        'titleBlock' => [
+            'name' => 'titleBlock',
+            'class' => 'Magento\Theme\Test\Block\Html\Title',
+            'locator' => '.page.title',
+            'strategy' => 'css selector',
+        ],
+        'accountMenuBlock' => [
+            'name' => 'accountMenuBlock',
+            'class' => 'Magento\Customer\Test\Block\Account\Links',
+            'locator' => '.nav.items',
+            'strategy' => 'css selector',
+        ],
+    ];
 
     /**
-     * Custom constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_frontend_url'] . self::MCA;
-    }
-
-    /**
-     * Get Messages block
-     *
      * @return \Magento\Core\Test\Block\Messages
      */
     public function getMessages()
     {
-        return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messagesBlock));
+        return $this->getBlockInstance('messages');
     }
 
     /**
-     * Get Address Book block
-     *
      * @return \Magento\Customer\Test\Block\Account\Dashboard\Address
      */
     public function getDashboardAddress()
     {
-        return Factory::getBlockFactory()->getMagentoCustomerAccountDashboardAddress(
-            $this->_browser->find($this->dashboardAddressBlock)
-        );
+        return $this->getBlockInstance('dashboardAddress');
     }
 
     /**
-     * Get title block
-     *
      * @return \Magento\Theme\Test\Block\Html\Title
      */
     public function getTitleBlock()
     {
-        return $this->titleBlock = Factory::getBlockFactory()->getMagentoThemeHtmlTitle(
-            $this->_browser->find($this->titleBlock)
-        );
+        return $this->getBlockInstance('titleBlock');
     }
 
     /**
      * Get Account Menu Block
      *
-     * @return \Magento\Customer\Test\Block\Account\Menu
+     * @return \Magento\Customer\Test\Block\Account\Links
      */
     public function getAccountMenuBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCustomerAccountMenu(
-            $this->_browser->find($this->accountMenuSelector)
-        );
+        return $this->getBlockInstance('accountMenuBlock');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..08a8c094a0f90a9d63978f6d750bcf96f9315231
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Page/CustomerAccountIndex.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="customer/account/index">
+    <block>
+        <name>messages</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>.page.messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>dashboardAddress</name>
+        <class>Magento\Customer\Test\Block\Account\Dashboard\Address</class>
+        <locator>.block.dashboard.addresses</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>titleBlock</name>
+        <class>Magento\Theme\Test\Block\Html\Title</class>
+        <locator>.page.title</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>accountMenuBlock</name>
+        <class>Magento\Customer\Test\Block\Account\Links</class>
+        <locator>.nav.items</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php
new file mode 100644
index 0000000000000000000000000000000000000000..52c1ff5f2958c331d2c7d18fa775357ee3609ca1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Repository/CustomerInjectable.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\Repository;
+
+use Mtf\Repository\AbstractRepository;
+
+/**
+ * Class CustomerInjectable
+ *
+ * @package Magento\Customer\Test\Repository
+ */
+class CustomerInjectable extends AbstractRepository
+{
+    /**
+     * @param array $defaultConfig
+     * @param array $defaultData
+     */
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
+    {
+        $this->_data['default'] = [
+            'firstname' => 'John',
+            'lastname' => 'Doe',
+            'email' => 'JohnDoe_%isolation%@example.com',
+            'password' => '123123q',
+            'password_confirmation' => '123123q',
+        ];
+
+        $this->_data['defaultBackend'] = [
+            'firstname' => 'John',
+            'lastname' => 'Doe',
+            'email' => 'JohnDoe_%isolation%@example.com',
+        ];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php
index 11e8172516647bed25cf81831b1a7523d82381d1..f91e3aa20d3d778bab7ca11afc4255f7278c62d6 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerBackendEntityTest.php
@@ -78,6 +78,9 @@ class CreateCustomerBackendEntityTest extends Injectable
      */
     public function testCreateCustomerBackendEntity(CustomerInjectable $customer, AddressInjectable $address)
     {
+        // Prepare data
+        $address = $address->hasData() ? $address : null;
+
         // Steps
         $this->pageCustomerIndex->open();
         $this->pageCustomerIndex->getPageActionsBlock()->addNew();
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..601698b4bf8f6bcf569a73c38e98935347275ccf
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\TestCase;
+
+use Magento\Customer\Test\Fixture\CustomerGroupInjectable;
+use Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex;
+use Magento\Customer\Test\Page\Adminhtml\CustomerGroupNew;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for CreateCustomerGroupEntity
+ *
+ * Test Flow:
+ * 1.Log in to backend as admin user.
+ * 2.Navigate to Stores>Other Settings>Customer Groups.
+ * 3.Start to create new Customer Group.
+ * 4.Fill in all data according to data set.
+ * 5.Click "Save Customer Group" button.
+ * 6.Perform all assertions.
+ *
+ * @group Customer_Groups_(MX)
+ * @ZephyrId MAGETWO-23422
+ */
+class CreateCustomerGroupEntityTest extends Injectable
+{
+    /**
+     * Customer group index
+     *
+     * @var CustomerGroupIndex
+     */
+    protected $customerGroupIndex;
+
+    /**
+     * New customer group
+     *
+     * @var CustomerGroupNew
+     */
+    protected $customerGroupNew;
+
+    /**
+     * @param CustomerGroupIndex $customerGroupIndex
+     * @param CustomerGroupNew $customerGroupNew
+     */
+    public function __inject(
+        CustomerGroupIndex $customerGroupIndex,
+        CustomerGroupNew $customerGroupNew
+    ) {
+        $this->customerGroupIndex = $customerGroupIndex;
+        $this->customerGroupNew = $customerGroupNew;
+    }
+
+    /**
+     * Create customer group
+     *
+     * @param CustomerGroupInjectable $customerGroup
+     */
+    public function testCreateCustomerGroup(
+        CustomerGroupInjectable $customerGroup
+    ) {
+        //Steps
+        $this->customerGroupIndex->open();
+        $this->customerGroupIndex->getGridPageActions()->addNew();
+        $this->customerGroupNew->getPageMainForm()->fill($customerGroup);
+        $this->customerGroupNew->getPageMainActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest/testCreateCustomerGroup.csv b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest/testCreateCustomerGroup.csv
new file mode 100644
index 0000000000000000000000000000000000000000..1bc43c1efba0d7dd178e13bc7947865e7fc4a053
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateCustomerGroupEntityTest/testCreateCustomerGroup.csv
@@ -0,0 +1,4 @@
+"customerGroup/data/tax_class_id/dataSet";"customerGroup/data/customer_group_code";"constraint"
+"Retail Customer";"GroupName%isolation%";"assertCustomerGroupSuccessCreateMessage, assertCustomerGroupInGrid, assertCustomerGroupOnCustomerForm"
+"Retail Customer";"General ";"assertCustomerGroupAlreadyExists, assertCustomerGroupNotInGrid"
+"customer_tax_class";"GroupName%isolation%";"assertCustomerGroupSuccessCreateMessage, assertCustomerGroupInGrid, assertCustomerGroupOnCustomerForm"
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateOnFrontendTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateOnFrontendTest.php
index 7036103082bd9659c6806ecfa18278191631aa3b..7b02a957ed642949bfad9ce88b0b07e9c3eba4a6 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateOnFrontendTest.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/CreateOnFrontendTest.php
@@ -26,6 +26,8 @@ namespace Magento\Customer\Test\TestCase;
 
 use Mtf\Factory\Factory;
 use Mtf\TestCase\Functional;
+use Magento\Customer\Test\Fixture\Address;
+use Magento\Customer\Test\Block\Address\Edit as AddressEditForm;
 
 /**
  * Create Customer on frontend and set default billing address
@@ -75,6 +77,29 @@ class CreateOnFrontendTest extends Functional
         $accountIndexPage->open();
         $accountIndexPage->getDashboardAddress()->editBillingAddress();
         $addressEditPage = Factory::getPageFactory()->getCustomerAddressEdit();
-        $this->assertTrue($addressEditPage->getEditForm()->verify($customerAddress));
+        $this->verifyCustomerAddress($customerAddress, $addressEditPage->getEditForm());
+    }
+
+    /**
+     * Verify that customer address is equals data on form
+     *
+     * @param Address $address
+     * @param AddressEditForm $form
+     * @return bool
+     */
+    protected function verifyCustomerAddress(Address $address, AddressEditForm $form)
+    {
+        $dataAddress = $address->getData();
+        $preparedDataAddress = [];
+
+        foreach ($dataAddress['fields'] as $key => $field) {
+            $preparedDataAddress[$key] = $field['value'];
+        }
+
+        $dataDiff = array_diff($preparedDataAddress, $form->getData($address));
+        $this->assertTrue(
+            empty($dataDiff),
+            'Customer addresses data on edit page(backend) not equals to passed from fixture.'
+        );
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..90f8fdcb5155518e1fc4a419acf85df46605735b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Customer\Test\TestCase;
+
+use Mtf\TestCase\Injectable;
+use Magento\Customer\Test\Page\Adminhtml\CustomerIndex;
+use Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit;
+use Magento\Customer\Test\Fixture\AddressInjectable;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+
+/**
+ * Test Creation for UpdateCustomerBackendEntity
+ *
+ * General Flow:
+ * 1. Login to backend as admin
+ * 2. Navigate to CUSTOMERS->All Customers
+ * 3. Open from grid test customer
+ * 4. Edit some values, if addresses fields are not presented click 'Add New Address' button
+ * 5. Click 'Save' button
+ * 6. Perform all assertions
+ *
+ * @ticketId MAGETWO-23881
+ */
+class UpdateCustomerBackendEntityTest extends Injectable
+{
+    /**
+     * @var CustomerIndex
+     */
+    protected $customerIndexPage;
+
+    /**
+     * @var CustomerIndexEdit
+     */
+    protected $customerIndexEditPage;
+
+    /**
+     * @param CustomerIndex $customerIndexPage
+     * @param CustomerIndexEdit $customerIndexEditPage
+     */
+    public function __inject(
+        CustomerIndex $customerIndexPage,
+        CustomerIndexEdit $customerIndexEditPage
+    ) {
+        $this->customerIndexPage = $customerIndexPage;
+        $this->customerIndexEditPage = $customerIndexEditPage;
+    }
+
+    /**
+     * @param CustomerInjectable $initialCustomer
+     * @param CustomerInjectable $customer
+     * @param AddressInjectable $address
+     */
+    public function testUpdateCustomerBackendEntity(
+        CustomerInjectable $initialCustomer,
+        CustomerInjectable $customer,
+        AddressInjectable $address
+    ) {
+        // Prepare data
+        $address = $address->hasData() ? $address : null;
+
+        // Preconditions:
+        $initialCustomer->persist();
+
+        // Steps
+        $filter = ['email' => $initialCustomer->getEmail()];
+        $this->customerIndexPage->open();
+        $this->customerIndexPage->getCustomerGridBlock()->searchAndOpen($filter);
+        $this->customerIndexEditPage->getCustomerForm()->updateCustomer($customer, $address);
+        $this->customerIndexEditPage->getPageActionsBlock()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv
new file mode 100644
index 0000000000000000000000000000000000000000..6fd1ba7c220b3035aed886c8071f3e0eecae13a5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/UpdateCustomerBackendEntityTest/testUpdateCustomerBackendEntity.csv
@@ -0,0 +1,4 @@
+"initialCustomer/dataSet";"customer/data/group_id";"customer/data/prefix";"customer/data/firstname";"customer/data/middlename";"customer/data/lastname";"customer/data/suffix";"customer/data/email";"customer/data/dob";"customer/data/taxvat";"customer/data/gender";"address/data/prefix";"address/data/firstname";"address/data/middlename";"address/data/lastname";"address/data/suffix";"address/data/company";"address/data/street";"address/data/city";"address/data/country_id";"address/data/region_id";"address/data/region";"address/data/postcode";"address/data/telephone";"address/data/fax";"address/data/vat_id";"constraint"
+"default";"Wholesale";"%isolation%Prefix_";"John_%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"JohnDoe%isolation%@example.com";1/8/1986;123456789001;"Male";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid"
+"default";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"Prefix%isolation%_";"Doe%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"Company%isolation%";"3962 Horner Street";"Dothan";"United States";"Alabama";"-";36303;"334-200-4060";"555-666-777-8910";"U1234567890";"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid"
+"default";"Retailer";"%isolation%Prefix_";"Jane_%isolation%";"Jane Middle Name %isolation%";"Doe%isolation%";"_JaneSuffix%isolation%";"Jane%isolation%@example.com";1/12/2000;987654321;"Female";"Prefix%isolation%_";"Doe%isolation%";"Middle Name %isolation%";"Doe%isolation%";"_Suffix%isolation%";"Company%isolation%";"39 Northgate Street";"BICKTON";"United Kingdom";"-";"PINMINNOCH";"KA26 1PF ";"999-777-111-2345";"-";987654321;"assertCustomerSuccessSaveMessage, assertCustomerForm, assertCustomerInGrid"
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/curl/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..00a17f9778b4a4532925b2ffd41bc97340b86054
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/curl/di.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\Customer\Test\Handler\CustomerInjectable\CustomerInjectableInterface"
+                type="\Magento\Customer\Test\Handler\CustomerInjectable\Curl"/>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/constraint.xml
index cb41b4f3d0b70b2a60a6c491344e4b6540aca750..68b0d80fe8be6557fbe23ec8513fc568eb647ef4 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/constraint.xml
@@ -43,6 +43,14 @@
             <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" />
         </require>
     </assertCustomerInGrid>
+    <assertUpdateCustomerInGrid module="Magento_Customer">
+        <severeness>middle</severeness>
+        <require>
+            <preconditionCustomer class="Magento\Customer\Test\Fixture\CustomerInjectable" />
+            <customer class="Magento\Customer\Test\Fixture\CustomerInjectable" />
+            <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" />
+        </require>
+    </assertUpdateCustomerInGrid>
     <assertCustomerForm module="Magento_Customer">
         <severeness>middle</severeness>
         <require>
@@ -51,6 +59,15 @@
             <pageCustomerIndexEdit class="Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit" />
         </require>
     </assertCustomerForm>
+    <assertUpdateCustomerForm module="Magento_Customer">
+        <severeness>middle</severeness>
+        <require>
+            <preconditionCustomer class="Magento\Customer\Test\Fixture\CustomerInjectable" />
+            <customer class="Magento\Customer\Test\Fixture\CustomerInjectable" />
+            <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" />
+            <pageCustomerIndexEdit class="Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit" />
+        </require>
+    </assertUpdateCustomerForm>
     <assertCustomerInvalidEmail module="Magento_Customer">
         <severeness>middle</severeness>
         <require>
@@ -59,4 +76,19 @@
             <pageCustomerIndexNew class="Magento\Customer\Test\Page\Adminhtml\CustomerIndexNew" />
         </require>
     </assertCustomerInvalidEmail>
+    <assertCustomerGroupSuccessCreateMessage module="Magento_Customer">
+        <severeness>low</severeness>
+    </assertCustomerGroupSuccessCreateMessage>
+    <assertCustomerGroupInGrid module="Magento_Customer">
+        <severeness>low</severeness>
+    </assertCustomerGroupInGrid>
+    <assertCustomerGroupOnCustomerForm module="Magento_Customer">
+        <severeness>low</severeness>
+    </assertCustomerGroupOnCustomerForm>
+    <assertCustomerGroupAlreadyExists module="Magento_Customer">
+        <severeness>low</severeness>
+    </assertCustomerGroupAlreadyExists>
+    <assertCustomerGroupNotInGrid module="Magento_Customer">
+        <severeness>low</severeness>
+    </assertCustomerGroupNotInGrid>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/fixture.xml
index a4576f12fb9ba59c8e61a7ff4e01061c27209779..4038bc2143996fec4c352a34e7dc3f02c826c749 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/fixture.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/fixture.xml
@@ -49,4 +49,9 @@
         <entity_type>customer_address</entity_type>
         <collection>Magento\Customer\Model\Resource\Address\Collection</collection>
     </addressInjectable>
+    <customerGroup module="Magento_Customer">
+        <type>flat</type>
+        <entity_type>customer_group</entity_type>
+        <collection>Magento\Customer\Model\Resource\Group\Collection</collection>
+    </customerGroup>
 </fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/page.xml
index fb2c506e146a341dce26a765322992b19de8aaa4..968424e9029fb5f5757530d32ad8fd2b19dd9c17 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/page.xml
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/etc/global/page.xml
@@ -28,6 +28,10 @@
         <mca>customer/account/create</mca>
         <class>Magento\Customer\Test\Page\CustomerAccountCreate</class>
     </customerAccountCreate>
+    <customerAccountIndex>
+        <mca>customer/account/index</mca>
+        <class>Magento\Customer\Test\Page\CustomerAccountIndex</class>
+    </customerAccountIndex>
     <customerIndex>
         <mca>customer/index</mca>
         <area>adminhtml</area>
@@ -43,4 +47,14 @@
         <area>adminhtml</area>
         <class>Magento\Customer\Test\Page\Adminhtml\CustomerIndexEdit</class>
     </customerIndexEdit>
+    <customerGroupIndex>
+        <mca>customer/group/index</mca>
+        <area>adminhtml</area>
+        <class>Magento\Customer\Test\Page\Adminhtml\CustomerGroupIndex</class>
+    </customerGroupIndex>
+    <customerGroupNew>
+        <mca>customer/group/new</mca>
+        <area>adminhtml</area>
+        <class>Magento\Customer\Test\Page\Adminhtml\CustomerGroupNew</class>
+    </customerGroupNew>
 </page>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php
index 2fa35ecf5c987a7d439b4ee5a688d3bd2d455904..5272ddc9cb88fa81a02911714d93de1c82670b1f 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable.php
@@ -47,10 +47,10 @@ class Downloadable extends Tab
      * Fill downloadable information
      *
      * @param array $fields
-     * @param Element $element
+     * @param Element|null $element
      * @return $this
      */
-    public function fillFormTab(array $fields, Element $element)
+    public function fillFormTab(array $fields, Element $element = null)
     {
         if (isset($fields['downloadable'])) {
             foreach ($fields['downloadable']['link'] as $index => $link) {
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/Create/LinksPurchasedSeparatelyTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/Create/LinksPurchasedSeparatelyTest.php
index 213953b494d5a05c63014ac479a0dcfa51dea7c5..274e3a47850a2a249a5022854902a4a807bffd05 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/Create/LinksPurchasedSeparatelyTest.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/Create/LinksPurchasedSeparatelyTest.php
@@ -21,12 +21,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Downloadable\Test\TestCase\Create;
 
 use Mtf\Factory\Factory;
 use Mtf\TestCase\Functional;
 use Magento\Downloadable\Test\Fixture\DownloadableProduct;
 
+/**
+ * Class LinksPurchasedSeparatelyTest
+ */
 class LinksPurchasedSeparatelyTest extends Functional
 {
     /**
@@ -49,16 +53,17 @@ class LinksPurchasedSeparatelyTest extends Functional
      * Creating Downloadable product with required fields only and assign it to the category
      *
      * @ZephyrId MAGETWO-13595
+     * @return void
      */
     public function test()
     {
         $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
         $createProductPage->init($this->product);
-        $productBlockForm = $createProductPage->getProductBlockForm();
+        $productForm = $createProductPage->getProductForm();
 
         $createProductPage->open();
-        $productBlockForm->fill($this->product);
-        $productBlockForm->save($this->product);
+        $productForm->fill($this->product);
+        $createProductPage->getFormAction()->save();
 
         $createProductPage->getMessagesBlock()->assertSuccessMessage();
 
@@ -73,6 +78,8 @@ class LinksPurchasedSeparatelyTest extends Functional
 
     /**
      * Assert existing product on admin product grid
+     *
+     * @return void
      */
     protected function assertOnBackend()
     {
@@ -84,6 +91,8 @@ class LinksPurchasedSeparatelyTest extends Functional
 
     /**
      * Assert product data on category and product pages
+     *
+     * @return void
      */
     protected function assertOnFrontend()
     {
@@ -101,13 +110,16 @@ class LinksPurchasedSeparatelyTest extends Functional
 
         $productViewBlock = $productPage->getViewBlock();
         $this->assertEquals($product->getProductName(), $productViewBlock->getProductName());
-        $this->assertEquals($product->getProductPrice(), $productViewBlock->getProductPrice());
+        $price = $productViewBlock->getProductPrice();
+        $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']);
 
         $productPage->getDownloadableLinksBlock()
             ->check([['title' => $product->getData('fields/downloadable/link/0/title/value')]]);
+
+        $price = $productViewBlock->getProductPrice();
         $this->assertEquals(
-            (int)$product->getProductPrice() + $product->getData('fields/downloadable/link/0/price/value'),
-            $productViewBlock->getProductPrice()
+            number_format($product->getProductPrice() + $product->getData('fields/downloadable/link/0/price/value'), 2),
+            $price['price_regular_price']
         );
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Search/Test/Block/Catalog/Layer/View.php b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php
similarity index 96%
rename from dev/tests/functional/tests/app/Magento/Search/Test/Block/Catalog/Layer/View.php
rename to dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php
index e2d8cbb7409c29a8a72c3e5d529f71d4acbda15d..ad4d80cc3adcdb3f6946638d7fc2163b2c0e0d44 100644
--- a/dev/tests/functional/tests/app/Magento/Search/Test/Block/Catalog/Layer/View.php
+++ b/dev/tests/functional/tests/app/Magento/LayeredNavigation/Test/Block/Navigation.php
@@ -21,16 +21,15 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Search\Test\Block\Catalog\Layer;
+namespace Magento\LayeredNavigation\Test\Block;
 
 use Mtf\Block\Block;
 use Mtf\Client\Element\Locator;
 
 /**
  * Catalog layered navigation view block
- *
  */
-class View extends Block
+class Navigation extends Block
 {
     /**
      * 'Clear All' link
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/FormPageActions.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4ce7a70876d0219f94e8469edc33a0da46ccd02
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/FormPageActions.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\Block\Adminhtml\Template;
+
+use Magento\Backend\Test\Block\FormPageActions as AbstractFormPageActions;
+
+/**
+ * Class FormPageActions
+ * Form page actions block
+ *
+ * @package Magento\Newsletter\Test\Block\Adminhtml\Template
+ */
+class FormPageActions extends AbstractFormPageActions
+{
+    /**
+     * "Save" button
+     *
+     * @var string
+     */
+    protected $saveButton = "[data-ui-id='page-actions-toolbar-save-button']";
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/Grid.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..d25a5e0cb5b6326008ce3fcd74719f8fa8acaefa
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/Grid.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\Block\Adminhtml\Template;
+
+use Magento\Backend\Test\Block\Widget\Grid as AbstractGrid;
+
+/**
+ * Class Grid
+ * Newsletter templates grid block
+ *
+ * @package Magento\Newsletter\Test\Block\Aminhtml\Template
+ */
+class Grid extends AbstractGrid
+{
+    /**
+     * Filters array mapping
+     *
+     * @var array $filters
+     */
+    protected $filters = [
+        'code' => [
+            'selector' => '[data-ui-id="widget-grid-column-filter-text-1-filter-code"]'
+        ]
+    ];
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/GridPageActions.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/GridPageActions.php
new file mode 100644
index 0000000000000000000000000000000000000000..496304b5cc168eb66b44c7b87796de51cf1c0cfd
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Block/Adminhtml/Template/GridPageActions.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\Block\Adminhtml\Template;
+
+use Magento\Backend\Test\Block\GridPageActions as AbstractGridPageActions;
+
+/**
+ * Class GridPageActions
+ * Grid page actions block
+ *
+ * @package Magento\Newsletter\Test\Block\Adminhtml\Template
+ */
+class GridPageActions extends AbstractGridPageActions
+{
+    /**
+     * "Add New" button
+     *
+     * @var string
+     */
+    protected $addNewButton = "[data-ui-id='page-actions-toolbar-add-button']";
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterInGrid.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..772ae2d0d89a90cd1dd8a50df37fb19e55909db9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterInGrid.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\Constraint;
+
+use Magento\Newsletter\Test\Fixture\Template;
+use Magento\Newsletter\Test\Page\Adminhtml\TemplateIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertNewsletterInGrid
+ *
+ * @package Magento\Newsletter\Test\Constraint
+ */
+class AssertNewsletterInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     *  Assert that newsletter template is present in grid
+     *
+     * @param TemplateIndex $templateIndex
+     * @param Template $template
+     * @return void
+     */
+    public function processAssert(
+        TemplateIndex $templateIndex,
+        Template $template
+    ) {
+        $templateIndex->open();
+        $filter = ['code' => $template->getCode()];
+        \PHPUnit_Framework_Assert::assertTrue(
+            $templateIndex->getNewsletterTemplateGrid()->isRowVisible($filter),
+            'Newsletter \'' . $template->getCode() . '\'is absent in newsletter template grid.'
+        );
+    }
+
+    /**
+     * Success assert of newsletter template in grid.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Newsletter template is present in grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterSuccessCreateMessage.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterSuccessCreateMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0d43d9ea562aa836149641051a0a6bba4585a0b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Constraint/AssertNewsletterSuccessCreateMessage.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\Constraint;
+
+use Magento\Newsletter\Test\Page\Adminhtml\TemplateIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertNewsletterSuccessCreateMessage
+ *
+ * @package Magento\Newsletter\Test\Constraint
+ */
+class AssertNewsletterSuccessCreateMessage extends AbstractConstraint
+{
+    const SUCCESS_MESSAGE = 'The newsletter template has been saved.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that success message is displayed after newsletter template save
+     *
+     * @param TemplateIndex $templateIndex
+     */
+    public function processAssert(TemplateIndex $templateIndex)
+    {
+        $actualMessage = $templateIndex->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Success assert of created newsletter template success message
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Newsletter success save message is present.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.php
new file mode 100644
index 0000000000000000000000000000000000000000..8d6b2e95eb6542337108df8fe0fe5bb7af24e44b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.php
@@ -0,0 +1,199 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class Template
+ *
+ * @package Magento\Newsletter\Test\Fixture
+ */
+class Template extends InjectableFixture
+{
+    protected $defaultDataSet = [
+        'code' => 'TemplateName%isolation%',
+        'subject' => 'TemplateSubject%isolation%',
+        'sender_name' => 'SenderName%isolation%',
+        'sender_email' => 'SenderName%isolation%@example.com',
+        'text' => 'Some text %isolation%',
+    ];
+
+    protected $id = [
+        'attribute_code' => 'template_id',
+        'backend_type' => 'int',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $code = [
+        'attribute_code' => 'template_code',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $text = [
+        'attribute_code' => 'template_text',
+        'backend_type' => 'text',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $text_preprocessed = [
+        'attribute_code' => 'template_text_preprocessed',
+        'backend_type' => 'text',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $styles = [
+        'attribute_code' => 'template_styles',
+        'backend_type' => 'text',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $type = [
+        'attribute_code' => 'template_type',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $subject = [
+        'attribute_code' => 'template_subject',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $sender_name = [
+        'attribute_code' => 'template_sender_name',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $sender_email = [
+        'attribute_code' => 'template_sender_email',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $actual = [
+        'attribute_code' => 'template_actual',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '1',
+        'input' => '',
+    ];
+
+    protected $added_at = [
+        'attribute_code' => 'added_at',
+        'backend_type' => 'timestamp',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $modified_at = [
+        'attribute_code' => 'modified_at',
+        'backend_type' => 'timestamp',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    public function getId()
+    {
+        return $this->getData('id');
+    }
+
+    public function getCode()
+    {
+        return $this->getData('code');
+    }
+
+    public function getText()
+    {
+        return $this->getData('text');
+    }
+
+    public function getTextPreprocessed()
+    {
+        return $this->getData('text_preprocessed');
+    }
+
+    public function getStyles()
+    {
+        return $this->getData('styles');
+    }
+
+    public function getType()
+    {
+        return $this->getData('type');
+    }
+
+    public function getSubject()
+    {
+        return $this->getData('subject');
+    }
+
+    public function getSenderName()
+    {
+        return $this->getData('sender_name');
+    }
+
+    public function getSenderEmail()
+    {
+        return $this->getData('sender_email');
+    }
+
+    public function getActual()
+    {
+        return $this->getData('actual');
+    }
+
+    public function getAddedAt()
+    {
+        return $this->getData('added_at');
+    }
+
+    public function getModifiedAt()
+    {
+        return $this->getData('modified_at');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8cbfa452add0d2e1b3b9127eb71391094399a9a4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Fixture/Template.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Newsletter\Test\Fixture\Template">
+    <module>Magento_Newsletter</module>
+    <type>flat</type>
+    <entity_type>newsletter_template</entity_type>
+    <collection>Magento\Newsletter\Model\Resource\Template\Collection</collection>
+    <identifier>template_id</identifier>
+    <fields>
+        <id>
+            <attribute_code>template_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>1</is_required>
+            <default_value/>
+            <input/>
+        </id>
+        <code>
+            <attribute_code>template_code</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </code>
+        <text>
+            <attribute_code>template_text</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </text>
+        <text_preprocessed>
+            <attribute_code>template_text_preprocessed</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </text_preprocessed>
+        <styles>
+            <attribute_code>template_styles</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </styles>
+        <type>
+            <attribute_code>template_type</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </type>
+        <subject>
+            <attribute_code>template_subject</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </subject>
+        <sender_name>
+            <attribute_code>template_sender_name</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </sender_name>
+        <sender_email>
+            <attribute_code>template_sender_email</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </sender_email>
+        <actual>
+            <attribute_code>template_actual</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required/>
+            <default_value>1</default_value>
+            <input/>
+        </actual>
+        <added_at>
+            <attribute_code>added_at</attribute_code>
+            <backend_type>timestamp</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </added_at>
+        <modified_at>
+            <attribute_code>modified_at</attribute_code>
+            <backend_type>timestamp</backend_type>
+            <is_required/>
+            <default_value/>
+            <input/>
+        </modified_at>
+    </fields>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..18a1317adc918bc27370b8cf9379e3763b2a207f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class TemplateIndex
+ *
+ * @package Magento\Newsletter\Test\Page\Adminhtml
+ */
+class TemplateIndex extends BackendPage
+{
+    const MCA = 'newsletter/template/index';
+
+    protected $_blocks = [
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages .messages',
+            'strategy' => 'css selector',
+        ],
+        'gridPageActions' => [
+            'name' => 'gridPageActions',
+            'class' => 'Magento\Newsletter\Test\Block\Adminhtml\Template\GridPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'newsletterTemplateGrid' => [
+            'name' => 'newsletterTemplateGrid',
+            'class' => 'Magento\Newsletter\Test\Block\Adminhtml\Template\Grid',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+
+    /**
+     * @return \Magento\Newsletter\Test\Block\Adminhtml\Template\GridPageActions
+     */
+    public function getGridPageActions()
+    {
+        return $this->getBlockInstance('gridPageActions');
+    }
+
+    /**
+     * @return \Magento\Newsletter\Test\Block\Adminhtml\Template\Grid
+     */
+    public function getNewsletterTemplateGrid()
+    {
+        return $this->getBlockInstance('newsletterTemplateGrid');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..72fe1d07e81a411e88cc8b1076d68006dc92b942
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateIndex.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="newsletter/template/index">
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages .messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>gridPageActions</name>
+        <class>Magento\Newsletter\Test\Block\Adminhtml\Template\GridPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>newsletterTemplateGrid</name>
+        <class>Magento\Newsletter\Test\Block\Adminhtml\Template\Grid</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c266605c921980a6676aa73c23f08d77b560039
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class TemplateNewIndex
+ *
+ * @package Magento\Newsletter\Test\Page\Adminhtml
+ */
+class TemplateNewIndex extends BackendPage
+{
+    const MCA = 'newsletter/template/new/index';
+
+    protected $_blocks = [
+        'formPageActions' => [
+            'name' => 'formPageActions',
+            'class' => 'Magento\Newsletter\Test\Block\Adminhtml\Template\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'editForm' => [
+            'name' => 'editForm',
+            'class' => 'Magento\Backend\Test\Block\Widget\Form',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Newsletter\Test\Block\Adminhtml\Template\FormPageActions
+     */
+    public function getFormPageActions()
+    {
+        return $this->getBlockInstance('formPageActions');
+    }
+
+    /**
+     * @return \Magento\Backend\Test\Block\Widget\Form
+     */
+    public function getEditForm()
+    {
+        return $this->getBlockInstance('editForm');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0f7231a192d5a2e6dae416f99f871f34fb3b094d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/Page/Adminhtml/TemplateNewIndex.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="newsletter/template/new/index">
+    <block>
+        <name>formPageActions</name>
+        <class>Magento\Newsletter\Test\Block\Adminhtml\Template\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>editForm</name>
+        <class>Magento\Backend\Test\Block\Widget\Form</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd132df9ef1330897fb583a175a2eee77ae106f7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Newsletter\Test\TestCase;
+
+use Magento\Newsletter\Test\Fixture\Template;
+use Magento\Newsletter\Test\Page\Adminhtml\TemplateIndex;
+use Magento\Newsletter\Test\Page\Adminhtml\TemplateNewIndex;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for Create Newsletter Template
+ *
+ * Test Flow:
+ * 1. Login to backend.
+ * 2. Navigate to MARKETING > Newsletter Template.
+ * 3. Add New Template.
+ * 4. Fill in all data according to data set.
+ * 5. Save.
+ * 6. Perform asserts.
+ *
+ * @group Newsletters_(MX)
+ * @ZephyrId MAGETWO-23302
+ */
+class CreateNewsletterTemplateEntityTest extends Injectable
+{
+    /**
+     * Page for create newsletter template
+     *
+     * @var TemplateNewIndex
+     */
+    protected $templateNewIndex;
+
+    /**
+     * Page with newsletter template grid
+     *
+     * @var TemplateIndex
+     */
+    protected $templateIndex;
+
+    /**
+     * Inject newsletter page
+     *
+     * @param TemplateIndex $templateIndex
+     * @param TemplateNewIndex $templateNewIndex
+     */
+    public function __inject(
+        TemplateIndex $templateIndex,
+        TemplateNewIndex $templateNewIndex
+    ) {
+        $this->templateIndex = $templateIndex;
+        $this->templateNewIndex = $templateNewIndex;
+    }
+
+    /**
+     * Create newsletter template
+     *
+     * @param Template $template
+     */
+    public function testCreateNewsletterTemplate(Template $template)
+    {
+        // Steps
+        $this->templateIndex->open();
+        $this->templateIndex->getGridPageActions()->addNew();
+        $this->templateNewIndex->getEditForm()->fill($template);
+        $this->templateNewIndex->getFormPageActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest/testCreateNewsletterTemplate.csv b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest/testCreateNewsletterTemplate.csv
new file mode 100644
index 0000000000000000000000000000000000000000..a87a9c80325b789defeb8882f259f088f2877968
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/TestCase/CreateNewsletterTemplateEntityTest/testCreateNewsletterTemplate.csv
@@ -0,0 +1,2 @@
+"template/data/code";"template/data/subject";"template/data/sender_name";"template/data/sender_email";"template/data/text";"constraint"
+"TemplateName%isolation%";"TemplateSubject%isolation%";"SenderName%isolation%";"SenderName%isolation%@example.com";"Some content %isolation%";"assertNewsletterSuccessCreateMessage, assertNewsletterInGrid"
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/constraint.xml
index 1dc7c77bc8d2565f0dbaad83cd025ccd1b1335a6..9321ac60842203820d61ed048bf5aab0ab3e5566 100644
--- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/constraint.xml
@@ -24,6 +24,12 @@
  */
 -->
 <constraint>
+    <assertNewsletterSuccessCreateMessage module="Magento_Newsletter">
+        <severeness>low</severeness>
+    </assertNewsletterSuccessCreateMessage>
+    <assertNewsletterInGrid module="Magento_Newsletter">
+        <severeness>low</severeness>
+    </assertNewsletterInGrid>
     <assertCustomerIsSubscribedToNewsletter module="Magento_Newsletter">
         <severeness>low</severeness>
         <require>
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/fixture.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eefd75a556ba4d703b6f268119e699e90912fb64
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/fixture.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture>
+    <template module="Magento_Newsletter">
+        <type>flat</type>
+        <entity_type>newsletter_template</entity_type>
+        <collection>Magento\Newsletter\Model\Resource\Template\Collection</collection>
+        <identifier>template_id</identifier>
+    </template>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/page.xml
index aeab51771315963df8d762b79dd1834ab9d17c31..a18cb41d5d14af89fc794f018086ffb21d38e976 100644
--- a/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/page.xml
+++ b/dev/tests/functional/tests/app/Magento/Newsletter/Test/etc/global/page.xml
@@ -24,6 +24,16 @@
  */
 -->
 <page>
+    <templateIndex>
+        <mca>newsletter/template/index</mca>
+        <area>adminhtml</area>
+        <class>Magento\Newsletter\Test\Page\Adminhtml\templateIndex</class>
+    </templateIndex>
+    <templateNewIndex>
+        <mca>newsletter/template/new/index</mca>
+        <area>adminhtml</area>
+        <class>Magento\Newsletter\Test\Page\Adminhtml\templateNewIndex</class>
+    </templateNewIndex>
     <subscriberIndex>
         <mca>newsletter/subscriber/index</mca>
         <area>adminhtml</area>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php
index b54c12f8715745756d5474645846435f4012e736..fc05c321c3ddb0a1a3a987928edc24766adc369f 100644
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php
@@ -24,6 +24,7 @@
 
 namespace Magento\Review\Test\TestCase;
 
+use Mtf\Block\Form;
 use Magento\Review\Test\Block\Product\View\Summary;
 use Magento\Review\Test\Block\Product\View;
 use Magento\Review\Test\Fixture\Review;
@@ -84,14 +85,14 @@ class ReviewTest extends Functional
         $this->assertEquals('Guest', $reviewBackendForm->getPostedBy(), 'Review is not posted by Guest');
         $this->assertEquals('Pending', $reviewBackendForm->getStatus(), 'Review is not in Pending status');
         $this->assertTrue(
-            $reviewBackendForm->verify($reviewFixture),
+            $this->verifyReviewBackendForm($reviewFixture, $reviewBackendForm),
             'Review data is not corresponds to submitted one'
         );
 
         $reviewBackendForm->approveReview();
         $this->assertContains(
             'You saved the review.',
-            $backendReviewPage->getMessageBlock()->getSuccessMessages(),
+            $backendReviewPage->getMessagesBlock()->getSuccessMessages(),
             'Review is not saved'
         );
 
@@ -161,4 +162,22 @@ class ReviewTest extends Functional
             );
         }
     }
+
+    /**
+     * Verify that review is equals to data on form
+     *
+     * @param Review $review
+     * @param Form $form
+     * @return bool
+     */
+    protected function verifyReviewBackendForm(Review $review, Form $form)
+    {
+        $reviewData = [];
+        foreach ($review->getData()['fields'] as $key => $field) {
+            $reviewData[$key] = $field['value'];
+        }
+        $dataDiff = array_diff($reviewData, $form->getData($review));
+
+        return empty($dataDiff);
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php
index 5bdbcd0db1dd9f60389fd2139a74c9391f5f14a7..fcf5167241896b40097889093b885cf121f673b3 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.php
@@ -24,88 +24,102 @@
 
 namespace Magento\Tax\Test\Block\Adminhtml\Rule\Edit;
 
+use Magento\Tax\Test\Fixture\TaxRule;
+use Mtf\Block\BlockFactory;
+use Mtf\Block\Form as FormInterface;
+use Mtf\Block\Mapper;
+use Mtf\Client\Browser;
 use Mtf\Client\Element;
-use Mtf\Factory\Factory;
 use Mtf\Client\Element\Locator;
 use Mtf\Fixture\FixtureInterface;
-use Mtf\Block\Form as FormInterface;
-use Magento\Tax\Test\Fixture\TaxRule;
 
 /**
  * Class Form
  * Form for tax rule creation
- *
  */
 class Form extends FormInterface
 {
     /**
-     * Tax rule name
+     * The root element of the browser
+     *
+     * @var Browser
+     */
+    protected $browser;
+
+    /**
+     * 'Additional Settings' link
      *
      * @var string
      */
-    protected $name = '#code';
+    protected $additionalSettings = '#details-summarybase_fieldset';
 
     /**
-     * Tax rule priority field
+     * Tax rate block
      *
      * @var string
      */
-    protected $priority = '#priority';
+    protected $taxRateBlock = '[class*=tax_rate]';
 
     /**
-     * Tax rule sort order field
+     * Tax rate form
      *
      * @var string
      */
-    protected $position = '#position';
+    protected $taxRateForm = '//*[contains(@class, "tax-rate-popup")]';
 
     /**
-     * 'Additional Settings' link
+     * Customer Tax Class block
      *
      * @var string
      */
-    protected $additionalSettings = '#details-summarybase_fieldset';
+    protected $taxCustomerBlock = '[class*=tax_customer_class]';
 
     /**
-     * 'Save and Continue Edit' button
+     * Product Tax Class block
      *
      * @var string
      */
-    protected $saveAndContinue = '#save_and_continue';
+    protected $taxProductBlock = '[class*=tax_product_class]';
 
     /**
-     * Tax rate block
+     * XPath selector for finding needed option by its value
      *
      * @var string
      */
-    protected $taxRateBlock = '[class*=tax_rate]';
+    protected $optionMaskElement = './/*[contains(@class, "mselect-list-item")]//label/span[text()="%s"]';
 
     /**
-     * Get tax rate block
+     * Css selector for Add New button
      *
-     * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxRate
+     * @var string
      */
-    protected function getTaxRateBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoTaxAdminhtmlRuleEditTaxRate(
-            $this->_rootElement->find($this->taxRateBlock, Locator::SELECTOR_CSS)
-        );
-    }
+    protected $addNewButton = '.mselect-button-add';
 
     /**
-     * Get Customer/Product Tax Classes bloc
+     * Css selector for Add New tax class input
      *
-     * @param string $taxClass (e.g. customer|product)
+     * @var string
+     */
+    protected $addNewInput = '.mselect-input';
+
+    /**
+     * Css selector for Add New save button
      *
-     * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxClass
+     * @var string
      */
-    protected function getTaxClassBlock($taxClass)
-    {
-        $taxClassBlock = Factory::getBlockFactory()->getMagentoTaxAdminhtmlRuleEditTaxClass(
-            $this->_rootElement->find('[class*=tax_' . $taxClass . ']', Locator::SELECTOR_CSS)
-        );
+    protected $saveButton = '.mselect-save';
 
-        return $taxClassBlock;
+    /**
+     * @constructor
+     * @param Element $element
+     * @param BlockFactory $blockFactory
+     * @param Mapper $mapper
+     * @param Browser $browser
+     */
+    public function __construct(Element $element, BlockFactory $blockFactory, Mapper $mapper, Browser $browser)
+    {
+        parent::__construct($element, $blockFactory, $mapper);
+        $this->browser = $browser;
     }
 
     /**
@@ -113,30 +127,115 @@ class Form extends FormInterface
      *
      * @param FixtureInterface $fixture
      * @param Element $element
-     * @return $this
+     * @return $this|void
      */
     public function fill(FixtureInterface $fixture, Element $element = null)
     {
         /** @var TaxRule $fixture */
-        $data = $fixture->getData('fields');
-        $this->_rootElement->find($this->name, Locator::SELECTOR_CSS)->setValue($fixture->getTaxRuleName());
-        $this->getTaxRateBlock()->selectTaxRate($fixture->getTaxRate());
-        $this->_rootElement->find($this->additionalSettings, Locator::SELECTOR_CSS)->click();
-        $this->getTaxClassBlock('customer')->selectTaxClass($fixture->getTaxClass('customer'));
-        $this->getTaxClassBlock('product')->selectTaxClass($fixture->getTaxClass('product'));
-        if (!empty($data['priority'])) {
-            $this->_rootElement->find($this->priority, Locator::SELECTOR_CSS)->setValue($fixture->getTaxRulePriority());
+        $this->addNewTaxRates($fixture);
+        $this->openAdditionalSettings();
+        if ($fixture->hasData('tax_customer_class')) {
+            $taxCustomerBlock = $this->_rootElement->find(
+                $this->taxCustomerBlock,
+                Locator::SELECTOR_CSS,
+                'multiselectlist'
+            );
+            $this->addNewTaxClass($fixture->getTaxCustomerClass(), $taxCustomerBlock);
+        }
+        if ($fixture->hasData('tax_product_class')) {
+            $taxProductBlock = $this->_rootElement->find(
+                $this->taxProductBlock,
+                Locator::SELECTOR_CSS,
+                'multiselectlist'
+            );
+            $this->addNewTaxClass($fixture->getTaxProductClass(), $taxProductBlock);
         }
-        if (!empty($data['position'])) {
-            $this->_rootElement->find($this->position, Locator::SELECTOR_CSS)->setValue($fixture->getTaxRulePosition());
+
+        parent::fill($fixture);
+    }
+
+    /**
+     * Method to add new tax rate
+     *
+     * @param TaxRule $taxRule
+     * @return void
+     */
+    protected function addNewTaxRates($taxRule)
+    {
+        $taxRateBlock = $this->_rootElement->find($this->taxRateBlock, Locator::SELECTOR_CSS, 'multiselectlist');
+        /** @var \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxRate $taxRateForm */
+        $taxRateForm = $this->blockFactory->create(
+            'Magento\Tax\Test\Block\Adminhtml\Rule\Edit\TaxRate',
+            ['element' => $this->browser->find($this->taxRateForm, Locator::SELECTOR_XPATH)]
+        );
+
+        /** @var \Magento\Tax\Test\Fixture\TaxRule\TaxRate $taxRatesFixture */
+        $taxRatesFixture = $taxRule->getDataFieldConfig('tax_rate')['source'];
+        $taxRatesFixture = $taxRatesFixture->getFixture();
+        $taxRatesData = $taxRule->getTaxRate();
+
+        foreach ($taxRatesData as $key => $taxRate) {
+            $option = $taxRateBlock->find(sprintf($this->optionMaskElement, $taxRate), Locator::SELECTOR_XPATH);
+            if (!$option->isVisible()) {
+                $taxRate = $taxRatesFixture[$key];
+
+                /** @var \Magento\Tax\Test\Fixture\TaxRate $taxRate */
+                $taxRateBlock->find($this->addNewButton)->click();
+                $taxRateForm->fill($taxRate);
+                $taxRateForm->saveTaxRate();
+                $code = $taxRate->getCode();
+                $this->waitUntilOptionIsVisible($taxRateBlock, $code);
+            }
+        }
+    }
+
+    /**
+     * Method to add new tax classes
+     *
+     * @param array $taxClasses
+     * @param Element $element
+     * @return void
+     */
+    protected function addNewTaxClass(array $taxClasses, Element $element)
+    {
+        foreach ($taxClasses as $taxClass) {
+            $option = $element->find(sprintf($this->optionMaskElement, $taxClass), Locator::SELECTOR_XPATH);
+            if (!$option->isVisible()) {
+                $element->find($this->addNewButton)->click();
+                $element->find($this->addNewInput)->setValue($taxClass);
+                $element->find($this->saveButton)->click();
+                $this->waitUntilOptionIsVisible($element, $taxClass);
+            }
         }
     }
 
     /**
-     * Click Save And Continue Button on Form
+     * Waiting until option in list is visible
+     *
+     * @param Element $element
+     * @param string $value
+     * @return void
+     */
+    protected function waitUntilOptionIsVisible($element, $value)
+    {
+        $element->waitUntil(
+            function () use ($element, $value) {
+                $productSavedMessage = $element->find(
+                    sprintf($this->optionMaskElement, $value),
+                    Locator::SELECTOR_XPATH
+                );
+                return $productSavedMessage->isVisible() ? true : null;
+            }
+        );
+    }
+
+    /**
+     * Open Additional Settings on Form
+     *
+     * @return void
      */
-    public function clickSaveAndContinue()
+    public function openAdditionalSettings()
     {
-        $this->_rootElement->find($this->saveAndContinue, Locator::SELECTOR_CSS)->click();
+        $this->_rootElement->find($this->additionalSettings)->click();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d0df4db97b61a059c619a1cbcb658b9660724fce
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/Form.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <code />
+        <priority />
+        <position />
+        <tax_rate>
+            <selector>[class*=tax_rate]</selector>
+            <input>multiselectlist</input>
+        </tax_rate>
+        <tax_customer_class>
+            <selector>[class*=tax_customer_class]</selector>
+            <input>multiselectlist</input>
+        </tax_customer_class>
+        <tax_product_class>
+            <selector>[class*=tax_product_class]</selector>
+            <input>multiselectlist</input>
+        </tax_product_class>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxClass.php
deleted file mode 100644
index 555d71cd8a3faf9c263632542c18895a423bcd0a..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxClass.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Tax\Test\Block\Adminhtml\Rule\Edit;
-
-use Mtf\Fixture\FixtureInterface;
-use Mtf\Block\Block;
-use Mtf\Client\Element\Locator;
-
-/**
- * Class TaxClass
- * Customer/Product Tax Classes block
- *
- */
-class TaxClass extends Block
-{
-    /**
-     * Tax class row item
-     *
-     * @var string
-     */
-    protected $taxClassRow = './/label[input[contains(@class, "mselect-checked")]]';
-
-    /**
-     * Add new tax class button
-     *
-     * @var string
-     */
-    protected $addNewTaxClass = '.action-add';
-
-    /**
-     * Tax class to select
-     *
-     * @var string
-     */
-    protected $taxClassItem = './/*[contains(@class, "mselect-list-item")]//span';
-
-    /**
-     * New tax class input field
-     *
-     * @var string
-     */
-    protected $newTaxClass = '.mselect-input';
-
-    /**
-     * Save new tax class
-     *
-     * @var string
-     */
-    protected $saveTaxClass = '.mselect-save';
-
-    /**
-     * Select Tax Class in multiselect and create new one if required
-     *
-     * @param array $taxClasses
-     */
-    public function selectTaxClass($taxClasses)
-    {
-        //Uncheck all marked classes
-        while ($this->_rootElement->find($this->taxClassRow, Locator::SELECTOR_XPATH)->isVisible()) {
-            $this->_rootElement->find($this->taxClassRow, Locator::SELECTOR_XPATH)->click();
-        }
-        //Select tax classes
-        foreach ($taxClasses as $class) {
-            $taxOption = $this->_rootElement->find(
-                $this->taxClassItem . '[text()="' . $class . '"]',
-                Locator::SELECTOR_XPATH
-            );
-            if (!$taxOption->isVisible()) {
-                $this->_rootElement->find($this->addNewTaxClass, Locator::SELECTOR_CSS)->click();
-                $this->_rootElement->find($this->newTaxClass, Locator::SELECTOR_CSS)->setValue($class);
-                $this->_rootElement->find($this->saveTaxClass, Locator::SELECTOR_CSS)->click();
-                $this->waitForElementVisible(
-                    $this->taxClassRow . '/span[text()="' . $class . '"]',
-                    Locator::SELECTOR_XPATH
-                );
-            } else {
-                $this->_rootElement->find('//label/span[text()="' . $class . '"]', Locator::SELECTOR_XPATH)->click();
-            }
-        }
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.php
index e3b87b382a741c6219f2ccbc19a333a0f3b2d28a..15c84e159bc457b999b3aa0ed71e4e62bda7e3a4 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.php
@@ -24,30 +24,14 @@
 
 namespace Magento\Tax\Test\Block\Adminhtml\Rule\Edit;
 
-use Mtf\Client\Element\Locator;
 use Mtf\Block\Form as FormInterface;
 
 /**
  * Class TaxRate
  * Tax rate block
- *
  */
 class TaxRate extends FormInterface
 {
-    /**
-     * 'Add New Tax Rate' button
-     *
-     * @var string
-     */
-    protected $addNewTaxRate = '.action-add';
-
-    /**
-     * Dialog window for creating new tax rate
-     *
-     * @var string
-     */
-    protected $taxRateUiDialog = '//*[contains(@class, ui-dialog)]//*[@id="tax-rate-form"]/..';
-
     /**
      * 'Save' button on dialog window for creating new tax rate
      *
@@ -56,32 +40,12 @@ class TaxRate extends FormInterface
     protected $saveTaxRate = '#tax-rule-edit-apply-button';
 
     /**
-     * Tax rate option
-     *
-     * @var string
-     */
-    protected $taxRateOption = '//*[contains(@class, "mselect-list-item")]//label';
-
-    /**
-     * Select Tax Rate in multiselect and create new one if required
+     * Clicking 'Save' button on dialog window for creating new tax rate
      *
-     * @param array $rates
+     * @return void
      */
-    public function selectTaxRate(array $rates)
+    public function saveTaxRate()
     {
-        foreach ($rates as $rate) {
-            if (isset($rate['rate'])) {
-                $this->_rootElement->find($this->addNewTaxRate, Locator::SELECTOR_CSS)->click();
-                $taxRateDialog = $this->_rootElement->find($this->taxRateUiDialog, Locator::SELECTOR_XPATH);
-                $this->_fill($this->dataMapping($rate), $taxRateDialog);
-                $taxRateDialog->find($this->saveTaxRate, Locator::SELECTOR_CSS)->click();
-                $this->waitForElementNotVisible($this->taxRateUiDialog, Locator::SELECTOR_XPATH);
-            } else {
-                $this->_rootElement->find(
-                    $this->taxRateOption . '/span[text()="' . $rate['code']['value'] . '"]',
-                    Locator::SELECTOR_XPATH
-                )->click();
-            }
-        }
+        $this->_rootElement->find($this->saveTaxRate)->click();
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.xml
index 44708431b48bcc7a1472e48463c3318585f8fa09..cb1e40217b961039ba23649a53f3d75ea5744c61 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Edit/TaxRate.xml
@@ -27,8 +27,17 @@
     <fields>
         <code />
         <rate />
+        <tax_postcode />
+        <zip_from />
+        <zip_to />
         <tax_region_id>
             <input>select</input>
         </tax_region_id>
+        <tax_country_id>
+            <input>select</input>
+        </tax_country_id>
+        <zip_is_range>
+            <input>checkbox</input>
+        </zip_is_range>
     </fields>
 </mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Grid.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Grid.php
index e0c6237ec5cd108cf8c10972ed6969cd59942d75..75f800359e28728fbb5f8146f194ab7d195c1420 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rule/Grid.php
@@ -24,43 +24,43 @@
 
 namespace Magento\Tax\Test\Block\Adminhtml\Rule;
 
-use Mtf\Client\Element\Locator;
 use Magento\Backend\Test\Block\Widget\Grid as GridInterface;
 
 /**
  * Class Grid
- * Tax rules grid
- *
+ * Adminhtml Tax Rules management grid
  */
 class Grid extends GridInterface
 {
     /**
-     * 'Add New' rule button
+     * Locator value for opening needed row
      *
      * @var string
      */
-    protected $addNewRule = "../*[@class='page-actions']//*[@id='add']";
+    protected $editLink = 'td[class*=col-code]';
 
     /**
-     * {@inheritdoc}
+     * Initialize block elements
+     *
+     * @var array
      */
-    protected $filters = array(
-        'name' => array(
-            'selector' => '#taxRuleGrid_filter_code'
-        ),
-        'customer_tax_class' => array(
+    protected $filters = [
+        'code' => [
+            'selector' => '#taxRuleGrid_filter_code',
+        ],
+        'tax_customer_class' => [
             'selector' => '#taxRuleGrid_filter_customer_tax_classes',
-            'input' => 'select'
-        ),
-        'product_tax_class' => array(
+            'input' => 'select',
+        ],
+        'tax_product_class' => [
             'selector' => '#taxRuleGrid_filter_product_tax_classes',
-            'input' => 'select'
-        ),
-        'tax_rate' => array(
+            'input' => 'select',
+        ],
+        'tax_rate' => [
             'selector' => '#taxRuleGrid_filter_tax_rates',
-            'input' => 'select'
-        )
-    );
+            'input' => 'select',
+        ],
+    ];
 
     /**
      * Check if specific row exists in grid
@@ -71,15 +71,7 @@ class Grid extends GridInterface
      */
     public function isRowVisible(array $filter, $isSearchable = false)
     {
-        $this->search(array('name' => $filter['name']));
+        $this->search(array('code' => $filter['code']));
         return parent::isRowVisible($filter, $isSearchable);
     }
-
-    /**
-     * Add new rule
-     */
-    public function addNewRule()
-    {
-        $this->_rootElement->find($this->addNewRule, Locator::SELECTOR_XPATH)->click();
-    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleForm.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1bd7eb7988cace553b7b33c5d379fdee119ea95
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleForm.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Constraint;
+
+use Magento\Tax\Test\Fixture\TaxRule;
+use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex;
+use Magento\Tax\Test\Page\Adminhtml\TaxRuleNew;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertTaxRuleForm
+ */
+class AssertTaxRuleForm extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert that tax rule form filled right
+     *
+     * @param TaxRuleNew $taxRuleNew
+     * @param TaxRuleIndex $taxRuleIndex
+     * @param TaxRule $taxRule
+     * @param TaxRule $initialTaxRule
+     */
+    public function processAssert(
+        TaxRuleNew $taxRuleNew,
+        TaxRuleIndex $taxRuleIndex,
+        TaxRule $taxRule,
+        TaxRule $initialTaxRule = null
+    ) {
+        $data = $taxRule->getData();
+        if ($initialTaxRule !== null) {
+            $taxRuleCode = ($taxRule->hasData('code')) ? $taxRule->getCode() : $initialTaxRule->getCode();
+        } else {
+            $taxRuleCode = $taxRule->getCode();
+        }
+        $filter = [
+            'code' => $taxRuleCode,
+        ];
+        $taxRuleIndex->open();
+        $taxRuleIndex->getTaxRuleGrid()->searchAndOpen($filter);
+        $taxRuleNew->getTaxRuleForm()->openAdditionalSettings();
+        $formData = $taxRuleNew->getTaxRuleForm()->getData($taxRule);
+        $dataDiff = $this->verifyForm($formData, $data);
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($dataDiff),
+            'Tax Rule form was filled not right.'
+            . "\nLog:\n" . implode(";\n", $dataDiff)
+        );
+    }
+
+    /**
+     * Verifying that form is filled right
+     *
+     * @param array $formData
+     * @param array $fixtureData
+     * @return array $errorMessage
+     */
+    protected function verifyForm(array $formData, array $fixtureData)
+    {
+        $errorMessage = [];
+
+        foreach ($fixtureData as $key => $value) {
+            if (is_array($value)) {
+                $diff = array_diff($value, $formData[$key]);
+                $diff = array_merge($diff, array_diff($formData[$key], $value));
+                if (!empty($diff)) {
+                    $errorMessage[] = "Data in " . $key . " field not equal."
+                        . "\nExpected: " . implode(", ", $value)
+                        . "\nActual: " . implode(", ", $formData[$key]);
+                }
+            } else {
+                if ($value !== $formData[$key]) {
+                    $errorMessage[] = "Data in " . $key . " field not equal."
+                        . "\nExpected: " . $value
+                        . "\nActual: " . $formData[$key];
+                }
+            }
+        }
+
+        return $errorMessage;
+    }
+
+    /**
+     * Text that form was filled right
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Tax Rule form has been filled right.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleInGrid.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..4decb13dc2a0c3fd2a7798ebfd97159232737351
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleInGrid.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Constraint;
+
+use Magento\Tax\Test\Fixture\TaxRule;
+use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertTaxRuleInGrid
+ */
+class AssertTaxRuleInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert tax rule availability in Tax Rule grid
+     *
+     * @param TaxRuleIndex $taxRuleIndex
+     * @param TaxRule $taxRule
+     * @param TaxRule $initialTaxRule
+     */
+    public function processAssert(
+        TaxRuleIndex $taxRuleIndex,
+        TaxRule $taxRule,
+        TaxRule $initialTaxRule = null
+    ) {
+        if ($initialTaxRule !== null) {
+            $taxRuleCode = ($taxRule->hasData('code')) ? $taxRule->getCode() : $initialTaxRule->getCode();
+        } else {
+            $taxRuleCode = $taxRule->getCode();
+        }
+        $filter = [
+            'code' => $taxRuleCode,
+        ];
+
+        $taxRuleIndex->open();
+        \PHPUnit_Framework_Assert::assertTrue(
+            $taxRuleIndex->getTaxRuleGrid()->isRowVisible($filter),
+            'Tax Rule \'' . $filter['code'] . '\' is absent in Tax Rule grid.'
+        );
+    }
+
+    /**
+     * Text of Tax Rule in grid assert
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Tax rule is present in grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleSuccessSaveMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d35eae41fc377fe29b9aa2ad49680d605270f54
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleSuccessSaveMessage.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Constraint;
+
+use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertSuccessSavedMessageTaxRule
+ */
+class AssertTaxRuleSuccessSaveMessage extends AbstractConstraint
+{
+    const SUCCESS_MESSAGE = 'The tax rule has been saved.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that success message is displayed after tax rule saved
+     *
+     * @param TaxRuleIndex $taxRuleIndex
+     * @return void
+     */
+    public function processAssert(TaxRuleIndex $taxRuleIndex)
+    {
+        $actualMessage = $taxRuleIndex->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Text of Created Tax Rule Success Message assert
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Tax rule success create message is present.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.php
index 83e70d29d18804b58b13745a7777f4bc0393c03b..246e8e1da3a77b4c33d9034dc68a1b08aca5843f 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.php
@@ -24,64 +24,73 @@
 
 namespace Magento\Tax\Test\Fixture;
 
-use Mtf\Factory\Factory;
-use Mtf\Fixture\DataFixture;
+use Mtf\Fixture\InjectableFixture;
 
 /**
  * Class TaxClass
- *
  */
-class TaxClass extends DataFixture
+class TaxClass extends InjectableFixture
 {
     /**
-     * Get tax class name
-     *
-     * @return string
+     * @var string
      */
-    public function getTaxClassName()
-    {
-        return $this->getData('fields/data/class_name/value');
-    }
+    protected $repositoryClass = 'Magento\Tax\Test\Repository\TaxClass';
 
     /**
-     * Return saved class id
-     *
-     * @return mixed
+     * @var string
      */
-    public function getTaxClassId()
+    protected $handlerInterface = 'Magento\Tax\Test\Handler\TaxClass\TaxClassInterface';
+
+    protected $defaultDataSet = [
+        'class_name' => 'Tax Class %isolation%',
+    ];
+
+    protected $class_id = [
+        'attribute_code' => 'class_id',
+        'backend_type' => 'smallint',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $class_name = [
+        'attribute_code' => 'class_name',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $class_type = [
+        'attribute_code' => 'class_type',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => 'CUSTOMER',
+        'input' => '',
+    ];
+
+    protected $id = [
+        'attribute_code' => 'id',
+        'backend_type' => 'virtual',
+    ];
+
+    public function getClassId()
     {
-        return $this->getData('fields/id');
+        return $this->getData('class_id');
     }
 
-    /**
-     * Create tax class
-     *
-     * @return TaxClass
-     */
-    public function persist()
+    public function getClassName()
     {
-        $id = Factory::getApp()->magentoTaxCreateTaxClass($this);
-        $this->_data['fields']['id'] = $id;
-        return $this;
+        return $this->getData('class_name');
     }
 
-    /**
-     * Init data
-     */
-    protected function _initData()
+    public function getClassType()
     {
-        $this->_data = array(
-            'fields' => array(
-                'class_name' => array(
-                    'value' => 'Customer Tax Class %isolation%'
-                ),
-                'class_type' => array(
-                    'value' => 'CUSTOMER'
-                )
-            )
-        );
+        return $this->getData('class_type');
+    }
 
-        $this->_repository = Factory::getRepositoryFactory()
-            ->getMagentoTaxTaxClass($this->_dataConfig, $this->_data);
+    public function getId()
+    {
+        return $this->getData('id');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ad14daa4f633ba606cad9c35718c27a73c75ce61
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxClass.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Tax\Test\Fixture\TaxClass">
+    <module>Magento_Tax</module>
+    <type>flat</type>
+    <entity_type>tax_class</entity_type>
+    <collection>Magento\Tax\Model\Resource\TaxClass\Collection</collection>
+    <identifier />
+    <fields>
+        <class_id>
+            <attribute_code>class_id</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required>1</is_required>
+            <default_value />
+            <input />
+        </class_id>
+        <class_name>
+            <attribute_code>class_name</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </class_name>
+        <class_type>
+            <attribute_code>class_type</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required />
+            <default_value>CUSTOMER</default_value>
+            <input />
+        </class_type>
+        <id>
+            <attribute_code>id</attribute_code>
+            <backend_type>virtual</backend_type>
+        </id>
+    </fields>
+    <data_set />
+    <data_config />
+    <repository_class>Magento\Tax\Test\Repository\TaxClass</repository_class>
+    <handler_interface>Magento\Tax\Test\Handler\TaxClass\TaxClassInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.php
index ccdc77fe296667b2c386a1b7740f8183e51e4a36..a71e5f2953b5561e4cea804e3ec965c487edbf23 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.php
@@ -24,73 +24,155 @@
 
 namespace Magento\Tax\Test\Fixture;
 
-use Mtf\Factory\Factory;
-use Mtf\Fixture\DataFixture;
+use Mtf\Fixture\InjectableFixture;
 
 /**
  * Class TaxRate
- *
  */
-class TaxRate extends DataFixture
+class TaxRate extends InjectableFixture
 {
     /**
-     * Get tax rate name
-     *
-     * @return string
+     * @var string
      */
-    public function getTaxRateName()
-    {
-        return $this->getData('code/value');
-    }
+    protected $repositoryClass = 'Magento\Tax\Test\Repository\TaxRate';
 
     /**
-     * Get tax rate id
-     *
-     * @return string
+     * @var string
      */
-    public function getTaxRateId()
+    protected $handlerInterface = 'Magento\Tax\Test\Handler\TaxRate\TaxRateInterface';
+
+    protected $defaultDataSet = [
+        'code' => 'Tax Rate %isolation%',
+        'rate' => '10',
+        'tax_country_id' => 'United States',
+        'tax_postcode' => '*',
+        'tax_region_id' => '0',
+    ];
+
+    protected $tax_calculation_rate_id = [
+        'attribute_code' => 'tax_calculation_rate_id',
+        'backend_type' => 'int',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $tax_country_id = [
+        'attribute_code' => 'tax_country_id',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $tax_region_id = [
+        'attribute_code' => 'tax_region_id',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $tax_postcode = [
+        'attribute_code' => 'tax_postcode',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $code = [
+        'attribute_code' => 'code',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $rate = [
+        'attribute_code' => 'rate',
+        'backend_type' => 'decimal',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $zip_is_range = [
+        'attribute_code' => 'zip_is_range',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $zip_from = [
+        'attribute_code' => 'zip_from',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $zip_to = [
+        'attribute_code' => 'zip_to',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $id = [
+        'attribute_code' => 'id',
+        'backend_type' => 'virtual',
+    ];
+
+    public function getTaxCalculationRateId()
     {
-        return $this->getData('fields/id');
+        return $this->getData('tax_calculation_rate_id');
     }
 
-    /**
-     * Create tax rate
-     *
-     * @return TaxRate
-     */
-    public function persist()
+    public function getTaxCountryId()
     {
-        $id = Factory::getApp()->magentoTaxCreateTaxRate($this);
-        $this->_data['fields']['id'] = $id;
-        return $this;
+        return $this->getData('tax_country_id');
     }
 
-    /**
-     * Init data
-     */
-    protected function _initData()
+    public function getTaxRegionId()
+    {
+        return $this->getData('tax_region_id');
+    }
+
+    public function getTaxPostcode()
+    {
+        return $this->getData('tax_postcode');
+    }
+
+    public function getCode()
+    {
+        return $this->getData('code');
+    }
+
+    public function getRate()
+    {
+        return $this->getData('rate');
+    }
+
+    public function getZipIsRange()
+    {
+        return $this->getData('zip_is_range');
+    }
+
+    public function getZipFrom()
+    {
+        return $this->getData('zip_from');
+    }
+
+    public function getZipTo()
+    {
+        return $this->getData('zip_to');
+    }
+
+    public function getId()
     {
-        $this->_data = array(
-            'fields' => array(
-                'code' => array(
-                    'value' => 'Tax Rate %isolation%'
-                ),
-                'rate' => array(
-                    'value' => '10'
-                ),
-                'tax_country_id' => array(
-                    'value' => 'US',
-                ),
-                'tax_postcode' => array(
-                    'value' => '*'
-                ),
-                'tax_region_id' => array(
-                    'value' => '0'
-                )
-            )
-        );
-
-        $this->_repository = Factory::getRepositoryFactory()
-            ->getMagentoTaxTaxRate($this->_dataConfig, $this->_data);
+        return $this->getData('id');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0ed8efa85c83ce381b8b6436174848e48c6a7edb
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRate.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Tax\Test\Fixture\TaxRate">
+    <module>Magento_Tax</module>
+    <type>flat</type>
+    <entity_type>tax_calculation_rate</entity_type>
+    <collection>Magento\Tax\Model\Resource\Calculation\Rate\Collection</collection>
+    <identifier>code</identifier>
+    <fields>
+        <tax_calculation_rate_id>
+            <attribute_code>tax_calculation_rate_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>1</is_required>
+            <default_value />
+            <input />
+        </tax_calculation_rate_id>
+        <tax_country_id>
+            <attribute_code>tax_country_id</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </tax_country_id>
+        <tax_region_id>
+            <attribute_code>tax_region_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </tax_region_id>
+        <tax_postcode>
+            <attribute_code>tax_postcode</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </tax_postcode>
+        <code>
+            <attribute_code>code</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </code>
+        <rate>
+            <attribute_code>rate</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </rate>
+        <zip_is_range>
+            <attribute_code>zip_is_range</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </zip_is_range>
+        <zip_from>
+            <attribute_code>zip_from</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </zip_from>
+        <zip_to>
+            <attribute_code>zip_to</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </zip_to>
+        <id>
+            <attribute_code>id</attribute_code>
+            <backend_type>virtual</backend_type>
+        </id>
+    </fields>
+    <data_set />
+    <data_config />
+    <repository_class>Magento\Tax\Test\Repository\TaxRate</repository_class>
+    <handler_interface>Magento\Tax\Test\Handler\TaxRate\TaxRateInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.php
index e115104b9146fa51641ca9bbdde7caa57f2e44dc..3a89dba95ff8b110e90071fc9281d01bb2d3ba6a 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.php
@@ -24,160 +24,114 @@
 
 namespace Magento\Tax\Test\Fixture;
 
-use Mtf\Factory\Factory;
-use Mtf\Fixture\DataFixture;
-use Mtf\System\Config;
+use Mtf\Fixture\InjectableFixture;
 
 /**
  * Class TaxRule
- *
  */
-class TaxRule extends DataFixture
+class TaxRule extends InjectableFixture
 {
     /**
-     * Initialize data and apply placeholders
-     *
-     * @param Config $configuration
-     * @param array $placeholders
+     * @var string
      */
-    public function __construct(Config $configuration, array $placeholders = array())
-    {
-        parent::__construct($configuration, $placeholders);
-
-        $this->_placeholders['us_ca_rate_8_25'] = array($this, '_getTaxRateId');
-        $this->_placeholders['uk_full_tax_rate'] = array($this, '_getTaxRateId');
-        $this->_placeholders['us_ny_rate_8_1'] = array($this, '_getTaxRateData');
-        $this->_placeholders['us_ny_rate_8_375'] = array($this, '_getTaxRateId');
-        $this->_placeholders['product_tax_class'] = array($this, '_getTaxClassId');
-        $this->_placeholders['customer_tax_class'] = array($this, '_getTaxClassId');
-    }
+    protected $repositoryClass = 'Magento\Tax\Test\Repository\TaxRule';
 
     /**
-     * Callback function returns created rate id
-     *
-     * @param string $dataSetName
-     * @return int
+     * @var string
      */
-    protected function _getTaxRateId($dataSetName)
-    {
-        $taxRate = Factory::getFixtureFactory()->getMagentoTaxTaxRate();
-        $taxRate->switchData($dataSetName);
-        return $taxRate->persist()->getTaxRateId();
-    }
+    protected $handlerInterface = 'Magento\Tax\Test\Handler\TaxRule\TaxRuleInterface';
 
-    /**
-     * Callback function returns class id
-     *
-     * @param string $dataSetName
-     * @return mixed
-     */
-    protected function _getTaxClassId($dataSetName)
-    {
-        $taxClass = Factory::getFixtureFactory()->getMagentoTaxTaxClass();
-        $taxClass->switchData($dataSetName);
-        return $taxClass->persist()->getTaxClassId();
-    }
+    protected $defaultDataSet = [
+        'code' => 'TaxIdentifier%isolation%',
+        'tax_rate' => [
+            'dataSet' => [
+                'US-CA-*-Rate 1'
+            ],
+        ],
+    ];
 
-    protected function _getTaxRateData($dataSetName)
-    {
-        $taxClass = Factory::getFixtureFactory()->getMagentoTaxTaxRate();
-        $taxClass->switchData($dataSetName);
-        return $taxClass->getData('fields');
-    }
+    protected $tax_calculation_rule_id = [
+        'attribute_code' => 'tax_calculation_rule_id',
+        'backend_type' => 'int',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
 
-    /**
-     * Get tax rule name
-     *
-     * @return string
-     */
-    public function getTaxRuleName()
+    protected $code = [
+        'attribute_code' => 'code',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $priority = [
+        'attribute_code' => 'priority',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $position = [
+        'attribute_code' => 'position',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $tax_rate = [
+        'attribute_code' => 'tax_rate',
+        'backend_type' => 'virtual',
+        'source' => 'Magento\Tax\Test\Fixture\TaxRule\TaxRate',
+    ];
+
+    protected $tax_customer_class = [
+        'attribute_code' => 'tax_customer_class',
+        'backend_type' => 'virtual',
+        'source' => 'Magento\Tax\Test\Fixture\TaxRule\TaxClass',
+    ];
+
+    protected $tax_product_class = [
+        'attribute_code' => 'tax_product_class',
+        'backend_type' => 'virtual',
+        'source' => 'Magento\Tax\Test\Fixture\TaxRule\TaxClass',
+    ];
+
+    public function getTaxCalculationRuleId()
     {
-        return $this->getData('fields/code/value');
+        return $this->getData('tax_calculation_rule_id');
     }
 
-    /**
-     * Get tax rule priority
-     *
-     * @return string
-     */
-    public function getTaxRulePriority()
+    public function getCode()
     {
-        return $this->getData('fields/priority/value');
+        return $this->getData('code');
     }
 
-    /**
-     * Get tax rule position
-     *
-     * @return string
-     */
-    public function getTaxRulePosition()
+    public function getPriority()
     {
-        return $this->getData('fields/position/value');
+        return $this->getData('priority');
     }
 
-    /**
-     * Get product/customer tax class
-     *
-     * @return string|array
-     */
-    public function getTaxRate()
+    public function getPosition()
     {
-        return $this->getData('fields/tax_rate');
+        return $this->getData('position');
     }
 
-    /**
-     * Get product/customer tax class
-     *
-     * @param string $taxClass (e.g. product|customer)
-     * @return string|array
-     */
-    public function getTaxClass($taxClass)
+    public function getTaxRate()
     {
-        return $this->getData('fields/tax_' . $taxClass . '_class/value');
+        return $this->getData('tax_rate');
     }
 
-    /**
-     * Create tax rule
-     *
-     * @return TaxRule
-     */
-    public function persist()
+    public function getTaxCustomerClass()
     {
-        Factory::getApp()->magentoTaxCreateTaxRule($this);
-        return $this;
+        return $this->getData('tax_customer_class');
     }
 
-    /**
-     * Init data
-     */
-    protected function _initData()
+    public function getTaxProductClass()
     {
-        $this->_data = array(
-            'fields' => array(
-                'code' => array(
-                    'value' => 'Tax Rule %isolation%'
-                ),
-                'tax_rate' => array(
-                    'value' => '1',
-                    'input_name' => 'tax_rate[]'
-                ),
-                'tax_product_class' => array(
-                    'value' => '2',
-                    'input_name' => 'tax_product_class[]'
-                ),
-                'tax_customer_class' => array(
-                    'value' => '3',
-                    'input_name' => 'tax_customer_class[]'
-                ),
-                'priority' => array(
-                    'value' => '0'
-                ),
-                'position' => array(
-                    'value' => '0'
-                )
-            )
-        );
-
-        $this->_repository = Factory::getRepositoryFactory()->getMagentoTaxTaxRule($this->_dataConfig, $this->_data);
+        return $this->getData('tax_product_class');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml
new file mode 100644
index 0000000000000000000000000000000000000000..70977f3adb97b4bea7510a8d38d569a4ec3b0031
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Tax\Test\Fixture\TaxRule">
+    <module>Magento_Tax</module>
+    <type>flat</type>
+    <entity_type>tax_calculation_rule</entity_type>
+    <collection>Magento\Tax\Model\Resource\Calculation\Rule\Collection</collection>
+    <identifier>code</identifier>
+    <fields>
+        <tax_calculation_rule_id>
+            <attribute_code>tax_calculation_rule_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>1</is_required>
+            <default_value />
+            <input />
+        </tax_calculation_rule_id>
+        <code>
+            <attribute_code>code</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </code>
+        <priority>
+            <attribute_code>priority</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </priority>
+        <position>
+            <attribute_code>position</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required />
+            <default_value />
+            <input />
+        </position>
+        <tax_rate>
+            <attribute_code>tax_rate</attribute_code>
+            <backend_type>virtual</backend_type>
+        </tax_rate>
+        <tax_customer_class>
+            <attribute_code>tax_customer_class</attribute_code>
+            <backend_type>virtual</backend_type>
+        </tax_customer_class>
+        <tax_product_class>
+            <attribute_code>tax_product_class</attribute_code>
+            <backend_type>virtual</backend_type>
+        </tax_product_class>
+    </fields>
+    <data_set />
+    <data_config />
+    <repository_class>Magento\Tax\Test\Repository\TaxRule</repository_class>
+    <handler_interface>Magento\Tax\Test\Handler\TaxRule\TaxRuleInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxClass.php
new file mode 100644
index 0000000000000000000000000000000000000000..4c52c1b111dd2d5f0dfca8a03b691013f97c363d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxClass.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Fixture\TaxRule;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+
+/**
+ * Class TaxClass
+ *
+ * Data keys:
+ *  - dataSet
+ */
+class TaxClass implements FixtureInterface
+{
+    /**
+     * Array with tax class names
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Array with tax class fixtures
+     *
+     * @var array
+     */
+    protected $fixture;
+
+    /**
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
+    {
+        $this->params = $params;
+        if (isset($data['dataSet'])) {
+            $dataSets = $data['dataSet'];
+            foreach ($dataSets as $dataSet) {
+                if ($dataSet !== '-') {
+                    /** @var \Magento\Tax\Test\Fixture\TaxClass $taxClass */
+                    $taxClass = $fixtureFactory->createByCode('taxClass', ['dataSet' => $dataSet]);
+                    $this->fixture[] = $taxClass;
+                    $this->data[] = $taxClass->getClassName();
+                }
+            }
+        }
+    }
+
+    /**
+     * Persist custom selections tax classes
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param $key [optional]
+     * @return mixed
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return string
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Return tax class fixture
+     *
+     * @return array
+     */
+    public function getFixture()
+    {
+        return $this->fixture;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxRate.php
new file mode 100644
index 0000000000000000000000000000000000000000..fbbbb82f9172595e256d7a0eb8d6418a342037c4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Fixture/TaxRule/TaxRate.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Fixture\TaxRule;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+
+/**
+ * Class TaxRate
+ *
+ * Data keys:
+ *  - dataSet
+ */
+class TaxRate implements FixtureInterface
+{
+    /**
+     * Array with tax rates codes
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Array with tax rate fixtures
+     *
+     * @var array
+     */
+    protected $fixture;
+
+    /**
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
+    {
+        $this->params = $params;
+        if (isset($data['dataSet'])) {
+            $dataSets = $data['dataSet'];
+            foreach ($dataSets as $dataSet) {
+                if ($dataSet !== '-') {
+                    /** @var \Magento\Tax\Test\Fixture\TaxRate $taxRate */
+                    $taxRate = $fixtureFactory->createByCode('taxRate', ['dataSet' => $dataSet]);
+                    $this->fixture[] = $taxRate;
+                    $this->data[] = $taxRate->getCode();
+                }
+            }
+        }
+    }
+
+    /**
+     * Persist custom selections tax rates
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param $key [optional]
+     * @return mixed
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return string
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Return tax rate fixtures
+     *
+     * @return array
+     */
+    public function getFixture()
+    {
+        return $this->fixture;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php
similarity index 74%
rename from dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxClass.php
rename to dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php
index 80f87b66f1d3e1f945269d9b70de2d4147e091fb..b3d25e63fdebf286f7e6996b37be8062886251f4 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxClass.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/Curl.php
@@ -18,25 +18,24 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @spi
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Tax\Test\Handler\Curl;
+namespace Magento\Tax\Test\Handler\TaxClass;
 
 use Mtf\Fixture\FixtureInterface;
-use Mtf\Handler\Curl;
+use Mtf\Handler\Curl as AbstractCurl;
 use Mtf\Util\Protocol\CurlInterface;
 use Mtf\Util\Protocol\CurlTransport;
 use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
 use Mtf\System\Config;
 
 /**
- * Curl handler for creating customer and product tax class.
- *
+ * Class Curl
+ * Curl handler for creating customer and product tax class
  */
-class CreateTaxClass extends Curl
+class Curl extends AbstractCurl implements TaxClassInterface
 {
     /**
      * Post request for creating tax class
@@ -46,28 +45,31 @@ class CreateTaxClass extends Curl
      */
     public function persist(FixtureInterface $fixture = null)
     {
-        $data = $fixture->getData('fields');
-        $fields = array();
-        foreach ($data as $key => $field) {
-            $fields[$key] = $field['value'];
-        }
+        $data = $fixture->getData();
+
         $url = $_ENV['app_backend_url'] . 'tax/tax/ajaxSAve/?isAjax=true';
         $curl = new BackendDecorator(new CurlTransport(), new Config());
-        $curl->write(CurlInterface::POST, $url, '1.0', array(), $fields);
+        $curl->write(CurlInterface::POST, $url, '1.0', array(), $data);
         $response = $curl->read();
         $curl->close();
-        return $this->_getClassId($response);
+
+        $id = $this->getClassId($response);
+        return ['id' => $id];
     }
 
     /**
      * Return saved class id if saved
      *
-     * @param string $data
+     * @param $response
      * @return int|null
+     * @throws \Exception
      */
-    protected function _getClassId($data)
+    protected function getClassId($response)
     {
-        $data = json_decode($data);
+        $data = json_decode($response);
+        if ($data->success !== true) {
+            throw new \Exception("Tax class creation by curl handler was not successful! Response: $response");
+        }
         return isset($data->class_id) ? (int)$data->class_id : null;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/TaxClassInterface.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/TaxClassInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..cd8c1ae059266231e3ca5fc96cbd139a07cf67d1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxClass/TaxClassInterface.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Handler\TaxClass;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface TaxClassInterface
+ */
+interface TaxClassInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php
similarity index 58%
rename from dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRate.php
rename to dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php
index bd59f767df4027860877d3b4c0336a5794ed930e..d76a231d2946ba7a80b192fba46b5a170049151a 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRate.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/Curl.php
@@ -18,26 +18,47 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @spi
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Tax\Test\Handler\Curl;
+namespace Magento\Tax\Test\Handler\TaxRate;
 
 use Mtf\Fixture\FixtureInterface;
-use Mtf\Handler\Curl;
+use Mtf\Handler\Curl as AbstractCurl;
 use Mtf\Util\Protocol\CurlInterface;
 use Mtf\Util\Protocol\CurlTransport;
 use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
 use Mtf\System\Config;
 
 /**
+ * Class Curl
  * Curl handler for creating Tax Rate
- *
  */
-class CreateTaxRate extends Curl
+class Curl extends AbstractCurl implements TaxRateInterface
 {
+    /**
+     * Mapping for countries
+     *
+     * @var array
+     */
+    protected $countryId = [
+        'AU' => 'Australia',
+        'US' => 'United States',
+        'GB' => 'United Kingdom',
+    ];
+
+    /**
+     * Mapping for regions
+     *
+     * @var array
+     */
+    protected $regionId = [
+        '0' => '*',
+        '12' => 'California',
+        '43' => 'New York',
+    ];
+
     /**
      * Post request for creating tax rate
      *
@@ -46,28 +67,37 @@ class CreateTaxRate extends Curl
      */
     public function persist(FixtureInterface $fixture = null)
     {
-        $data = $fixture->getData('fields');
-        $fields = array();
-        foreach ($data as $key => $field) {
-            $fields[$key] = $field['value'];
+        $data = $fixture->getData();
+        $data['tax_country_id'] = array_search($data['tax_country_id'], $this->countryId);
+        if (isset($data['tax_region_id'])) {
+            $data['tax_region_id'] = array_search($data['tax_region_id'], $this->regionId);
+        } else {
+            $data['tax_region_id'] = 0;
         }
+
         $url = $_ENV['app_backend_url'] . 'tax/rate/ajaxSave/?isAjax=true';
         $curl = new BackendDecorator(new CurlTransport(), new Config());
-        $curl->write(CurlInterface::POST, $url, '1.0', array(), $fields);
+        $curl->write(CurlInterface::POST, $url, '1.0', array(), $data);
         $response = $curl->read();
         $curl->close();
-        return $this->_getTaxRateId($response);
+
+        $id = $this->getTaxRateId($response);
+        return ['id' => $id];
     }
 
     /**
-     * Return saved rate id
+     * Return saved tax rate id
      *
-     * @param string $data
+     * @param $response
      * @return int|null
+     * @throws \Exception
      */
-    protected function _getTaxRateId($data)
+    protected function getTaxRateId($response)
     {
-        $data = json_decode($data);
+        $data = json_decode($response);
+        if ($data->success !== true) {
+            throw new \Exception("Tax rate creation by curl handler was not successful! Response: $response");
+        }
         return isset($data->tax_calculation_rate_id) ? (int)$data->tax_calculation_rate_id : null;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/TaxRateInterface.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/TaxRateInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..3468e23b7a22f44cf22779f9336396ed59855100
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRate/TaxRateInterface.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Handler\TaxRate;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface TaxRateInterface
+ */
+interface TaxRateInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php
similarity index 53%
rename from dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRule.php
rename to dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php
index 66a4cb5413f607c867e200177b90db7347965bf8..0779ad699ec9fd98397b5f808425ba577dd16267 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/Curl/CreateTaxRule.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/Curl.php
@@ -18,96 +18,89 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @spi
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Tax\Test\Handler\Curl;
+namespace Magento\Tax\Test\Handler\TaxRule;
 
 use Mtf\Fixture\FixtureInterface;
-use Mtf\Handler\Curl;
+use Mtf\Handler\Curl as AbstractCurl;
 use Mtf\Util\Protocol\CurlInterface;
 use Mtf\Util\Protocol\CurlTransport;
 use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
 use Mtf\System\Config;
 
 /**
- * Curl handler for creating Tax Rule.
- *
+ * Class Curl
+ * Curl handler for creating Tax Rule
  */
-class CreateTaxRule extends Curl
+class Curl extends AbstractCurl implements TaxRuleInterface
 {
     /**
-     * Returns data for curl POST params
+     * Default Tax Class values
      *
-     * @param $fixture
-     * @return array
+     * @var array
      */
-    public function _getPostParams($fixture)
-    {
-        $data = $fixture->getData('fields');
-        $fields = array();
-        foreach ($data as $key => $field) {
-            $value = $this->_getParamValue($field);
-
-            if (null === $value) {
-                continue;
-            }
-
-            $_key = $this->_getParamKey($field);
-            if (null === $_key) {
-                $_key = $key;
-            }
-            $fields[$_key] = $value;
-        }
-        return $fields;
-    }
+    protected $defaultTaxClasses = [
+        'tax_customer_class' => 3, // Retail Customer
+        'tax_product_class' => 2, // Taxable Goods
+    ];
 
     /**
-     * Return key for request
+     * Post request for creating tax rule
      *
-     * @param array $data
-     * @return null|string
+     * @param FixtureInterface $fixture
+     * @return mixed|null
      */
-    protected function _getParamKey(array $data)
+    public function persist(FixtureInterface $fixture = null)
     {
-        return isset($data['input_name']) ? $data['input_name'] : null;
+        $data = $this->prepareData($fixture);
+
+        $url = $_ENV['app_backend_url'] . 'tax/rule/save/?back=1';
+        $curl = new BackendDecorator(new CurlTransport(), new Config());
+        $curl->addOption(CURLOPT_HEADER, 1);
+        $curl->write(CurlInterface::POST, $url, '1.0', array(), $data);
+        $response = $curl->read();
+        $curl->close();
+
+        preg_match("~Location: [^\s]*\/rule\/(\d+)~", $response, $matches);
+        $id = isset($matches[1]) ? $matches[1] : null;
+        return ['id' => $id];
     }
 
     /**
-     * Return value for request
+     * Returns data for curl POST params
      *
-     * @param array $data
-     * @return null|string
+     * @param FixtureInterface $fixture
+     * @return mixed
      */
-    protected function _getParamValue(array $data)
+    protected function prepareData($fixture)
     {
-        if (array_key_exists('input_value', $data)) {
-            return $data['input_value'];
-        }
+        $data = $fixture->getData();
+        $fields = [
+            'tax_rate',
+            'tax_customer_class',
+            'tax_product_class',
+        ];
 
-        if (array_key_exists('value', $data)) {
-            return $data['value'];
+        foreach ($fields as $field) {
+            if (!array_key_exists($field, $data)) {
+                $data[$field][] = $this->defaultTaxClasses[$field];
+                continue;
+            }
+            $fieldFixture = $fixture->getDataFieldConfig($field);
+            $fieldFixture = $fieldFixture['source']->getFixture();
+            foreach ($data[$field] as $key => $value) {
+                $id = $fieldFixture[$key]->getId();
+                if ($id === null) {
+                    $fieldFixture[$key]->persist();
+                    $id = $fieldFixture[$key]->getId();
+                }
+                $data[$field][$key] = $id;
+            }
         }
-        return null;
-    }
 
-    /**
-     * Post request for creating tax rate
-     *
-     * @param FixtureInterface $fixture [optional]
-     * @return mixed|string
-     */
-    public function persist(FixtureInterface $fixture = null)
-    {
-        $url = $_ENV['app_backend_url'] . 'tax/rule/save/?back=1';
-        $curl = new BackendDecorator(new CurlTransport(), new Config());
-        $curl->addOption(CURLOPT_HEADER, 1);
-        $curl->write(CurlInterface::POST, $url, '1.0', array(), $this->_getPostParams($fixture));
-        $response = $curl->read();
-        $curl->close();
-        preg_match("~Location: [^\s]*\/rule\/(\d+)~", $response, $matches);
-        return isset($matches[1]) ? $matches[1] : null;
+        return $data;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/TaxRuleInterface.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/TaxRuleInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..560adf970ccc4a7ec5593b9772ad3b3fd7eb18ed
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Handler/TaxRule/TaxRuleInterface.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Handler\TaxRule;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface TaxRuleInterface
+ */
+interface TaxRuleInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..db54d44e9d6c4061ca84af427d9e83fc02ebecb5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class TaxRuleIndex
+ */
+class TaxRuleIndex extends BackendPage
+{
+    const MCA = 'tax/rule/index';
+
+    protected $_blocks = [
+        'gridPageActions' => [
+            'name' => 'gridPageActions',
+            'class' => 'Magento\Backend\Test\Block\GridPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'taxRuleGrid' => [
+            'name' => 'taxRuleGrid',
+            'class' => 'Magento\Tax\Test\Block\Adminhtml\Rule\Grid',
+            'locator' => '#taxRuleGrid',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Backend\Test\Block\GridPageActions
+     */
+    public function getGridPageActions()
+    {
+        return $this->getBlockInstance('gridPageActions');
+    }
+
+    /**
+     * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Grid
+     */
+    public function getTaxRuleGrid()
+    {
+        return $this->getBlockInstance('taxRuleGrid');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..af69bc3bf86e172bdc065edf3f18568a1456aa69
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleIndex.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="tax/rule/index">
+    <block>
+        <name>gridPageActions</name>
+        <class>Magento\Backend\Test\Block\GridPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>taxRuleGrid</name>
+        <class>Magento\Tax\Test\Block\Adminhtml\Rule\Grid</class>
+        <locator>#taxRuleGrid</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1fe5b94aac987eefd44439c7967bf092af5c63a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class TaxRuleNew
+ */
+class TaxRuleNew extends BackendPage
+{
+    const MCA = 'tax/rule/new';
+
+    protected $_blocks = [
+        'formPageActions' => [
+            'name' => 'formPageActions',
+            'class' => 'Magento\Backend\Test\Block\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'taxRuleForm' => [
+            'name' => 'taxRuleForm',
+            'class' => 'Magento\Tax\Test\Block\Adminhtml\Rule\Edit\Form',
+            'locator' => '#edit_form',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Backend\Test\Block\FormPageActions
+     */
+    public function getFormPageActions()
+    {
+        return $this->getBlockInstance('formPageActions');
+    }
+
+    /**
+     * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\Form
+     */
+    public function getTaxRuleForm()
+    {
+        return $this->getBlockInstance('taxRuleForm');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.xml
new file mode 100644
index 0000000000000000000000000000000000000000..efc8f5c65069b042045a8dc668cd04d011ccc03c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRuleNew.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="tax/rule/new">
+    <block>
+        <name>formPageActions</name>
+        <class>Magento\Backend\Test\Block\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>taxRuleForm</name>
+        <class>Magento\Tax\Test\Block\Adminhtml\Rule\Edit\Form</class>
+        <locator>#edit_form</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRule.php
deleted file mode 100644
index 56a065f7394b05c89f6ac578e0ab3e9857625b52..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRule.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @spi
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Tax\Test\Page;
-
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
-use Mtf\Client\Element\Locator;
-use Magento\Backend\Test\Block\GridPageActions;
-
-/**
- * Class TaxRule.
- * Tax rule manage grid.
- *
- */
-class TaxRule extends Page
-{
-    /**
-     * URL for customer login
-     */
-    const MCA = 'tax/rule/';
-
-    /**
-     * Tax rules grid
-     *
-     * @var string
-     */
-    protected $taxRuleGrid = '#taxRuleGrid';
-
-    /**
-     * Grid page actions block
-     *
-     * @var string
-     */
-    protected $pageActionsBlock = '.page-main-actions';
-
-    /**
-     * Custom constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_backend_url'] . self::MCA;
-    }
-
-    /**
-     * Get tax rules grid
-     *
-     * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Grid
-     */
-    public function getRuleGrid()
-    {
-        return Factory::getBlockFactory()->getMagentoTaxAdminhtmlRuleGrid(
-            $this->_browser->find($this->taxRuleGrid, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get Grid page actions block
-     *
-     * @return GridPageActions
-     */
-    public function getActionsBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoBackendGridPageActions(
-            $this->_browser->find($this->pageActionsBlock)
-        );
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRuleNew.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRuleNew.php
deleted file mode 100644
index a61abcab3350817d8c28fe04d3cdd30fce246b57..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/TaxRuleNew.php
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @spi
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Tax\Test\Page;
-
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
-use Mtf\Client\Element\Locator;
-use Magento\Backend\Test\Block\FormPageActions;
-
-/**
- * Class TaxRuleNew
- * Class for new tax rule page
- *
- */
-class TaxRuleNew extends Page
-{
-    /**
-     * URL for new tax rule
-     */
-    const MCA = 'tax/rule/new/';
-
-    /**
-     * Form for tax rule creation
-     *
-     * @var string
-     */
-    protected $editBlock = '[id="page:main-container"]';
-
-    /**
-     * Global messages block
-     *
-     * @var string
-     */
-    protected $messagesBlock = '#messages .messages';
-
-    /**
-     * Form page actions block
-     *
-     * @var string
-     */
-    protected $pageActionsBlock = '.page-main-actions';
-
-    /**
-     * Custom constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_backend_url'] . self::MCA;
-    }
-
-    /**
-     * Get form for tax rule creation
-     *
-     * @return \Magento\Tax\Test\Block\Adminhtml\Rule\Edit\Form
-     */
-    public function getEditBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoTaxAdminhtmlRuleEditForm(
-            $this->_browser->find($this->editBlock, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get global messages block
-     *
-     * @return \Magento\Core\Test\Block\Messages
-     */
-    public function getMessagesBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCoreMessages(
-            $this->_browser->find($this->messagesBlock, Locator::SELECTOR_CSS)
-        );
-    }
-
-    /**
-     * Get Form page actions block
-     *
-     * @return FormPageActions
-     */
-    public function getPageActionsBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoBackendFormPageActions(
-            $this->_browser->find($this->pageActionsBlock)
-        );
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.php
index 230e5a3447b303fc6188b84aa050386ab0f395c3..bfbc4b50cb0f239d4d139d3f9bbcbc91d3a5f4b5 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.php
@@ -27,25 +27,36 @@ namespace Magento\Tax\Test\Repository;
 use Mtf\Repository\AbstractRepository;
 
 /**
- * Class Tax Class Repository
- *
+ * Class TaxClass Repository
  */
 class TaxClass extends AbstractRepository
 {
-    public function __construct(array $defaultConfig = array(), array $defaultData = array())
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
     {
-        $this->_data['default'] = array(
-            'config' => $defaultConfig,
-            'data' => $defaultData
-        );
+        $this->_data['Taxable Goods'] = [
+            'class_id' => '2',
+            'class_name' => 'Taxable Goods',
+            'class_type' => 'PRODUCT',
+            'id' => '2',
+            'mtf_dataset_name' => 'Taxable Goods',
+        ];
+
+        $this->_data['Retail Customer'] = [
+            'class_id' => '3',
+            'class_name' => 'Retail Customer',
+            'class_type' => 'CUSTOMER',
+            'id' => '3',
+            'mtf_dataset_name' => 'Retail Customer',
+        ];
 
-        $this->_data['customer_tax_class'] = array(
-            'config' => $defaultConfig,
-            'data' => $defaultData
-        );
+        $this->_data['customer_tax_class'] = [
+            'class_name' => 'Customer Tax Class %isolation%',
+            'class_type' => 'CUSTOMER',
+        ];
 
-        $this->_data['product_tax_class'] = $this->_data['customer_tax_class'];
-        $this->_data['product_tax_class']['data']['fields']['class_name']['value'] = 'Product Tax Class %isolation%';
-        $this->_data['product_tax_class']['data']['fields']['class_type']['value'] = 'PRODUCT';
+        $this->_data['product_tax_class'] = [
+            'class_name' => 'Product Tax Class %isolation%',
+            'class_type' => 'PRODUCT',
+        ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3b8a8e20aa1b11f021a69def578706187b66fd9d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxClass.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<repository class="Magento\Tax\Test\Repository\TaxClass">
+    <item>
+        <class_id>2</class_id>
+        <class_name><![CDATA[Taxable Goods]]></class_name>
+        <class_type><![CDATA[PRODUCT]]></class_type>
+        <id>2</id>
+        <mtf_dataset_name><![CDATA[taxable_goods]]></mtf_dataset_name>
+    </item>
+    <item>
+        <class_id>3</class_id>
+        <class_name><![CDATA[Retail Customer]]></class_name>
+        <class_type><![CDATA[CUSTOMER]]></class_type>
+        <id>3</id>
+        <mtf_dataset_name><![CDATA[retail_customer]]></mtf_dataset_name>
+    </item>
+</repository>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php
index f0d0388a7dbc738cced73411135fe763ac9988f1..958373b4dc044d829b717addd416448cfa5a7914 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php
@@ -27,147 +27,92 @@ namespace Magento\Tax\Test\Repository;
 use Mtf\Repository\AbstractRepository;
 
 /**
- * Class Tax Rate Repository
- *
+ * Class TaxRate Repository
  */
 class TaxRate extends AbstractRepository
 {
-    /**
-     * Initialize default parameters
-     *
-     * @param array $defaultConfig
-     * @param array $defaultData
-     */
-    public function __construct(array $defaultConfig = array(), array $defaultData = array())
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
     {
-        $this->_data['default'] = array(
-            'config' => $defaultConfig,
-            'data' => $defaultData
-        );
+        $this->_data['US-CA-*-Rate 1'] = [
+            'tax_calculation_rate_id' => '1',
+            'tax_country_id' => 'US',
+            'tax_region_id' => '12',
+            'tax_postcode' => '*',
+            'code' => 'US-CA-*-Rate 1',
+            'rate' => '8.2500',
+            'zip_is_range' => '',
+            'zip_from' => '',
+            'zip_to' => '',
+            'id' => '1',
+            'mtf_dataset_name' => 'US-CA-*-Rate 1',
+        ];
 
-        $this->_data['us_ca_rate_8_25'] = array_replace_recursive($this->_data['default'], $this->_getRateUSCA());
-        $this->_data['us_ny_rate_8_375'] = array_replace_recursive($this->_data['default'], $this->_getRateUSNY());
-        $this->_data['us_ny_rate_8_1'] = array_replace_recursive($this->_data['default'], $this->_getRateUSNYCustom());
-        $this->_data['paypal_rate_8_25'] = array_replace_recursive($this->_data['default'], $this->_getRatePayPal());
-        $this->_data['uk_full_tax_rate'] = $this->getUKFullTaxRate($this->_data['default']);
-    }
+        $this->_data['US-NY-*-Rate 1'] = [
+            'tax_calculation_rate_id' => '2',
+            'tax_country_id' => 'US',
+            'tax_region_id' => '43',
+            'tax_postcode' => '*',
+            'code' => 'US-NY-*-Rate 1',
+            'rate' => '8.3750',
+            'zip_is_range' => '',
+            'zip_from' => '',
+            'zip_to' => '',
+            'id' => '2',
+            'mtf_dataset_name' => 'US-NY-*-Rate 1',
+        ];
 
-    /**
-     * Rate US CA with 8.25%
-     *
-     * @return array
-     */
-    protected function _getRateUSCA()
-    {
-        return array(
-            'data' => array(
-                'fields' => array(
-                    'rate' => array(
-                        'value' => '8.25'
-                    ),
-                    'tax_postcode' => array(
-                        'value' => '90230'
-                    ),
-                    'tax_region_id' => array(
-                        'value' => '12' // California
-                    )
-                )
-            )
-        );
-    }
+        $this->_data['us_ca_rate_8_25'] = [
+            'code' => 'Tax Rate %isolation%',
+            'rate' => '8.25',
+            'tax_country_id' => 'United States',
+            'tax_postcode' => '90230',
+            'tax_region_id' => 'California',
+        ];
 
-    /**
-     * Rate US CA with 8.25%
-     *
-     * @return array
-     */
-    protected function _getRatePayPal()
-    {
-        return array(
-            'data' => array(
-                'fields' => array(
-                    'rate' => array(
-                        'value' => '8.25'
-                    ),
-                    'tax_postcode' => array(
-                        'value' => '95131'
-                    ),
-                    'tax_region_id' => array(
-                        'value' => '12' // California
-                    )
-                )
-            )
-        );
-    }
+        $this->_data['us_ny_rate_8_375'] = [
+            'code' => 'Tax Rate %isolation%',
+            'rate' => '8.375',
+            'tax_country_id' => 'United States',
+            'tax_region_id' => 'New York',
+        ];
 
-    /**
-     * Rate US NY with 8.375%
-     *
-     * @return array
-     */
-    protected function _getRateUSNY()
-    {
-        return array(
-            'data' => array(
-                'fields' => array(
-                    'rate' => array(
-                        'value' => '8.375'
-                    ),
-                    'tax_region_id' => array(
-                        'value' => '43' // New York
-                    )
-                )
-            )
-        );
-    }
+        $this->_data['us_ny_rate_8_1'] = [
+            'code' => 'US-NY-*-%isolation%',
+            'rate' => '8.1',
+            'tax_country_id' => 'United States',
+            'tax_region_id' => 'New York',
+        ];
 
-    /**
-     * Rate US NY with 8.1%
-     *
-     * @return array
-     */
-    protected function _getRateUSNYCustom()
-    {
-        return array(
-            'data' => array(
-                'fields' => array(
-                    'code' => array(
-                        'value' => 'US-NY-*-%isolation%'
-                    ),
-                    'rate' => array(
-                        'value' => '8.1'
-                    ),
-                    'tax_region_id' => array(
-                        'value' => 'New York',
-                        'input' => 'select'
-                    )
-                )
-            )
-        );
-    }
+        $this->_data['paypal_rate_8_25'] = [
+            'code' => 'Tax Rate %isolation%',
+            'rate' => '8.25',
+            'tax_country_id' => 'United States',
+            'tax_postcode' => '95131',
+            'tax_region_id' => 'California',
+        ];
 
-    /**
-     * Get UK full tax rate
-     *
-     * @param array $defaultData
-     * @return array
-     */
-    protected function getUKFullTaxRate($defaultData)
-    {
-        return array_replace_recursive(
-            $defaultData,
-            array(
-                'data' => array(
-                    'fields' => array(
-                        'rate' => array(
-                            'value' => 20
-                        ),
-                        'tax_country_id' => array(
-                            'value' => 'GB',
-                        ),
-                    ),
-                ),
-            )
-        );
+        $this->_data['uk_full_tax_rate'] = [
+            'code' => 'Tax Rate %isolation%',
+            'rate' => '10',
+            'tax_country_id' => 'United Kingdom',
+            'tax_postcode' => '*',
+        ];
+
+        $this->_data['default'] = [
+            'code' => 'TaxIdentifier%isolation%',
+            'tax_postcode' => '*',
+            'tax_country_id' => 'Australia',
+            'rate' => '20'
+        ];
+
+        $this->_data['withZipRange'] = [
+            'code' => 'TaxIdentifier%isolation%',
+            'zip_is_range' => 'Yes',
+            'zip_from' => '90001',
+            'zip_to' => '96162',
+            'tax_country_id' => 'United States',
+            'tax_region_id' => 'California',
+            'rate' => '15.5'
+        ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c50d07947fdf8f4c46775c091ea45b522338e462
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<repository class="Magento\Tax\Test\Repository\TaxRate">
+    <item>
+        <tax_calculation_rate_id>1</tax_calculation_rate_id>
+        <tax_country_id><![CDATA[US]]></tax_country_id>
+        <tax_region_id>12</tax_region_id>
+        <tax_postcode><![CDATA[*]]></tax_postcode>
+        <code><![CDATA[US-CA-*-Rate 1]]></code>
+        <rate>8.2500</rate>
+        <zip_is_range><![CDATA[]]></zip_is_range>
+        <zip_from><![CDATA[]]></zip_from>
+        <zip_to><![CDATA[]]></zip_to>
+        <id>1</id>
+        <mtf_dataset_name><![CDATA[US-CA-*-Rate 1]]></mtf_dataset_name>
+    </item>
+    <item>
+        <tax_calculation_rate_id>2</tax_calculation_rate_id>
+        <tax_country_id><![CDATA[US]]></tax_country_id>
+        <tax_region_id>43</tax_region_id>
+        <tax_postcode><![CDATA[*]]></tax_postcode>
+        <code><![CDATA[US-NY-*-Rate 1]]></code>
+        <rate>8.3750</rate>
+        <zip_is_range><![CDATA[]]></zip_is_range>
+        <zip_from><![CDATA[]]></zip_from>
+        <zip_to><![CDATA[]]></zip_to>
+        <id>2</id>
+        <mtf_dataset_name><![CDATA[US-NY-*-Rate 1]]></mtf_dataset_name>
+    </item>
+</repository>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRule.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRule.php
index f72717da87010a3b5c24fbdf55d43e35bf8009d0..2b57af9581d929e0c591f3fac12fe1a318df5e0a 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRule.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRule.php
@@ -27,124 +27,98 @@ namespace Magento\Tax\Test\Repository;
 use Mtf\Repository\AbstractRepository;
 
 /**
- * Class Tax Rule Repository
- *
+ * Class TaxRule Repository
  */
 class TaxRule extends AbstractRepository
 {
-    /**
-     * Initialize repository data
-     *
-     * @param array $defaultConfig
-     * @param array $defaultData
-     */
-    public function __construct(array $defaultConfig = array(), array $defaultData = array())
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
     {
-        $this->_data['default'] = array(
-            'config' => $defaultConfig,
-            'data' => $defaultData
-        );
+        $this->_data['custom_rule'] = [
+            'code' => 'TaxIdentifier%isolation%',
+            'tax_rate' => [
+                'dataSet' => [
+                    0 => 'us_ca_rate_8_25',
+                    1 => 'us_ny_rate_8_375',
+                ]
+            ],
+        ];
 
-        $this->_data['custom_rule'] = array_replace_recursive($this->_data['default'], $this->_getCustomTaxRule());
-        $this->_data['us_ca_ny_rule'] = $this->_getUscanyTaxRule();
-        $this->_data['uk_full_tax_rule'] = $this->getUKFullTaxRule($this->_data['default']);
-    }
+        $this->_data['us_ca_ny_rule'] = [
+            'code' => 'Tax Rule %isolation%',
+            'tax_rate' => [
+                'dataSet' => [
+                    0 => 'US-CA-*-Rate 1',
+                    1 => 'us_ny_rate_8_1',
+                ],
+            ],
+            'tax_customer_class' => [
+                'dataSet' => [
+                    0 => 'Retail Customer',
+                    1 => 'customer_tax_class',
+                ],
+            ],
+            'tax_product_class' => [
+                'dataSet' => [
+                    0 => 'Taxable Goods',
+                    1 => 'product_tax_class',
+                ],
+            ],
+            'priority' => '0',
+            'position' => '0',
+        ];
 
-    /**
-     * Return data structure for Tax Rule with custom Rates, Tax class
-     *
-     * @return array
-     */
-    protected function _getCustomTaxRule()
-    {
-        return array(
-            'data' => array(
-                'fields' => array(
-                    'tax_rate[0]' => array(
-                        'value' => '%us_ca_rate_8_25%'
-                    ),
-                    'tax_rate[1]' => array(
-                        'value' => '%us_ny_rate_8_375%'
-                    ),
-                )
-            )
-        );
-    }
+        $this->_data['uk_full_tax_rule'] = [
+            'code' => 'TaxIdentifier%isolation%',
+            'tax_rate' => [
+                'dataSet' => [
+                    0 => 'uk_full_tax_rate',
+                ],
+            ],
+        ];
 
-    /**
-     * Return data structure for Tax Rule with custom Rates, Tax classes
-     *
-     * @return array
-     */
-    protected function _getUscanyTaxRule()
-    {
-        return array(
-            'data' => array(
-                'fields' => array(
-                    'code' => array(
-                        'value' => 'Tax Rule %isolation%'
-                    ),
-                    'tax_rate' => array(
-                        array(
-                            'code' => array(
-                                'value' => 'US-CA-*-Rate 1'
-                            )
-                        ),
-                        array(
-                            'code' => array(
-                                'value' => 'US-NY-*-%isolation%'
-                            ),
-                            'rate' => array(
-                                'value' => '8.1'
-                            ),
-                            'tax_region_id' => array(
-                                'value' => 'New York',
-                                'input' => 'select'
-                            )
-                        )
-                    ),
-                    'tax_customer_class' => array(
-                        'value' => array(
-                            'Retail Customer',
-                            'Customer Tax Class %isolation%'
-                        )
-                    ),
-                    'tax_product_class' => array(
-                        'value' => array(
-                            'Taxable Goods',
-                            'Product Tax Class %isolation%'
-                        )
-                    ),
-                    'priority' => array(
-                        'value' => '0'
-                    ),
-                    'position' => array(
-                        'value' => '0'
-                    )
-                )
-            )
-        );
-    }
+        $this->_data['tax_rule_default'] = [
+            'code' => 'TaxIdentifier%isolation%',
+            'tax_rate' => [
+                'dataSet' => [
+                    0 => 'US-CA-*-Rate 1'
+                ],
+            ],
+            'tax_customer_class' => [
+                'dataSet' => [
+                    0 => 'Retail Customer',
+                ],
+            ],
+            'tax_product_class' => [
+                'dataSet' => [
+                    0 => 'Taxable Goods',
+                ],
+            ],
+            'priority' => '1',
+            'position' => '1',
+        ];
 
-    /**
-     * Get UK full tax rule
-     *
-     * @param array $defaultData
-     * @return array
-     */
-    protected function getUKFullTaxRule($defaultData)
-    {
-        return array_replace_recursive(
-            $defaultData,
-            array(
-                'data' => array(
-                    'fields' => array(
-                        'tax_rate' => array(
-                            'value' => '%uk_full_tax_rate%'
-                        ),
-                    ),
-                ),
-            )
-        );
+        $this->_data['tax_rule_with_custom_tax_classes'] = [
+            'code' => 'TaxIdentifier%isolation%',
+            'tax_rate' => [
+                'dataSet' => [
+                    0 => 'US-CA-*-Rate 1',
+                    1 => 'US-NY-*-Rate 1',
+                ],
+            ],
+            'tax_customer_class' => [
+                'dataSet' => [
+                    0 => 'Retail Customer',
+                    1 => 'customer_tax_class',
+                ],
+            ],
+            'tax_product_class' => [
+                'dataSet' => [
+                    0 => 'Taxable Goods',
+                    1 => 'product_tax_class',
+                ],
+            ],
+            'priority' => '1',
+            'position' => '1',
+        ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..86180d2db3865f939936d30b326fa70795a21812
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\TestCase;
+
+use Magento\Tax\Test\Fixture\TaxRule;
+use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex;
+use Magento\Tax\Test\Page\Adminhtml\TaxRuleNew;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for CreateTaxRuleEntity
+ *
+ * Test Flow:
+ * 1. Log in as default admin user.
+ * 2. Go to Stores > Tax Rules.
+ * 3. Click 'Add New Tax Rule' button.
+ * 4. Fill in data according to dataSet
+ * 5. Save Tax Rule.
+ * 6. Perform all assertions.
+ *
+ * @group Tax_(CS)
+ * @ZephyrId MAGETWO-20913
+ */
+class CreateTaxRuleEntityTest extends Injectable
+{
+    /**
+     * @var TaxRuleIndex
+     */
+    protected $taxRuleIndexPage;
+
+    /**
+     * @var TaxRuleNew
+     */
+    protected $taxRuleNewPage;
+
+    /**
+     * @param TaxRuleIndex $taxRuleIndexPage
+     * @param TaxRuleNew $taxRuleNewPage
+     */
+    public function __inject(
+        TaxRuleIndex $taxRuleIndexPage,
+        TaxRuleNew $taxRuleNewPage
+    ) {
+        $this->taxRuleIndexPage = $taxRuleIndexPage;
+        $this->taxRuleNewPage = $taxRuleNewPage;
+    }
+
+    /**
+     * @param TaxRule $taxRule
+     */
+    public function testCreateTaxRule(TaxRule $taxRule)
+    {
+        // Steps
+        $this->taxRuleIndexPage->open();
+        $this->taxRuleIndexPage->getGridPageActions()->addNew();
+        $this->taxRuleNewPage->getTaxRuleForm()->fill($taxRule);
+        $this->taxRuleNewPage->getFormPageActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest/testCreateTaxRule.csv b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest/testCreateTaxRule.csv
new file mode 100644
index 0000000000000000000000000000000000000000..3b880e7f96e986298a49df1e54a34bce6c93466f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/CreateTaxRuleEntityTest/testCreateTaxRule.csv
@@ -0,0 +1,5 @@
+"taxRule/data/code";"taxRule/data/tax_rate/dataSet/rate_0";"taxRule/data/tax_rate/dataSet/rate_1";"taxRule/data/tax_rate/dataSet/rate_2";"taxRule/data/tax_customer_class/dataSet/class_0";"taxRule/data/tax_customer_class/dataSet/class_1";"taxRule/data/tax_product_class/dataSet/class_0";"taxRule/data/tax_product_class/dataSet/class_1";"taxRule/data/priority";"taxRule/data/position";"constraint"
+"TaxIdentifier%isolation%";"US-CA-*-Rate 1";"-";"-";"-";"-";"-";"-";"-";"-";"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm"
+"TaxIdentifier%isolation%";"US-CA-*-Rate 1";"US-NY-*-Rate 1";"-";"customer_tax_class";"-";"product_tax_class";"-";1;1;"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm"
+"TaxIdentifier%isolation%";"default";"US-NY-*-Rate 1";"US-CA-*-Rate 1";"Retail Customer";"customer_tax_class";"Taxable Goods";"-";"-";1;"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm"
+"TaxIdentifier%isolation%";"withZipRange";"US-CA-*-Rate 1";"-";"Retail Customer";"customer_tax_class";"Taxable Goods";"product_tax_class";1;"-";"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm"
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php
index 16e48a448dfec7c9dcde70349dcd552ff95df02c..c1d1dfd028e102b8d1226ed4f3ea155fade53c10 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/TaxRuleTest.php
@@ -18,6 +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    Mtf
+ * @package     Mtf
+ * @subpackage  functional_tests
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
@@ -31,7 +34,6 @@ use Magento\Tax\Test\Fixture\TaxRule;
 /**
  * Class TaxRuleTest
  * Functional test for Tax Rule configuration
- *
  */
 class TaxRuleTest extends Functional
 {
@@ -43,17 +45,17 @@ class TaxRuleTest extends Functional
     public function testCreateTaxRule()
     {
         //Data
-        $fixture = Factory::getFixtureFactory()->getMagentoTaxTaxRule();
-        $fixture->switchData('us_ca_ny_rule');
+        $objectManager = Factory::getObjectManager();
+        $fixture = $objectManager->create('\Magento\Tax\Test\Fixture\TaxRule', ['dataSet' => 'us_ca_ny_rule']);
         //Pages
-        $taxGridPage = Factory::getPageFactory()->getTaxRule();
+        $taxGridPage = Factory::getPageFactory()->getTaxRuleIndex();
         $newTaxRulePage = Factory::getPageFactory()->getTaxRuleNew();
         //Steps
         Factory::getApp()->magentoBackendLoginUser();
         $taxGridPage->open();
-        $taxGridPage->getActionsBlock()->addNew();
-        $newTaxRulePage->getEditBlock()->fill($fixture);
-        $newTaxRulePage->getPageActionsBlock()->saveAndContinue();
+        $taxGridPage->getGridPageActions()->addNew();
+        $newTaxRulePage->getTaxRuleForm()->fill($fixture);
+        $newTaxRulePage->getFormPageActions()->saveAndContinue();
         //Verifying
         $newTaxRulePage->getMessagesBlock()->assertSuccessMessage();
         $this->_assertOnGrid($fixture);
@@ -67,19 +69,19 @@ class TaxRuleTest extends Functional
     protected function _assertOnGrid(TaxRule $fixture)
     {
         //Data
-        $taxRates = array();
-        foreach ($fixture->getTaxRate() as $rate) {
-            $taxRates[] = $rate['code']['value'];
+        $filter = [
+            'code' => $fixture->getCode(),
+            'tax_rate' => implode(', ', $fixture->getTaxRate()),
+        ];
+        if ($fixture->getTaxCustomerClass() !== null) {
+            $filter['tax_customer_class'] = implode(', ', $fixture->getTaxCustomerClass());
+        }
+        if ($fixture->getTaxProductClass() !== null) {
+            $filter['tax_product_class'] = implode(', ', $fixture->getTaxProductClass());
         }
-        $filter = array(
-            'name' => $fixture->getTaxRuleName(),
-            'customer_tax_class' => implode(', ', $fixture->getTaxClass('customer')),
-            'product_tax_class' => implode(', ', $fixture->getTaxClass('product')),
-            'tax_rate' => implode(', ', $taxRates)
-        );
         //Verification
-        $taxGridPage = Factory::getPageFactory()->getTaxRule();
+        $taxGridPage = Factory::getPageFactory()->getTaxRuleIndex();
         $taxGridPage->open();
-        $this->assertTrue($taxGridPage->getRuleGrid()->isRowVisible($filter), 'New tax rule was not found.');
+        $this->assertTrue($taxGridPage->getTaxRuleGrid()->isRowVisible($filter), 'New tax rule was not found.');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/curl/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a27f5a1e18d03f8d0ec4732a6b7a73e45f98e0f5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/curl/di.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="\Magento\Tax\Test\Handler\TaxRule\TaxRuleInterface" type="\Magento\Tax\Test\Handler\TaxRule\Curl" />
+    <preference for="\Magento\Tax\Test\Handler\TaxRate\TaxRateInterface" type="\Magento\Tax\Test\Handler\TaxRate\Curl" />
+    <preference for="\Magento\Tax\Test\Handler\TaxClass\TaxClassInterface" type="\Magento\Tax\Test\Handler\TaxClass\Curl" />
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/constraint.xml
new file mode 100644
index 0000000000000000000000000000000000000000..54e405d8c0a07457dc17b36ff761b94e059b51c3
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/constraint.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<constraint>
+    <assertTaxRuleSuccessSaveMessage module="Magento_Tax">
+        <severeness>low</severeness>
+        <require>
+            <taxRuleIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex" />
+        </require>
+    </assertTaxRuleSuccessSaveMessage>
+    <assertTaxRuleInGrid module="Magento_Tax">
+        <severeness>high</severeness>
+        <require>
+            <taxRuleIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex" />
+            <taxRule class="Magento\Tax\Test\Fixture\TaxRule" />
+        </require>
+    </assertTaxRuleInGrid>
+    <assertTaxRuleForm module="Magento_Tax">
+        <severeness>high</severeness>
+        <require>
+            <taxRuleIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex" />
+            <taxRuleNew class="Magento\Tax\Test\Page\Adminhtml\TaxRuleNew" />
+            <taxRule class="Magento\Tax\Test\Fixture\TaxRule" />
+        </require>
+    </assertTaxRuleForm>
+</constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/fixture.xml
index 0b810461a68388cefb4566792c1e1b47aff83048..7632665296fd7968213f3d8b0952c3270fe768eb 100644
--- a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/fixture.xml
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/fixture.xml
@@ -26,19 +26,29 @@
 <fixture>
     <taxClass module="Magento_Tax">
         <type>flat</type>
-        <entity_type>tax_calculation_rate</entity_type>
+        <entity_type>tax_class</entity_type>
         <collection>Magento\Tax\Model\Resource\TaxClass\Collection</collection>
         <identifier />
-        <fields />
+        <fields>
+            <id>
+                <attribute_code>id</attribute_code>
+                <backend_type>virtual</backend_type>
+            </id>
+        </fields>
         <data_set />
         <data_config />
     </taxClass>
     <taxRate module="Magento_Tax">
         <type>flat</type>
-        <entity_type>tax_class</entity_type>
+        <entity_type>tax_calculation_rate</entity_type>
         <collection>Magento\Tax\Model\Resource\Calculation\Rate\Collection</collection>
         <identifier>code</identifier>
-        <fields />
+        <fields>
+            <id>
+                <attribute_code>id</attribute_code>
+                <backend_type>virtual</backend_type>
+            </id>
+        </fields>
         <data_set />
         <data_config />
     </taxRate>
@@ -47,7 +57,20 @@
         <entity_type>tax_calculation_rule</entity_type>
         <collection>Magento\Tax\Model\Resource\Calculation\Rule\Collection</collection>
         <identifier>code</identifier>
-        <fields />
+        <fields>
+            <tax_rate>
+                <attribute_code>tax_rate</attribute_code>
+                <backend_type>virtual</backend_type>
+            </tax_rate>
+            <tax_customer_class>
+                <attribute_code>tax_customer_class</attribute_code>
+                <backend_type>virtual</backend_type>
+            </tax_customer_class>
+            <tax_product_class>
+                <attribute_code>tax_product_class</attribute_code>
+                <backend_type>virtual</backend_type>
+            </tax_product_class>
+        </fields>
         <data_set />
         <data_config />
     </taxRule>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/page.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ddde8e9355ca77bf82ac69f253bdb124a7418407
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/etc/global/page.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page>
+    <taxRuleIndex>
+        <mca>tax/rule/index</mca>
+        <area>adminhtml</area>
+        <class>Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex</class>
+    </taxRuleIndex>
+    <taxRuleNew>
+        <mca>tax/rule/new</mca>
+        <area>adminhtml</area>
+        <class>Magento\Tax\Test\Page\Adminhtml\TaxRuleNew</class>
+    </taxRuleNew>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Links.php b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Links.php
index 254d85d35574f2953e131bdf5c91f78529138dc2..41120ea7989925890f581f148bcfb1c8ed162cca 100644
--- a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Links.php
+++ b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Links.php
@@ -47,4 +47,17 @@ class Links extends Block
             ->find('//a[contains(text(), "' . $linkTitle . '")]', Locator::SELECTOR_XPATH)
             ->click();
     }
+
+    /**
+     * Is visible Link by title
+     *
+     * @param string $linkTitle
+     * @return bool
+     */
+    public function isLinkVisible($linkTitle)
+    {
+        return $this->_rootElement
+            ->find('//a[contains(text(), "' . $linkTitle . '")]', Locator::SELECTOR_XPATH)
+            ->isVisible();
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd33825f2dced0795f9b00c66573c043ac138944
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Block\Adminhtml\Role;
+
+use Magento\Backend\Test\Block\Widget\FormTabs;
+
+/**
+ * Class Edit
+ * Role edit form page
+ *
+ * @package Magento\User\Test\Block\Adminhtml\Role
+ */
+class Edit extends FormTabs
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.xml b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5a9858f60d5586eb24b772516d007d2fe8d5cfe4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Edit.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<tabs>
+    <role-info>
+        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
+        <selector>#role_info_tabs_info</selector>
+        <strategy>css selector</strategy>
+        <fields>
+            <role_name>
+                <selector>[name='rolename']</selector>
+                <strategy>css selector</strategy>
+            </role_name>
+        </fields>
+    </role-info>
+    <role-resources-tab>
+        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
+        <selector>#role_info_tabs_account</selector>
+        <strategy>css selector</strategy>
+        <fields>
+            <resource_access>
+                <input>select</input>
+                <selector>#all</selector>
+                <strategy>css selector</strategy>
+            </resource_access>
+            <roles_resources>
+                <input>jquerytree</input>
+                <selector>[data-role="resource-tree"]</selector>
+                <strategy>css selector</strategy>
+            </roles_resources>
+        </fields>
+    </role-resources-tab>
+</tabs>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/PageActions.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/PageActions.php
new file mode 100644
index 0000000000000000000000000000000000000000..40fea7be4f42fc1f66977166969a57c43a10bc5b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/PageActions.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Block\Adminhtml\Role;
+
+use Magento\Backend\Test\Block\FormPageActions;
+
+/**
+ * Class PageActions
+ * PageActions for the role edit page
+ *
+ * @package Magento\User\Test\Block\Adminhtml\Role
+ */
+class PageActions extends FormPageActions
+{
+    /**
+     * "Save Role" button
+     *
+     * @var string
+     */
+    protected $saveButton = '.save-role';
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/RoleGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/RoleGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..62e9fb9d2be0b14ad14e8864ec446ff09b2fa7e0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/RoleGrid.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) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Block\Adminhtml;
+
+use Magento\Backend\Test\Block\Widget\Grid;
+
+/**
+ * Class RoleGrid
+ * Role grid on role index page
+ *
+ * @package Magento\User\Test\Block\Adminhtml
+ */
+class RoleGrid extends Grid
+{
+    /**
+     * Grid filters' selectors
+     *
+     * @var array
+     */
+    protected $filters = [
+        'id' => [
+            'selector' => '#roleGrid_filter_role_id'
+        ],
+        'role_name' => [
+            'selector' => '#roleGrid_filter_role_name'
+        ]
+    ];
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec96db7014d596ff5708b0a3f61477a1996393df
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\User\Test\Page\Adminhtml\UserRoleIndex;
+use Magento\User\Test\Fixture\AdminUserRole;
+
+/**
+ * Class AssertRoleInGrid
+ *
+ * @package Magento\User\Test\Constraint
+ */
+class AssertRoleInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that saved role is present in Role Grid.
+     *
+     * @return void
+     */
+    public function processAssert(
+        UserRoleIndex $rolePage,
+        AdminUserRole $role
+    ) {
+        $filter = ['role_name' => $role->getRoleName()];
+        $rolePage->open();
+        \PHPUnit_Framework_Assert::assertTrue(
+            $rolePage->getRoleGrid()->isRowVisible($filter),
+            'Role with name \'' . $role->getRoleName() . '\' is absent in Roles grid.'
+        );
+    }
+
+    /**
+     * Returns success message if assert true.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Role is present in Roles grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleSuccessSaveMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff1a4a3042f1245b97799a850474f685a49fbd24
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleSuccessSaveMessage.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\User\Test\Page\Adminhtml\UserRoleIndex;
+
+/**
+ * Class AssertRoleSuccessSaveMessage
+ *
+ * @package Magento\User\Test\Constraint
+ */
+class AssertRoleSuccessSaveMessage extends AbstractConstraint
+{
+
+    const SUCCESS_MESSAGE = 'You saved the role.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that success message equals to expected message.
+     *
+     * @return void
+     */
+    public function processAssert(UserRoleIndex $rolePage)
+    {
+        $successMessage = $rolePage->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $successMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_MESSAGE
+            . "\nActual: " . $successMessage
+        );
+    }
+
+    /**
+     * Returns success message if equals to expected message.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Success message on roles page is correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php
new file mode 100644
index 0000000000000000000000000000000000000000..e19d3c80dd79dc5fba42acae0eabf2b5e3dc34fa
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class AdminUserRole
+ *
+ * @package Magento\User\Test\Fixture
+ */
+class AdminUserRole extends InjectableFixture
+{
+    /**
+     * @var string
+     */
+    protected $repositoryClass = 'Magento\User\Test\Repository\AdminUserRole';
+
+    /**
+     * @var string
+     */
+    protected $handlerInterface = 'Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface';
+
+    protected $defaultDataSet = [
+        'rolename' => 'AdminRole%isolation%',
+        'resource_access' => 'All',
+    ];
+
+    protected $role_id = [
+        'attribute_code' => 'role_id',
+        'backend_type' => 'int',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $parent_id = [
+        'attribute_code' => 'parent_id',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $tree_level = [
+        'attribute_code' => 'tree_level',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $sort_order = [
+        'attribute_code' => 'sort_order',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $role_type = [
+        'attribute_code' => 'role_type',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $user_id = [
+        'attribute_code' => 'user_id',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $role_name = [
+        'attribute_code' => 'role_name',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $user_type = [
+        'attribute_code' => 'user_type',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $resource_access = [
+        'attribute_code' => 'resource_access',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $roles_resources = [
+        'attribute_code' => 'roles_resources',
+        'backend_type' => 'virtual',
+    ];
+
+    public function getRoleId()
+    {
+        return $this->getData('role_id');
+    }
+
+    public function getParentId()
+    {
+        return $this->getData('parent_id');
+    }
+
+    public function getTreeLevel()
+    {
+        return $this->getData('tree_level');
+    }
+
+    public function getSortOrder()
+    {
+        return $this->getData('sort_order');
+    }
+
+    public function getRoleType()
+    {
+        return $this->getData('role_type');
+    }
+
+    public function getUserId()
+    {
+        return $this->getData('user_id');
+    }
+
+    public function getRoleName()
+    {
+        return $this->getData('role_name');
+    }
+
+    public function getUserType()
+    {
+        return $this->getData('user_type');
+    }
+
+    public function getGwsIsAll()
+    {
+        return $this->getData('gws_is_all');
+    }
+
+    public function getGwsWebsites()
+    {
+        return $this->getData('gws_websites');
+    }
+
+    public function getGwsStoreGroups()
+    {
+        return $this->getData('gws_store_groups');
+    }
+
+    public function getResourceAccess()
+    {
+        return $this->getData('resource_access');
+    }
+
+    public function getRolesResources()
+    {
+        return $this->getData('roles_resources');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9d091e47fae3247548f3e8a86395e021f5826b62
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\User\Test\Fixture\AdminUserRole">
+    <module>Magento_User</module>
+    <type>flat</type>
+    <entity_type>admin_role</entity_type>
+    <collection>Magento\User\Model\Resource\Role\User\Collection</collection>
+    <fields>
+        <role_id>
+            <attribute_code>role_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input></input>
+        </role_id>
+        <parent_id>
+            <attribute_code>parent_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </parent_id>
+        <tree_level>
+            <attribute_code>tree_level</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </tree_level>
+        <sort_order>
+            <attribute_code>sort_order</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </sort_order>
+        <role_type>
+            <attribute_code>role_type</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </role_type>
+        <user_id>
+            <attribute_code>user_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </user_id>
+        <role_name>
+            <attribute_code>role_name</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </role_name>
+        <user_type>
+            <attribute_code>user_type</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </user_type>
+        <resource_access>
+            <attribute_code>resource_access</attribute_code>
+            <backend_type>virtual</backend_type>
+        </resource_access>
+        <roles_resources>
+            <attribute_code>roles_resources</attribute_code>
+            <backend_type>virtual</backend_type>
+        </roles_resources>
+    </fields>
+    <repository_class>Magento\User\Test\Repository\AdminUserRole</repository_class>
+    <handler_interface>Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0700c395e8ae6b88b67e4a60c80399ccf4d26d3
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class UserRoleEditRole
+ *
+ * @package Magento\User\Test\Page\Adminhtml
+ */
+class UserRoleEditRole extends BackendPage
+{
+    const MCA = 'admin/user_role/editrole';
+
+    protected $_blocks = [
+        'pageActions' => [
+            'name' => 'pageActions',
+            'class' => 'Magento\User\Test\Block\Adminhtml\Role\PageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'roleFormTabs' => [
+            'name' => 'roleFormTabs',
+            'class' => 'Magento\User\Test\Block\Adminhtml\Role\Edit',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\User\Test\Block\Adminhtml\Role\PageActions
+     */
+    public function getPageActions()
+    {
+        return $this->getBlockInstance('pageActions');
+    }
+
+    /**
+     * @return \Magento\User\Test\Block\Adminhtml\Role\Edit
+     */
+    public function getRoleFormTabs()
+    {
+        return $this->getBlockInstance('roleFormTabs');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.xml b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0f9ff486f6d61f93f141b4ec1d9f59cc828f67e5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleEditRole.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="admin/user_role/editrole" >
+    <block>
+        <name>pageActions</name>
+        <class>Magento\User\Test\Block\Adminhtml\Role\PageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>roleFormTabs</name>
+        <class>Magento\User\Test\Block\Adminhtml\Role\Edit</class>
+        <locator>[id="page:main-container"]</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4a81e25238cf8f4a4a32165766853c02821086f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class UserRoleIndex
+ *
+ * @package Magento\User\Test\Page\Adminhtml
+ */
+class UserRoleIndex extends BackendPage
+{
+    const MCA = 'admin/user_role/index';
+
+    protected $_blocks = [
+        'roleActions' => [
+            'name' => 'roleActions',
+            'class' => 'Magento\Backend\Test\Block\GridPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'roleGrid' => [
+            'name' => 'roleGrid',
+            'class' => 'Magento\User\Test\Block\Adminhtml\RoleGrid',
+            'locator' => '#roleGrid',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '.messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Backend\Test\Block\GridPageActions
+     */
+    public function getRoleActions()
+    {
+        return $this->getBlockInstance('roleActions');
+    }
+
+    /**
+     * @return \Magento\User\Test\Block\Adminhtml\RoleGrid
+     */
+    public function getRoleGrid()
+    {
+        return $this->getBlockInstance('roleGrid');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.xml b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bc7e240e0f2b6f51d9b83995dbccad5435996c9a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="admin/user_role/index" >
+    <block>
+        <name>roleActions</name>
+        <class>Magento\Backend\Test\Block\GridPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>roleGrid</name>
+        <class>Magento\User\Test\Block\Adminhtml\RoleGrid</class>
+        <locator>#roleGrid</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..796adf8faf3ec0537d4389b766586107a0a6b1e7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\TestCase;
+
+use Magento\User\Test\Fixture\AdminUserRole;
+use Magento\User\Test\Page\Adminhtml\UserRoleIndex;
+use Magento\User\Test\Page\Adminhtml\UserRoleEditRole;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for CreateAdminUserRolesEntity
+ *
+ * Test Flow:
+ * 1. Log in as default admin user
+ * 2. Go to System>Permissions>User Roles
+ * 3. Press "+" button to start create New Role
+ * 4. Fill in all data according to data set
+ * 5. Save role
+ * 6. Perform assertions
+ *
+ * @group ACL_(MX)
+ * @ZephyrId MAGETWO-23413
+ */
+class CreateAdminUserRoleEntityTest extends Injectable
+{
+    /**
+     * @var UserRoleIndex
+     */
+    protected $userRoleIndex;
+
+    /**
+     * @var UserRoleEditRole
+     */
+    protected $userRoleEditRole;
+
+    /**
+     * @param UserRoleIndex $userRoleIndex
+     * @param UserRoleEditRole $userRoleEditRole
+     */
+    public function __inject(
+        UserRoleIndex $userRoleIndex,
+        UserRoleEditRole $userRoleEditRole
+    ) {
+        $this->userRoleIndex = $userRoleIndex;
+        $this->userRoleEditRole = $userRoleEditRole;
+    }
+
+    /**
+     * Runs Create Admin User Role Entity test.
+     *
+     * @param AdminUserRole $role
+     */
+    public function testCreateUserRole(AdminUserRole $role)
+    {
+        //Steps
+        $this->userRoleIndex->open();
+        $this->userRoleIndex->getRoleActions()->addNew();
+        $this->userRoleEditRole->getRoleFormTabs()->fill($role);
+        $this->userRoleEditRole->getPageActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest/testCreateUserRole.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest/testCreateUserRole.csv
new file mode 100644
index 0000000000000000000000000000000000000000..b8c7ec03d178b52caf1064ca93331da2ce38ab01
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest/testCreateUserRole.csv
@@ -0,0 +1,3 @@
+"role/data/role_name";"role/data/resource_access";"role/data/roles_resources";"constraint"
+AdminRole%isolation%;Custom;Sales;"assertRoleSuccessSaveMessage, assertRoleInGrid"
+AdminRole%isolation%;All;-;"assertRoleSuccessSaveMessage, assertRoleInGrid"
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml
index e2906f2b20306654a70629d3225bb6367a644955..f11707ddacb4c2625533f9f2b5046522797c860f 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml
@@ -36,4 +36,16 @@
             <loginPage class="Magento\Backend\Test\Page\AdminAuthLogin" />
         </require>
     </invalidCredentials>
+   <assertRoleSuccessSaveMessage module="Magento_User">
+       <severeness>low</severeness>
+       <require>
+           <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleIndex" />
+       </require>
+   </assertRoleSuccessSaveMessage>
+   <assertRoleInGrid module="Magento_User">
+        <severeness>low</severeness>
+        <require>
+            <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleIndex" />
+        </require>
+   </assertRoleInGrid>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml
index f9a8a2587598e309945075c7f3bc30cb92ca9e39..7358eadc454d19864b0879f53b6e54fdd5934ba3 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml
@@ -29,4 +29,19 @@
         <entity_type>admin_user</entity_type>
         <collection>Magento\User\Model\Resource\User\Collection</collection>
     </adminUser>
+    <adminUserRole module="Magento_User">
+        <type>flat</type>
+        <entity_type>admin_role</entity_type>
+        <collection>Magento\User\Model\Resource\Role\User\Collection</collection>
+        <fields>
+            <resource_access>
+                <attribute_code>all</attribute_code>
+                <backend_type>virtual</backend_type>
+            </resource_access>
+            <roles_resources>
+                <attribute_code>roles_resources</attribute_code>
+                <backend_type>virtual</backend_type>
+            </roles_resources>
+        </fields>
+    </adminUserRole>
 </fixture>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/page.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6a38cc6d0b0f7b8404fdbbf2a2e9e2054ef9e427
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/page.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page>
+    <adminUserRoleIndex>
+        <mca>admin/user_role/index</mca>
+        <area>adminhtml</area>
+        <class>Magento\User\Test\Page\Adminhtml\UserRoleIndex</class>
+    </adminUserRoleIndex>
+    <adminUserRoleNew>
+        <mca>admin/user_role/editrole</mca>
+        <area>adminhtml</area>
+        <class>Magento\User\Test\Page\Adminhtml\UserRoleEditRole</class>
+    </adminUserRoleNew>
+</page>
\ No newline at end of file
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Application.php b/dev/tests/integration/framework/Magento/TestFramework/Application.php
index edcbf543fca0c71f63307de3c5b88deba846132a..e1fa69567bb53be2feb42dd4e6badbf13b3da009 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Application.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Application.php
@@ -149,7 +149,8 @@ class Application
                 Filesystem::STATIC_VIEW_DIR => array('path' => "{$installDir}/pub_static"),
                 Filesystem::PUB_VIEW_CACHE_DIR => array('path' => "{$installDir}/pub_cache"),
                 Filesystem::GENERATION_DIR => array('path' => $generationDir),
-                Filesystem::CACHE_DIR => array('path' => $installDir . '/cache')
+                Filesystem::CACHE_DIR => array('path' => $installDir . '/cache'),
+                Filesystem::LOG_DIR => array('path' => $installDir . '/log'),
             ),
             \Magento\Framework\App\State::PARAM_MODE => $appMode
         );
diff --git a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php
index 6599eb9b1cd64785d7af785c7e34c343b3af9745..97ef0078169dee5d38e9545d035fa47a2a5060c6 100644
--- a/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php
+++ b/dev/tests/integration/testsuite/Magento/Email/Model/Template/FilterTest.php
@@ -50,6 +50,23 @@ class FilterTest extends \PHPUnit_Framework_TestCase
         $this->assertStringEndsWith('favicon.ico', $url);
     }
 
+    /**
+     * Isolation level has been raised in order to flush themes configuration in-memory cache
+     *
+     * @magentoAppArea frontend
+     */
+    public function testBlockDirective()
+    {
+        $class = 'Magento\\\\Theme\\\\Block\\\\Html\\\\Footer';
+        $data = array("{{block class='$class' name='test.block' template='Magento_Theme::html/footer.phtml'}}",
+                'block',
+                " class='$class' name='test.block' template='Magento_Theme::html/footer.phtml'"
+
+            );
+        $html = $this->_model->blockDirective($data);
+        $this->assertContains('<div class="footer-container">', $html);
+    }
+
     /**
      * @magentoConfigFixture current_store web/unsecure/base_link_url http://example.com/
      * @magentoConfigFixture admin_store web/unsecure/base_link_url http://example.com/
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/CsvImportHandlerTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/CsvImportHandlerTest.php
index 3d3cfca5bf77ce4743330a4f9ec22390489c7c19..4fe351867310dc350b7dbdc1b13d4f0af770f6f1 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/CsvImportHandlerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/CsvImportHandlerTest.php
@@ -59,6 +59,7 @@ class CsvImportHandlerTest extends \PHPUnit_Framework_TestCase
         $this->assertNotEmpty($importedRuleCA->getId());
         $this->assertEquals(8.25, (double)$importedRuleCA->getRate());
         $this->assertEquals('US', $importedRuleCA->getTaxCountryId());
+        $this->assertEquals('*', $importedRuleCA->getTaxPostcode());
 
         $importedRuleFL = $objectManager->create(
             'Magento\Tax\Model\Calculation\Rate'
@@ -68,6 +69,7 @@ class CsvImportHandlerTest extends \PHPUnit_Framework_TestCase
         $this->assertNotEmpty($importedRuleFL->getId());
         $this->assertEquals(15, (double)$importedRuleFL->getRate());
         $this->assertEquals('US', $importedRuleFL->getTaxCountryId());
+        $this->assertNull($importedRuleFL->getTaxPostcode());
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/_files/correct_rates_import_file.csv b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/_files/correct_rates_import_file.csv
index 2c63dc259d96d96c4e84208aeddd144a071e9a94..2c5dc1d6905cf393598067c0530aece244f697fb 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/_files/correct_rates_import_file.csv
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/_files/correct_rates_import_file.csv
@@ -1,3 +1,3 @@
 "Code","Country","State","Zip/Post Code","Rate","Zip/Post is Range","Range From","Range To","default"
-"US-CA-*-Rate Import Test","US","CA","","8.2500","","","",""
+"US-CA-*-Rate Import Test","US","CA","*","8.2500","","","",""
 "US-FL-*-Rate Import Test","US","FL","","15.0000","","","",""
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
new file mode 100644
index 0000000000000000000000000000000000000000..be9f738483c99a252ea69c324a0abb6784503dfa
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
@@ -0,0 +1,669 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Model\Sales\Total\Quote;
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Calculation;
+
+class SetupUtil
+{
+    /**
+     * Default tax related configurations
+     *
+     * @var array
+     */
+    protected $defaultConfig = [
+        Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS => '0',
+        Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0, //Excluding tax
+        Config::CONFIG_XML_PATH_SHIPPING_INCLUDES_TAX => 0, //Excluding tax
+        Config::CONFIG_XML_PATH_BASED_ON => 'shipping', // or 'billing'
+        Config::CONFIG_XML_PATH_APPLY_ON => '0',
+        Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => '0',
+        Config::CONFIG_XML_PATH_DISCOUNT_TAX => '0',
+        Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE,
+        //@TODO: add config for cross border trade
+    ];
+
+    const TAX_RATE_TX = 'tax_rate_tx';
+    const TAX_RATE_SHIPPING = 'tax_rate_shipping';
+    const TAX_STORE_RATE = 'tax_store_rate';
+    const REGION_TX = '57';
+    const REGION_CA = '12';
+    const COUNTRY_US = 'US';
+    const AUSTIN_POST_CODE = '79729';
+
+    /**
+     * Tax rates
+     *
+     * @var array
+     */
+    protected $taxRates = [
+        self::TAX_RATE_TX => [
+            'data' => [
+                'tax_country_id' => self::COUNTRY_US,
+                'tax_region_id' => self::REGION_TX,
+                'tax_postcode' => '*',
+                'code' => self::TAX_RATE_TX,
+                'rate' => '20',
+            ],
+            'id' => null,
+        ],
+        self::TAX_RATE_SHIPPING => [
+            'data' => [
+                'tax_country_id' => self::COUNTRY_US,
+                'tax_region_id' => '*',
+                'tax_postcode' => '*',
+                'code' => self::TAX_RATE_SHIPPING,
+                'rate' => '7.5',
+            ],
+            'id' => null,
+        ],
+        self::TAX_STORE_RATE => [
+            'data' => [
+                'tax_country_id' => self::COUNTRY_US,
+                'tax_region_id' => self::REGION_CA,
+                'tax_postcode' => '*',
+                'code' => self::TAX_STORE_RATE,
+                'rate' => '8.25',
+            ],
+            'id' => null,
+        ],
+    ];
+
+    const PRODUCT_TAX_CLASS_1 = 'product_tax_class_1';
+    const PRODUCT_TAX_CLASS_2 = 'product_tax_class_2';
+    const SHIPPING_TAX_CLASS = 'shipping_tax_class';
+
+    /**
+     * List of product tax class that will be created
+     *
+     * @var array
+     */
+    protected $productTaxClasses = [
+        self::PRODUCT_TAX_CLASS_1 => null,
+        self::PRODUCT_TAX_CLASS_2 => null,
+        self::SHIPPING_TAX_CLASS => null,
+    ];
+
+    const CUSTOMER_TAX_CLASS_1 = 'customer_tax_class_1';
+
+    /**
+     * List of customer tax class to be created
+     *
+     * @var array
+     */
+    protected $customerTaxClasses = [
+        self::CUSTOMER_TAX_CLASS_1 => null,
+    ];
+
+    /**
+     * List of tax rules
+     *
+     * @var array
+     */
+    protected $taxRules = [];
+
+    const CONFIG_OVERRIDES = 'config_overrides';
+    const TAX_RATE_OVERRIDES = 'tax_rate_overrides';
+    const TAX_RULE_OVERRIDES = 'tax_rule_overrides';
+
+    /**
+     * Default data for shopping cart rule
+     *
+     * @var array
+     */
+    protected $defaultShoppingCartPriceRule = [
+        'name' => 'Shopping Cart Rule',
+        'is_active' => 1,
+        'customer_group_ids' => array(\Magento\Customer\Service\V1\CustomerGroupServiceInterface::CUST_GROUP_ALL),
+        'coupon_type' => \Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON,
+        'simple_action' => 'by_percent',
+        'discount_amount' => 40,
+        'stop_rules_processing' => 1,
+        'website_ids' => [1],
+    ];
+
+    /**
+     * Object manager
+     *
+     * @var \Magento\Framework\ObjectManager
+     */
+    var $objectManager;
+
+    /**
+     * @param \Magento\Framework\ObjectManager $objectManager
+     */
+    public function __construct($objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create customer tax classes
+     *
+     * @return $this
+     */
+    protected function createCustomerTaxClass()
+    {
+        foreach (array_keys($this->customerTaxClasses) as $className) {
+            $this->customerTaxClasses[$className] = $this->objectManager->create('Magento\Tax\Model\ClassModel')
+                ->setClassName($className)
+                ->setClassType(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER)
+                ->save()
+                ->getId();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Create product tax classes
+     *
+     * @return $this
+     */
+    protected function createProductTaxClass()
+    {
+        foreach (array_keys($this->productTaxClasses) as $className) {
+            $this->productTaxClasses[$className] = $this->objectManager->create('Magento\Tax\Model\ClassModel')
+                ->setClassName($className)
+                ->setClassType(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT)
+                ->save()
+                ->getId();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set the configuration.
+     *
+     * @param array $configData
+     * @return $this
+     */
+    protected function setConfig($configData)
+    {
+        /** @var \Magento\Core\Model\Resource\Config $config */
+        $config = $this->objectManager->get('Magento\Core\Model\Resource\Config');
+        foreach ($configData as $path => $value) {
+            if ($path == Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS) {
+                $value = $this->productTaxClasses[$value];
+            }
+            $config->saveConfig(
+                $path,
+                $value,
+                \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT,
+                0
+            );
+        }
+
+        /** @var \Magento\Framework\App\Config\ReinitableConfigInterface $config */
+        $config = $this->objectManager->get('Magento\Framework\App\Config\ReinitableConfigInterface');
+        $config->reinit();
+
+        return $this;
+    }
+
+    /**
+     * Create tax rates
+     *
+     * @param array $overrides
+     * @return $this
+     */
+    protected function createTaxRates($overrides)
+    {
+        $taxRateOverrides = empty($overrides[self::TAX_RATE_OVERRIDES]) ? [] : $overrides[self::TAX_RATE_OVERRIDES];
+        foreach (array_keys($this->taxRates) as $taxRateCode) {
+            if (isset($taxRateOverrides[$taxRateCode])) {
+                $this->taxRates[$taxRateCode]['data']['rate'] = $taxRateOverrides[$taxRateCode];
+            }
+            $this->taxRates[$taxRateCode]['id'] = $this->objectManager->create('Magento\Tax\Model\Calculation\Rate')
+                ->setData($this->taxRates[$taxRateCode]['data'])
+                ->save()
+                ->getId();
+        }
+        return $this;
+    }
+
+    /**
+     * Convert the code to id for productTaxClass, customerTaxClass and taxRate in taxRuleOverrideData
+     *
+     * @param array $taxRuleOverrideData
+     * @param array $taxRateIds
+     * @return array
+     */
+    protected function processTaxRuleOverrides($taxRuleOverrideData, $taxRateIds)
+    {
+        if (!empty($taxRuleOverrideData['tax_customer_class'])) {
+            $customerTaxClassIds = [];
+            foreach ($taxRuleOverrideData['tax_customer_class'] as $customerClassCode) {
+                $customerTaxClassIds[] = $this->customerTaxClasses[$customerClassCode];
+            }
+            $taxRuleOverrideData['tax_customer_class'] = $customerTaxClassIds;
+        }
+        if (!empty($taxRuleOverrideData['tax_product_class'])) {
+            $productTaxClassIds = [];
+            foreach ($taxRuleOverrideData['tax_product_class'] as $productClassCode) {
+                $productTaxClassIds[] = $this->productTaxClasses[$productClassCode];
+            }
+            $taxRuleOverrideData['tax_product_class'] = $productTaxClassIds;
+        }
+        if (!empty($taxRuleOverrideData['tax_rate'])) {
+            $taxRateIdsForRule = [];
+            foreach ($taxRuleOverrideData['tax_rate'] as $taxRateCode) {
+                $taxRateIdsForRule[] = $taxRateIds[$taxRateCode];
+            }
+            $taxRuleOverrideData['tax_rate'] = $taxRateIdsForRule;
+        }
+
+        return $taxRuleOverrideData;
+    }
+
+    /**
+     * Return a list of product tax class ids NOT including shipping product tax class
+     *
+     * @return array
+     */
+    protected function getProductTaxClassIds()
+    {
+        $productTaxClassIds = [];
+        foreach ($this->productTaxClasses as $productTaxClassName => $productTaxClassId) {
+            if ($productTaxClassName != self::SHIPPING_TAX_CLASS) {
+                $productTaxClassIds[] = $productTaxClassId;
+            }
+        }
+
+        return $productTaxClassIds;
+    }
+
+    /**
+     * Return a list of tax rate ids NOT including shipping tax rate
+     *
+     * @return array
+     */
+    protected function getTaxRateIds()
+    {
+        $taxRateIds = [];
+        foreach ($this->taxRates as $taxRateName => $taxRate) {
+            if ($taxRateName != self::TAX_RATE_SHIPPING) {
+                $taxRateIds[] = $taxRate['id'];
+            }
+        }
+
+        return $taxRateIds;
+    }
+
+    /**
+     * Return the default customer group tax class id
+     *
+     * @return int
+     */
+    public function getDefaultCustomerTaxClassId()
+    {
+        /** @var  \Magento\Customer\Service\V1\CustomerGroupServiceInterface $groupService */
+        $groupService = $this->objectManager->get('Magento\Customer\Service\V1\CustomerGroupServiceInterface');
+        $defaultGroup = $groupService->getDefaultGroup();
+        return $defaultGroup->getTaxClassId();
+    }
+
+    /**
+     * Create tax rules
+     *
+     * @param array $overrides
+     * @return $this
+     */
+    protected function createTaxRules($overrides)
+    {
+        $taxRateIds = [];
+        foreach ($this->taxRates as $taxRateCode => $taxRate) {
+            $taxRateIds[$taxRateCode] = $taxRate['id'];
+        }
+
+        //The default customer tax class id is used to calculate store tax rate
+        $customerClassIds = [
+            $this->customerTaxClasses[self::CUSTOMER_TAX_CLASS_1],
+            $this->getDefaultCustomerTaxClassId()
+        ];
+
+        //By default create tax rule that covers all product tax classes except SHIPPING_TAX_CLASS
+        //The tax rule will cover all tax rates except TAX_RATE_SHIPPING
+        $taxRuleDefaultData = [
+            'code' => 'Test Rule',
+            'priority' => '0',
+            'position' => '0',
+            'tax_customer_class' => $customerClassIds,
+            'tax_product_class' => $this->getProductTaxClassIds(),
+            'tax_rate' => $this->getTaxRateIds(),
+        ];
+
+        //Create tax rules
+        if (empty($overrides[self::TAX_RULE_OVERRIDES])) {
+            //Create separate shipping tax rule
+            $shippingTaxRuleData = [
+                'code' => 'Shipping Tax Rule',
+                'priority' => '0',
+                'position' => '0',
+                'tax_customer_class' => $customerClassIds,
+                'tax_product_class' => [$this->productTaxClasses[self::SHIPPING_TAX_CLASS]],
+                'tax_rate' => [$this->taxRates[self::TAX_RATE_SHIPPING]['id']],
+            ];
+            $this->taxRules[$shippingTaxRuleData['code']] = $this->objectManager
+                ->create('Magento\Tax\Model\Calculation\Rule')
+                ->setData($shippingTaxRuleData)
+                ->save()
+                ->getId();
+
+            //Create a default tax rule
+            $this->taxRules[$taxRuleDefaultData['code']] = $this->objectManager
+                ->create('Magento\Tax\Model\Calculation\Rule')
+                ->setData($taxRuleDefaultData)
+                ->save()
+                ->getId();
+        } else {
+            foreach ($overrides[self::TAX_RULE_OVERRIDES] as $taxRuleOverrideData ) {
+                //convert code to id for productTaxClass, customerTaxClass and taxRate
+                $taxRuleOverrideData = $this->processTaxRuleOverrides($taxRuleOverrideData, $taxRateIds);
+                $mergedTaxRuleData = array_merge($taxRuleDefaultData, $taxRuleOverrideData);
+                $this->taxRules[$mergedTaxRuleData['code']] = $this->objectManager
+                    ->create('Magento\Tax\Model\Calculation\Rule')
+                    ->setData($mergedTaxRuleData)
+                    ->save()
+                    ->getId();
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set up tax classes, tax rates and tax rules
+     * The override structure:
+     * override['self::CONFIG_OVERRIDES']
+     *      [
+     *          [config_path => config_value]
+     *      ]
+     * override['self::TAX_RATE_OVERRIDES']
+     *      [
+     *          ['tax_rate_code' => tax_rate]
+     *      ]
+     * override['self::TAX_RULE_OVERRIDES']
+     *      [
+     *          [
+     *              'code' => code //Required, has to be unique
+     *              'priority' => 0
+     *              'position' => 0
+     *              'tax_customer_class' => array of customer tax class names as defined in this class
+     *              'tax_product_class' => array of product tax class names as defined in this class
+     *              'tax_rate' => array of tax rate codes as defined in this class
+     *          ]
+     *      ]
+     *
+     * @param array $overrides
+     * @return void
+     */
+    public function setupTax($overrides)
+    {
+        //Create product tax classes
+        $this->createProductTaxClass();
+
+        //Create customer tax classes
+        $this->createCustomerTaxClass();
+
+        //Create tax rates
+        $this->createTaxRates($overrides);
+
+        //Create tax rules
+        $this->createTaxRules($overrides);
+
+        //Tax calculation configuration
+        if (!empty($overrides[self::CONFIG_OVERRIDES])) {
+            $this->setConfig($overrides[self::CONFIG_OVERRIDES]);
+        }
+    }
+
+    /**
+     * Create a simple product with given sku, price and tax class
+     *
+     * @param string $sku
+     * @param float $price
+     * @param int $taxClassId
+     * @return \Magento\Catalog\Model\Product
+     */
+    public function createSimpleProduct($sku, $price, $taxClassId)
+    {
+        /** @var \Magento\Catalog\Model\Product $product */
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product');
+        $product->isObjectNew(true);
+        $product->setTypeId('simple')
+            ->setAttributeSetId(4)
+            ->setName('Simple Product')
+            ->setSku($sku)
+            ->setPrice($price)
+            ->setTaxClassId($taxClassId)
+            ->setStockData(
+                [
+                    'use_config_manage_stock' => 1,
+                    'qty' => 100,
+                    'is_qty_decimal' => 0,
+                    'is_in_stock' => 1
+                ]
+            )->setMetaTitle('meta title')
+            ->setMetaKeyword('meta keyword')
+            ->setMetaDescription('meta description')
+            ->setVisibility(\Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH)
+            ->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED)
+            ->save();
+
+        $product = $product->load($product->getId());
+        return $product;
+    }
+
+    /**
+     * Create a customer group and associated it with given customer tax class
+     *
+     * @param int $customerTaxClassId
+     * @return int
+     */
+    protected function createCustomerGroup($customerTaxClassId)
+    {
+        /** @var \Magento\Customer\Service\V1\CustomerGroupService $customerGroupService */
+        $customerGroupService = $this->objectManager->create('Magento\Customer\Service\V1\CustomerGroupService');
+        $customerGroupBuilder = (new \Magento\Customer\Service\V1\Data\CustomerGroupBuilder())
+            ->setCode('custom_group')
+            ->setTaxClassId($customerTaxClassId);
+        $customerGroup = new \Magento\Customer\Service\V1\Data\CustomerGroup($customerGroupBuilder);
+        $customerGroupId = $customerGroupService->saveGroup($customerGroup);
+        return $customerGroupId;
+    }
+
+    /**
+     * Create a customer
+     *
+     * @return \Magento\Customer\Model\Customer
+     */
+    protected function createCustomer()
+    {
+        $customerGroupId = $this->createCustomerGroup($this->customerTaxClasses[self::CUSTOMER_TAX_CLASS_1]);
+        /** @var \Magento\Customer\Model\Customer $customer */
+        $customer = $this->objectManager->create('Magento\Customer\Model\Customer');
+        $customer->isObjectNew(true);
+        $customer->setWebsiteId(1)
+            ->setEntityTypeId(1)
+            ->setAttributeSetId(1)
+            ->setEmail('customer@example.com')
+            ->setPassword('password')
+            ->setGroupId($customerGroupId)
+            ->setStoreId(1)
+            ->setIsActive(1)
+            ->setFirstname('Firstname')
+            ->setLastname('Lastname')
+            ->save();
+
+        return $customer;
+    }
+
+    /**
+     * Create customer address
+     *
+     * @param array $addressOverride
+     * @param int $customerId
+     * @return \Magento\Customer\Model\Address
+     */
+    protected function createCustomerAddress($addressOverride, $customerId)
+    {
+        $defaultAddressData = [
+            'attribute_set_id' => 2,
+            'telephone' => 3468676,
+            'postcode' => self::AUSTIN_POST_CODE,
+            'country_id' => self::COUNTRY_US,
+            'city' => 'CityM',
+            'company' => 'CompanyName',
+            'street' => ['Green str, 67'],
+            'lastname' => 'Smith',
+            'firstname' => 'John',
+            'parent_id' => 1,
+            'region_id' => self::REGION_TX,
+        ];
+        $addressData = array_merge($defaultAddressData, $addressOverride);
+
+        /** @var \Magento\Customer\Model\Address $customerAddress */
+        $customerAddress = $this->objectManager->create('Magento\Customer\Model\Address');
+        $customerAddress->setData($addressData)
+            ->setCustomerId($customerId)
+            ->save();
+
+        return $customerAddress;
+    }
+
+    /**
+     * Create shopping cart rule
+     *
+     * @param array $ruleDataOverride
+     * @return $this
+     */
+    protected function createCartRule($ruleDataOverride)
+    {
+        /** @var \Magento\SalesRule\Model\Rule $salesRule */
+        $salesRule = $this->objectManager->create('Magento\SalesRule\Model\Rule');
+        $ruleData = array_merge($this->defaultShoppingCartPriceRule, $ruleDataOverride);
+        $salesRule->setData($ruleData);
+        $salesRule->save();
+
+        return $this;
+    }
+
+    /**
+     * Create a quote object with customer
+     *
+     * @param array $quoteData
+     * @param \Magento\Customer\Model\Customer $customer
+     * @return \Magento\Sales\Model\Quote
+     */
+    protected function createQuote($quoteData, $customer)
+    {
+        /** @var \Magento\Customer\Service\V1\CustomerAddressServiceInterface $addressService */
+        $addressService = $this->objectManager->create('Magento\Customer\Service\V1\CustomerAddressServiceInterface');
+
+        /** @var array $shippingAddressOverride */
+        $shippingAddressOverride = empty($quoteData['shipping_address']) ? [] : $quoteData['shipping_address'];
+        /** @var  \Magento\Customer\Model\Address $shippingAddress */
+        $shippingAddress = $this->createCustomerAddress($shippingAddressOverride, $customer->getId());
+
+        /** @var \Magento\Sales\Model\Quote\Address $quoteShippingAddress */
+        $quoteShippingAddress = $this->objectManager->create('Magento\Sales\Model\Quote\Address');
+        $quoteShippingAddress->importCustomerAddressData($addressService->getAddress($shippingAddress->getId()));
+
+        /** @var array $billingAddressOverride */
+        $billingAddressOverride = empty($quoteData['billing_address']) ? [] : $quoteData['billing_address'];
+        /** @var  \Magento\Customer\Model\Address $billingAddress */
+        $billingAddress = $this->createCustomerAddress($billingAddressOverride, $customer->getId());
+
+        /** @var \Magento\Sales\Model\Quote\Address $quoteBillingAddress */
+        $quoteBillingAddress = $this->objectManager->create('Magento\Sales\Model\Quote\Address');
+        $quoteBillingAddress->importCustomerAddressData($addressService->getAddress($billingAddress->getId()));
+
+        /** @var \Magento\Sales\Model\Quote $quote */
+        $quote = $this->objectManager->create('Magento\Sales\Model\Quote');
+        $quote->setStoreId(1)
+            ->setIsActive(true)
+            ->setIsMultiShipping(false)
+            ->assignCustomerWithAddressChange($customer, $quoteBillingAddress, $quoteShippingAddress)
+            ->setCheckoutMethod($customer->getMode())
+            ->setPasswordHash($customer->encryptPassword($customer->getPassword()));
+
+        return $quote;
+    }
+
+    /**
+     * Add products to quote
+     *
+     * @param \Magento\Sales\Model\Quote $quote
+     * @param array $itemsData
+     * @return $this
+     */
+    protected function addProductToQuote($quote, $itemsData)
+    {
+        foreach ($itemsData as $itemData) {
+            $sku = $itemData['sku'];
+            $price = $itemData['price'];
+            $qty = isset($itemData['qty']) ? $itemData['qty'] : 1;
+            $taxClassName =
+                isset($itemData['tax_class_name']) ? $itemData['tax_class_name'] : self::PRODUCT_TAX_CLASS_1;
+            $taxClassId = $this->productTaxClasses[$taxClassName];
+            $product = $this->createSimpleProduct($sku, $price, $taxClassId);
+            $quote->addProduct($product, $qty);
+        }
+        return $this;
+    }
+
+    /**
+     * Create a quote based on given data
+     *
+     * @param array $quoteData
+     * @return \Magento\Sales\Model\Quote
+     */
+    public function setupQuote($quoteData)
+    {
+        $customer = $this->createCustomer();
+
+        $quote = $this->createQuote($quoteData, $customer);
+
+        $this->addProductToQuote($quote, $quoteData['items']);
+
+        //Set shipping amount
+        if (isset($quoteData['shipping_method'])) {
+            $quote->getShippingAddress()->setShippingMethod($quoteData['shipping_method']);
+            $quote->getShippingAddress()->setCollectShippingRates(true);
+        }
+
+        //create shopping cart rules if necessary
+        if (!empty($quoteData['shopping_cart_rules'])) {
+            foreach ($quoteData['shopping_cart_rules'] as $ruleData) {
+                $ruleData['customer_group_ids'] = array($customer->getGroupId());
+                $this->createCartRule($ruleData);
+            }
+        }
+
+        return $quote;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php
index 6aba699d1fdb02f8bc33ba7abdd90b4b09a902c6..301e0d8d8190a3701e8b48e38985e0f2e6bf4bb9 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/TaxTest.php
@@ -24,9 +24,21 @@
 namespace Magento\Tax\Model\Sales\Total\Quote;
 
 use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Calculation;
+
+require_once __DIR__ . '/SetupUtil.php';
+require_once __DIR__ . '/../../../../_files/tax_calculation_data_aggregated.php';
 
 class TaxTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * Utility object for setting up tax rates, tax classes and tax rules
+     *
+     * @var SetupUtil
+     */
+    protected $setupUtil = null;
+
     /**
      * Test taxes collection for quote.
      *
@@ -123,4 +135,157 @@ class TaxTest extends \PHPUnit_Framework_TestCase
             'Customer tax was collected by \Magento\Tax\Model\Sales\Total\Quote\Tax::collect incorrectly.'
         );
     }
+
+    /**
+     * Verify fields in quote item
+     *
+     * @param \Magento\Sales\Model\Quote\Address\Item $item
+     * @param array $expectedItemData
+     * @return $this
+     */
+    protected function verifyItem($item, $expectedItemData)
+    {
+        foreach ($expectedItemData as $key => $value) {
+            $this->assertEquals($value, $item->getData($key), 'item ' . $key . ' is incorrect');
+        }
+
+        return $this;
+    }
+
+    /**
+     * Verify one tax rate in a tax row
+     *
+     * @param array $appliedTaxRate
+     * @param array $expectedAppliedTaxRate
+     * @return $this
+     */
+    protected function verifyAppliedTaxRate($appliedTaxRate, $expectedAppliedTaxRate)
+    {
+        foreach ($expectedAppliedTaxRate as $key => $value) {
+            $this->assertEquals($value, $appliedTaxRate[$key], 'Applied tax rate ' . $key . ' is incorrect');
+        }
+        return $this;
+    }
+
+    /**
+     * Verify one row in the applied taxes
+     *
+     * @param array $appliedTax
+     * @param array $expectedAppliedTax
+     * @return $this
+     */
+    protected function verifyAppliedTax($appliedTax, $expectedAppliedTax)
+    {
+        foreach ($expectedAppliedTax as $key => $value) {
+            if ($key == 'rates') {
+                foreach ($value as $index => $taxRate) {
+                    $this->verifyAppliedTaxRate($appliedTax['rates'][$index], $taxRate);
+                }
+            } else {
+                $this->assertEquals($value, $appliedTax[$key], 'Applied tax ' . $key . ' is incorrect');
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Verify that applied taxes are correct
+     *
+     * @param array $appliedTaxes
+     * @param array $expectedAppliedTaxes
+     * @return $this
+     */
+    protected function verifyAppliedTaxes($appliedTaxes, $expectedAppliedTaxes)
+    {
+        foreach ($expectedAppliedTaxes as $taxRateKey => $expectedTaxRate) {
+            $this->assertTrue(isset($appliedTaxes[$taxRateKey]), 'Missing tax rate ' . $taxRateKey );
+            $this->verifyAppliedTax($appliedTaxes[$taxRateKey], $expectedTaxRate);
+        }
+        return $this;
+    }
+
+    /**
+     * Verify fields in quote address
+     *
+     * @param \Magento\Sales\Model\Quote\Address $quoteAddress
+     * @param array $expectedAddressData
+     * @return $this
+     */
+    protected function verifyQuoteAddress($quoteAddress, $expectedAddressData)
+    {
+
+        foreach ($expectedAddressData as $key => $value) {
+            if ($key == 'applied_taxes') {
+                $this->verifyAppliedTaxes($quoteAddress->getAppliedTaxes(), $value);
+            } else {
+                $this->assertEquals($value, $quoteAddress->getData($key), 'Quote address ' . $key . ' is incorrect');
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Verify fields in quote address and quote item are correct
+     *
+     * @param \Magento\Sales\Model\Quote\Address $quoteAddress
+     * @param array $expectedResults
+     * @return $this
+     */
+    protected function verifyResult($quoteAddress, $expectedResults)
+    {
+        $addressData = $expectedResults['address_data'];
+
+        $this->verifyQuoteAddress($quoteAddress, $addressData);
+
+        $quoteItems = $quoteAddress->getAllItems();
+        foreach ($quoteItems as $item) {
+            /** @var  \Magento\Sales\Model\Quote\Address\Item $item */
+            $sku = $item->getProduct()->getSku();
+            $expectedItemData = $expectedResults['items_data'][$sku];
+            $this->verifyItem($item, $expectedItemData);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Test tax calculation with various configuration and combination of items
+     * This method will test various collectors through $quoteAddress->collectTotals() method
+     *
+     * @param array $configData
+     * @param array $quoteData
+     * @param array $expectedResults
+     * @magentoDbIsolation enabled
+     * @dataProvider taxDataProvider
+     * @return void
+     */
+    public function testTaxCalculation($configData, $quoteData, $expectedResults)
+    {
+        Bootstrap::getInstance()->reinitialize();
+        /** @var  \Magento\Framework\ObjectManager $objectManager */
+        $objectManager = Bootstrap::getObjectManager();
+
+        //Setup tax configurations
+        $this->setupUtil = new SetupUtil($objectManager);
+        $this->setupUtil->setupTax($configData);
+
+        $quote = $this->setupUtil->setupQuote($quoteData);
+        $quoteAddress = $quote->getShippingAddress();
+
+        $quoteAddress->collectTotals();
+        $this->verifyResult($quoteAddress, $expectedResults);
+    }
+
+    /**
+     * Read the array defined in ../../../../_files/tax_calculation_data_aggregated.php
+     * and feed it to testTaxCalculation
+     *
+     * @return array
+     */
+    public function taxDataProvider()
+    {
+        global $taxCalculationData;
+        return $taxCalculationData;
+    }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a25277044d95b7293bbb47368f0a1cad383b982
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+
+$taxCalculationData['excluding_tax_apply_tax_after_discount'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS => SetupUtil::SHIPPING_TAX_CLASS,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 20,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+            [
+                //tax rule for product
+                'code' => 'Product Tax Rule',
+                'tax_product_class' => [SetupUtil::PRODUCT_TAX_CLASS_1],
+            ],
+            [
+                //tax rule for shipping
+                'code' => 'Shipping Tax Rule',
+                'tax_product_class' => [SetupUtil::SHIPPING_TAX_CLASS],
+                'tax_rate' => [SetupUtil::TAX_RATE_SHIPPING],
+            ],
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10,
+                'qty' => 2,
+            ],
+        ],
+        'shipping_method' => 'flatrate_flatrate',
+        'shopping_cart_rules' => [
+            [
+                'discount_amount' => 50,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 20,
+            'base_subtotal' => 20,
+            'subtotal_incl_tax' => 24,
+            'base_subtotal_incl_tax' => 24,
+            'tax_amount' => 2.75,
+            'base_tax_amount' => 2.75,
+            'shipping_amount' => 10,
+            'base_shipping_amount' => 10,
+            'shipping_incl_tax' => 10.75,
+            'base_shipping_incl_tax' => 10.75,
+            'shipping_taxable' => 10,
+            'base_shipping_taxable' => 10,
+            'shipping_tax_amount' => 0.75,
+            'base_shipping_tax_amount' => 0.75,
+            'discount_amount' => -10,
+            'base_discount_amount' => -10,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 22.75,
+            'base_grand_total' => 22.75,
+            'applied_taxes' => [
+                SetupUtil::TAX_RATE_TX => [
+                    'percent' => 20,
+                    'amount' => 2,
+                    'base_amount' => 2,
+                    'rates' => [
+                        [
+                            'code' => SetupUtil::TAX_RATE_TX,
+                            'title' => SetupUtil::TAX_RATE_TX,
+                            'percent' => 20,
+                        ],
+                    ],
+                ],
+                SetupUtil::TAX_RATE_SHIPPING => [
+                    'percent' => 7.5,
+                    'amount' => 0.75,
+                    'base_amount' => 0.75,
+                    'rates' => [
+                        [
+                            'code' => SetupUtil::TAX_RATE_SHIPPING,
+                            'title' => SetupUtil::TAX_RATE_SHIPPING,
+                            'percent' => 7.5,
+                        ],
+                    ],
+                ],
+            ],
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 20,
+                'base_row_total' => 20,
+                'taxable_amount' => 20,
+                'base_taxable_amount' => 20,
+                'tax_percent' => 20,
+                'price' => 10,
+                'base_price' => 10,
+                'price_incl_tax' => 12,
+                'base_price_incl_tax' => 12,
+                'row_total_incl_tax' => 24,
+                'base_row_total_incl_tax' => 24,
+                'tax_amount' => 2,
+                'base_tax_amount' => 2,
+                'discount_amount' => 10,
+                'base_discount_amount' => 10,
+                'discount_percent' => 50,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.php
new file mode 100644
index 0000000000000000000000000000000000000000..9eaffb5eb7526cf2a2c3f9e46a4771153473de62
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+
+$taxCalculationData['excluding_tax_apply_tax_before_discount'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_SHIPPING_TAX_CLASS => SetupUtil::PRODUCT_TAX_CLASS_1,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 20,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10,
+                'qty' => 2,
+            ],
+        ],
+        'shipping_method' => 'flatrate_flatrate',
+        'shopping_cart_rules' => [
+            [
+                'discount_amount' => 50,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 20,
+            'base_subtotal' => 20,
+            'subtotal_incl_tax' => 24,
+            'base_subtotal_incl_tax' => 24,
+            'tax_amount' => 6,
+            'base_tax_amount' => 6,
+            'shipping_amount' => 10,
+            'base_shipping_amount' => 10,
+            'shipping_incl_tax' => 12,
+            'base_shipping_incl_tax' => 12,
+            'shipping_taxable' => 10,
+            'base_shipping_taxable' => 10,
+            'shipping_tax_amount' => 2,
+            'base_shipping_tax_amount' => 2,
+            'discount_amount' => -10,
+            'base_discount_amount' => -10,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 26,
+            'base_grand_total' => 26,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 20,
+                'base_row_total' => 20,
+                'taxable_amount' => 20,
+                'base_taxable_amount' => 20,
+                'tax_percent' => 20,
+                'price' => 10,
+                'base_price' => 10,
+                'price_incl_tax' => 12,
+                'base_price_incl_tax' => 12,
+                'row_total_incl_tax' => 24,
+                'base_row_total_incl_tax' => 24,
+                'tax_amount' => 4,
+                'base_tax_amount' => 4,
+                'discount_amount' => 10,
+                'base_discount_amount' => 10,
+                'discount_percent' => 50,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.php
new file mode 100644
index 0000000000000000000000000000000000000000..07c050f2ecf205973623a1d4d694126507bb57d4
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['excluding_tax__multi_item_row'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_ROW_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 8.25,
+            SetupUtil::TAX_STORE_RATE => 8.25,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10.00,
+                'qty' => 1,
+            ],
+            [
+                'sku' => 'simple2',
+                'price' => 11.00,
+                'qty' => 1,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 21,
+            'base_subtotal' => 21,
+            'subtotal_incl_tax' => 22.74,
+            'base_subtotal_incl_tax' => 22.74,
+            'tax_amount' => 1.74,
+            'base_tax_amount' => 1.74,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 22.74,
+            'base_grand_total' => 22.74,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 10,
+                'base_row_total' => 10,
+                'taxable_amount' => 10,
+                'base_taxable_amount' => 10,
+                'tax_percent' => 8.25,
+                'price' => 10,
+                'base_price' => 10,
+                'price_incl_tax' => 10.83,
+                'base_price_incl_tax' => 10.83,
+                'row_total_incl_tax' => 10.83,
+                'base_row_total_incl_tax' => 10.83,
+                'tax_amount' => 0.83,
+                'base_tax_amount' => 0.83,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+            'simple2' => [
+                'row_total' => 11,
+                'base_row_total' => 11,
+                'taxable_amount' => 11,
+                'base_taxable_amount' => 11,
+                'tax_percent' => 8.25,
+                'price' => 11,
+                'base_price' => 11,
+                'price_incl_tax' => 11.91,
+                'base_price_incl_tax' => 11.91,
+                'row_total_incl_tax' => 11.91,
+                'base_row_total_incl_tax' => 11.91,
+                'tax_amount' => 0.91,
+                'base_tax_amount' => 0.91,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.php
new file mode 100644
index 0000000000000000000000000000000000000000..cacf6059a5d338b3ccbdfa7b9635a162ebc626fc
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['excluding_tax__multi_item_total'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 8.25,
+            SetupUtil::TAX_STORE_RATE => 8.25,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10.00,
+                'qty' => 1,
+            ],
+            [
+                'sku' => 'simple2',
+                'price' => 11.00,
+                'qty' => 1,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 21,
+            'base_subtotal' => 21,
+            'subtotal_incl_tax' => 22.73,
+            'base_subtotal_incl_tax' => 22.73,
+            'tax_amount' => 1.73,
+            'base_tax_amount' => 1.73,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 22.73,
+            'base_grand_total' => 22.73,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 10,
+                'base_row_total' => 10,
+                'taxable_amount' => 10,
+                'base_taxable_amount' => 10,
+                'tax_percent' => 8.25,
+                'price' => 10,
+                'base_price' => 10,
+                'price_incl_tax' => 10.83,
+                'base_price_incl_tax' => 10.83,
+                'row_total_incl_tax' => 10.83,
+                'base_row_total_incl_tax' => 10.83,
+                'tax_amount' => 0.83,
+                'base_tax_amount' => 0.83,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+            'simple2' => [
+                'row_total' => 11,
+                'base_row_total' => 11,
+                'taxable_amount' => 11,
+                'base_taxable_amount' => 11,
+                'tax_percent' => 8.25,
+                'price' => 11,
+                'base_price' => 11,
+                'price_incl_tax' => 11.90,
+                'base_price_incl_tax' => 11.90,
+                'row_total_incl_tax' => 11.90,
+                'base_row_total_incl_tax' => 11.90,
+                'tax_amount' => 0.90,
+                'base_tax_amount' => 0.90,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f0a90aed5c3c77bd3c45051d362135130e1168e
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['excluding_tax__multi_item_unit'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 0,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_UNIT_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 8.25,
+            SetupUtil::TAX_STORE_RATE => 8.25,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10.00,
+                'qty' => 1,
+            ],
+            [
+                'sku' => 'simple2',
+                'price' => 11.00,
+                'qty' => 1,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 21,
+            'base_subtotal' => 21,
+            'subtotal_incl_tax' => 22.74,
+            'base_subtotal_incl_tax' => 22.74,
+            'tax_amount' => 1.74,
+            'base_tax_amount' => 1.74,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 22.74,
+            'base_grand_total' => 22.74,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 10,
+                'base_row_total' => 10,
+                'taxable_amount' => 10,
+                'base_taxable_amount' => 10,
+                'tax_percent' => 8.25,
+                'price' => 10,
+                'base_price' => 10,
+                'price_incl_tax' => 10.83,
+                'base_price_incl_tax' => 10.83,
+                'row_total_incl_tax' => 10.83,
+                'base_row_total_incl_tax' => 10.83,
+                'tax_amount' => 0.83,
+                'base_tax_amount' => 0.83,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+            'simple2' => [
+                'row_total' => 11,
+                'base_row_total' => 11,
+                'taxable_amount' => 11,
+                'base_taxable_amount' => 11,
+                'tax_percent' => 8.25,
+                'price' => 11,
+                'base_price' => 11,
+                'price_incl_tax' => 11.91,
+                'base_price_incl_tax' => 11.91,
+                'row_total_incl_tax' => 11.91,
+                'base_row_total_incl_tax' => 11.91,
+                'tax_amount' => 0.91,
+                'base_tax_amount' => 0.91,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ab70e7f36b245542fbb336ed0ba56249158c36c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['excluding_tax_row'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_ROW_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 8.25,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10,
+                'qty' => 2,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 20,
+            'base_subtotal' => 20,
+            'subtotal_incl_tax' => 21.65,
+            'base_subtotal_incl_tax' => 21.65,
+            'tax_amount' => 1.65,
+            'base_tax_amount' => 1.65,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 21.65,
+            'base_grand_total' => 21.65,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 20,
+                'base_row_total' => 20,
+                'taxable_amount' => 20,
+                'base_taxable_amount' => 20,
+                'tax_percent' => 8.25,
+                'price' => 10,
+                'base_price' => 10,
+                'price_incl_tax' => 10.83,
+                'base_price_incl_tax' => 10.83,
+                'row_total_incl_tax' => 21.65,
+                'base_row_total_incl_tax' => 21.65,
+                'tax_amount' => 1.65,
+                'base_tax_amount' => 1.65,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.php
new file mode 100644
index 0000000000000000000000000000000000000000..73befba2bdc84ef2fc65237bd5d4f17961e4d3da
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['excluding_tax_total'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 8.25,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10,
+                'qty' => 2,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 20,
+            'base_subtotal' => 20,
+            'subtotal_incl_tax' => 21.65,
+            'base_subtotal_incl_tax' => 21.65,
+            'tax_amount' => 1.65,
+            'base_tax_amount' => 1.65,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 21.65,
+            'base_grand_total' => 21.65,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 20,
+                'base_row_total' => 20,
+                'taxable_amount' => 20,
+                'base_taxable_amount' => 20,
+                'tax_percent' => 8.25,
+                'price' => 10,
+                'base_price' => 10,
+                'price_incl_tax' => 10.83,
+                'base_price_incl_tax' => 10.83,
+                'row_total_incl_tax' => 21.65,
+                'base_row_total_incl_tax' => 21.65,
+                'tax_amount' => 1.65,
+                'base_tax_amount' => 1.65,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e64a8a5b5c53a1f1747d4c604df983605504f2b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['excluding_tax_unit'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_UNIT_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 8.25,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10,
+                'qty' => 2,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 20,
+            'base_subtotal' => 20,
+            'subtotal_incl_tax' => 21.66,
+            'base_subtotal_incl_tax' => 21.66,
+            'tax_amount' => 1.66,
+            'base_tax_amount' => 1.66,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 21.66,
+            'base_grand_total' => 21.66,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 20,
+                'base_row_total' => 20,
+                'taxable_amount' => 10,
+                'base_taxable_amount' => 10,
+                'tax_percent' => 8.25,
+                'price' => 10,
+                'base_price' => 10,
+                'price_incl_tax' => 10.83,
+                'base_price_incl_tax' => 10.83,
+                'row_total_incl_tax' => 21.66,
+                'base_row_total_incl_tax' => 21.66,
+                'tax_amount' => 1.66,
+                'base_tax_amount' => 1.66,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.php
new file mode 100644
index 0000000000000000000000000000000000000000..65e4c3691257c4aa4ae0e8299ef953aa561c7f05
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['including_tax_row'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 1,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_ROW_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 20,
+            SetupUtil::TAX_STORE_RATE => 20,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 9.99,
+                'qty' => 2,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 16.65,
+            'base_subtotal' => 16.65,
+            'subtotal_incl_tax' => 19.98,
+            'base_subtotal_incl_tax' => 19.98,
+            'tax_amount' => 3.33,
+            'base_tax_amount' => 3.33,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 19.98,
+            'base_grand_total' => 19.98,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 16.65,
+                'base_row_total' => 16.65,
+                'taxable_amount' => 19.98,
+                'base_taxable_amount' => 19.98,
+                'tax_percent' => 20,
+                'price' => 8.33,
+                'base_price' => 8.33,
+                'price_incl_tax' => 9.99,
+                'base_price_incl_tax' => 9.99,
+                'row_total_incl_tax' => 19.98,
+                'base_row_total_incl_tax' => 19.98,
+                'tax_amount' => 3.33,
+                'base_tax_amount' => 3.33,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.php
new file mode 100644
index 0000000000000000000000000000000000000000..c737425c6563c54223dfe621535d5fd56624c256
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['including_tax_total'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 1,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 20,
+            SetupUtil::TAX_STORE_RATE => 20,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 9.99,
+                'qty' => 2,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 16.65,
+            'base_subtotal' => 16.65,
+            'subtotal_incl_tax' => 19.98,
+            'base_subtotal_incl_tax' => 19.98,
+            'tax_amount' => 3.33,
+            'base_tax_amount' => 3.33,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 19.98,
+            'base_grand_total' => 19.98,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 16.65,
+                'base_row_total' => 16.65,
+                'taxable_amount' => 19.98,
+                'base_taxable_amount' => 19.98,
+                'tax_percent' => 20,
+                'price' => 8.33,
+                'base_price' => 8.33,
+                'price_incl_tax' => 9.99,
+                'base_price_incl_tax' => 9.99,
+                'row_total_incl_tax' => 19.98,
+                'base_row_total_incl_tax' => 19.98,
+                'tax_amount' => 3.33,
+                'base_tax_amount' => 3.33,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.php
new file mode 100644
index 0000000000000000000000000000000000000000..18ec0c995ad3a7658914ac3c16e21111aeb018f5
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.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.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+$taxCalculationData['including_tax_unit'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX => 1,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_UNIT_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 20,
+            SetupUtil::TAX_STORE_RATE => 20,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 9.99,
+                'qty' => 2,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 16.64,
+            'base_subtotal' => 16.64,
+            'subtotal_incl_tax' => 19.98,
+            'base_subtotal_incl_tax' => 19.98,
+            'tax_amount' => 3.34,
+            'base_tax_amount' => 3.34,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 19.98,
+            'base_grand_total' => 19.98,
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 16.64,
+                'base_row_total' => 16.64,
+                'taxable_amount' => 9.99,
+                'base_taxable_amount' => 9.99,
+                'tax_percent' => 20,
+                'price' => 8.32,
+                'base_price' => 8.32,
+                'price_incl_tax' => 9.99,
+                'base_price_incl_tax' => 9.99,
+                'row_total_incl_tax' => 19.98,
+                'base_row_total_incl_tax' => 19.98,
+                'tax_amount' => 3.34,
+                'base_tax_amount' => 3.34,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php b/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php
new file mode 100644
index 0000000000000000000000000000000000000000..13097905b486d7e6b0a051628506ec3939b0bde3
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Global array that holds test scenarios data
+ *
+ * @var array
+ */
+$taxCalculationData = [];
+
+require_once __DIR__ . '/scenarios/excluding_tax_apply_tax_after_discount.php';
+require_once __DIR__ . '/scenarios/excluding_tax_apply_tax_before_discount.php';
+require_once __DIR__ . '/scenarios/excluding_tax_unit.php';
+require_once __DIR__ . '/scenarios/excluding_tax_row.php';
+require_once __DIR__ . '/scenarios/excluding_tax_total.php';
+require_once __DIR__ . '/scenarios/including_tax_unit.php';
+require_once __DIR__ . '/scenarios/including_tax_row.php';
+require_once __DIR__ . '/scenarios/including_tax_total.php';
+require_once __DIR__ . '/scenarios/excluding_tax_multi_item_unit.php';
+require_once __DIR__ . '/scenarios/excluding_tax_multi_item_row.php';
+require_once __DIR__ . '/scenarios/excluding_tax_multi_item_total.php';
+
diff --git a/dev/tests/js/testsuite/mage/_demo/test.js b/dev/tests/js/testsuite/mage/_demo/test.js
index 15043dc1e1605bf6a537373c200f2a1a5c9718e7..6db8bddc8d166fcd8e557906669ccf1bd6a5c04e 100644
--- a/dev/tests/js/testsuite/mage/_demo/test.js
+++ b/dev/tests/js/testsuite/mage/_demo/test.js
@@ -20,6 +20,6 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-test( "hello test", function() {
+TestCase( "hello test", function() {
     ok( 1 == "1", "Passed!" );
 });
\ No newline at end of file
diff --git a/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js b/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js
index 883aeafc0cab2f6ec347c7f8c1c42f2cd7704b7a..493c49887131f65fd11924d3ff3f6e1200981c25 100644
--- a/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js
+++ b/dev/tests/js/testsuite/mage/loader/jquery-loader-test.js
@@ -20,7 +20,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
-test('options', function() {
+TestCase('options', function() {
 	expect(3);
 
 	var element = $("#loader").loader({
@@ -39,7 +39,7 @@ test('options', function() {
 
 });
 
-test( 'element init', function() {
+TestCase( 'element init', function() {
 	expect(1);
 
 	//Initialize Loader on element
@@ -57,7 +57,7 @@ test( 'element init', function() {
 
 });
 
-test( 'body init', function() {
+TestCase( 'body init', function() {
 	expect(1);
 
 	//Initialize Loader on Body
@@ -68,7 +68,7 @@ test( 'body init', function() {
 
 });
 
-test( 'show/hide', function() {
+TestCase( 'show/hide', function() {
 	expect(3);
 
 	var element = $('body').loader();
@@ -90,7 +90,7 @@ test( 'show/hide', function() {
 
 });
 
-test( 'destroy', function() {
+TestCase( 'destroy', function() {
 	expect(1);
 
 	var element = $("#loader").loader({
diff --git a/dev/tests/js/testsuite/mage/search/regular-search-test.js b/dev/tests/js/testsuite/mage/search/regular-search-test.js
new file mode 100644
index 0000000000000000000000000000000000000000..451105229fc31e3d09c2db931b10fae9d297a23d
--- /dev/null
+++ b/dev/tests/js/testsuite/mage/search/regular-search-test.js
@@ -0,0 +1,64 @@
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    mage.js
+ * @package     test
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+//Code to be tested for /app/code/Magento/CatalogSearch/view/frontend/form-mini.js (_onSubmit)
+function regularSearch() {
+    if (this.document.getElementById('search').value === this.document.getElementById('search').placeholder || this.document.getElementById('search').value === '') {
+        this.document.getElementById('search').placeholder = 'Please specify at least one search term';
+        this.document.getElementById('search').value = this.document.getElementById('search').placeholder;
+    }
+}
+//The test case
+RegularSearchTest = TestCase("RegularSearchTest");
+RegularSearchTest.prototype.setUp = function() {
+    /*:DOC +=
+     <div id='main'>
+     <form id="search_mini_form" action="" method="get">
+     <div>
+     <label><span>Search</span></label>
+     <div>
+     <input id="search"
+     type="text"
+     name="q"
+     value=""
+     placeholder="Search entire store here..."/>
+     </div>
+     <div>
+     <button id="submit" type="submit"
+     title="Search">
+     <span>Search</span>
+     </button>
+     </div>
+     </form>
+     </div>*/
+};
+RegularSearchTest.prototype.testRegularSearch = function(){
+    //before
+    var inputValue = document.getElementById('search');
+    assertEquals("", inputValue.value);
+    regularSearch();
+    //after
+    inputValue = document.getElementById('search');
+    assertEquals("Please specify at least one search term", inputValue.value);
+};
diff --git a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php
index bf58e69147d1bedaf0e9cd2812e3cc9318c8af32..f0b157d619d6e20e6a22f6601a269087964ec57c 100644
--- a/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php
+++ b/dev/tests/static/testsuite/Magento/Test/Integrity/ClassesTest.php
@@ -348,6 +348,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
                 $newObjectPattern = '/^' .
                     '.*new\s(?<venderClass>\\\\Magento(?:\\\\[a-zA-Z0-9_]+)+)\(.*\)' .
                     '|.*new\s(?<badClass>[A-Z][a-zA-Z0-9]+[a-zA-Z0-9_\\\\]*)\(.*\)\;' .
+                    '|use [A-Z][a-zA-Z0-9_\\\\]+ as (?<aliasClass>[A-Z][a-zA-Z0-9]+)' .
                     '/m';
                 $result1 = array();
                 preg_match_all($newObjectPattern, $contents, $result1);
@@ -356,6 +357,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
                 $staticCallPattern = '/^' .
                     '((?!Magento).)*(?<venderClass>\\\\Magento(?:\\\\[a-zA-Z0-9_]+)+)\:\:.*\;' .
                     '|[^\\\\^a-z^A-Z^0-9^_^:](?<badClass>[A-Z][a-zA-Z0-9_]+)\:\:.*\;' .
+                    '|use [A-Z][a-zA-Z0-9_\\\\]+ as (?<aliasClass>[A-Z][a-zA-Z0-9]+)' .
                     '/m';
                 $result2 = array();
                 preg_match_all($staticCallPattern, $contents, $result2);
@@ -365,6 +367,7 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
                     '[\s]*\*\s\@(?:return|throws)\s(?<venderClass>\\\\Magento(?:\\\\[a-zA-Z0-9_]+)+)' .
                     '|[\s]*\*\s\@return\s(?<badClass>[A-Z][a-zA-Z0-9_\\\\]+)' .
                     '|[\s]*\*\s\@throws\s(?<exception>[A-Z][a-zA-Z0-9_\\\\]+)' .
+                    '|use [A-Z][a-zA-Z0-9_\\\\]+ as (?<aliasClass>[A-Z][a-zA-Z0-9]+)' .
                     '/m';
                 $result3 = array();
                 preg_match_all($annotationPattern, $contents, $result3);
@@ -377,6 +380,10 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
                     array_merge_recursive($result1['badClass'], $result2['badClass'], $result3['badClass'])
                 );
 
+                $aliasClasses = array_unique(
+                    array_merge_recursive($result1['aliasClass'], $result2['aliasClass'], $result3['aliasClass'])
+                );
+
                 $vendorClasses = array_filter($vendorClasses, 'strlen');
                 $vendorClasses = $this->referenceBlacklistFilter($vendorClasses);
                 if (!empty($vendorClasses)) {
@@ -391,6 +398,12 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
                 if (empty($badClasses)) {
                     return;
                 }
+
+                $aliasClasses = array_filter($aliasClasses, 'strlen');
+                if (!empty($aliasClasses)) {
+                    $badClasses = $this->handleAliasClasses($aliasClasses, $badClasses);
+                }
+
                 $badClasses = $this->referenceBlacklistFilter($badClasses);
                 $badClasses = $this->removeSpecialCases($badClasses, $file, $contents, $namespacePath);
                 $this->_assertClassReferences($badClasses, $file);
@@ -399,6 +412,24 @@ class ClassesTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    /**
+     * Remove alias class name references that have been identified as 'bad'.
+     *
+     * @param $aliasClasses
+     * @param $badClasses
+     */
+    protected function handleAliasClasses($aliasClasses, $badClasses)
+    {
+        foreach ($aliasClasses as $aliasClass) {
+            foreach ($badClasses as $badClass) {
+                if (strpos($badClass, $aliasClass) === 0) {
+                    unset($badClasses[array_search($badClass, $badClasses)]);
+                }
+            }
+        }
+        return $badClasses;
+    }
+
     /**
      * This function is to remove legacy code usages according to _files/blacklist/reference.txt
      * @param $classes
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index b90f6b315ac496b25e9c0f4ca902f4074004971d..21f633cb716b44eb464c014346a492408e296080 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -1005,6 +1005,9 @@ return array(
     array('getMigrationInstance', 'Magento\Customer\Model\Resource\Setup', '$this->_migrationFactory->create()'),
     array('turnOnReadCommittedMode', 'Magento\Backup\Model\Resource\Db'),
     array('turnOnSerializableMode', 'Magento\Backup\Model\Resource\Db', 'prepareTransactionIsolationLevel'),
+    array('turnOnMaintenanceMode', 'Magento\Backup\Helper\Data', 'Magento\Framework\App\State::turnOnMaintenanceMode'),
+    array('turnOffMaintenanceMode', 'Magento\Backup\Helper\Data', 'Magento\Framework\App\State::turnOffMaintenanceMode'),
+    array('getMaintenanceFlagFilePath', 'Magento\Backup\Helper\Data',),
     array('_getResourceModel', '\Magento\Webapi\Model\Source\Acl\Role', '$this->_resource'),
     array('_getSession', '\Magento\GiftMessage\Model\Save', '$this->_session'),
     array('run', '\Magento\Framework\AppInterface'),
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/Form/Field/ImageTest.php b/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/Form/Field/ImageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..44ea57719b7953552a8aa0f40a458cc3c14f642d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/Form/Field/ImageTest.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Tests for \Magento\Framework\Data\Form\Element\Image
+ */
+namespace Magento\Backend\Block\System\Config\Form\Field;
+
+class ImageTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_objectManagerMock;
+
+    /**
+     * @var \Magento\Framework\Url|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \Magento\Backend\Block\System\Config\Form\Field\Image
+     */
+    protected $_image;
+
+    protected function setUp()
+    {
+        $factoryMock = $this->getMock('Magento\Framework\Data\Form\Element\Factory', array(), array(), '', false);
+        $collectionFactoryMock = $this->getMock(
+            'Magento\Framework\Data\Form\Element\CollectionFactory',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $escaperMock = $this->getMock('Magento\Framework\Escaper', array(), array(), '', false);
+        $this->urlBuilderMock = $this->getMock('Magento\Framework\Url', array(), array(), '', false);
+        $this->_image = new \Magento\Backend\Block\System\Config\Form\Field\Image(
+            $factoryMock,
+            $collectionFactoryMock,
+            $escaperMock,
+            $this->urlBuilderMock
+        );
+        $formMock = new \Magento\Framework\Object();
+        $formMock->getHtmlIdPrefix('id_prefix');
+        $formMock->getHtmlIdPrefix('id_suffix');
+        $this->_image->setForm($formMock);
+    }
+
+    /**
+     * @covers \Magento\Backend\Block\System\Config\Form\Field\Image::_getUrl
+     */
+    public function testGetElementHtmlWithValue()
+    {
+        $type = 'media';
+        $url = 'http://test.example.com/media/';
+        $this->urlBuilderMock->expects($this->once())->method('getBaseUrl')
+            ->with(['_type' => $type])->will($this->returnValue($url));
+
+
+        $this->_image->setValue('test_value');
+        $this->_image->setFieldConfig(
+            array(
+                'id' => 'placeholder',
+                'type' => 'image',
+                'sortOrder' => '1',
+                'showInDefault' => '1',
+                'showInWebsite' => '1',
+                'showInStore' => '1',
+                'label' => null,
+                'backend_model' => 'Magento\\Backend\\Model\\Config\\Backend\\Image',
+                'upload_dir' => array(
+                    'config' => 'system/filesystem/media',
+                    'scope_info' => '1',
+                    'value' => 'catalog/product/placeholder',
+                ),
+                'base_url' => array(
+                    'type' => $type,
+                    'scope_info' => '1',
+                    'value' => 'catalog/product/placeholder',
+                ),
+                '_elementType' => 'field',
+                'path' => 'catalog/placeholder',
+            ));
+
+        $html = $this->_image->getElementHtml();
+        $this->assertContains('class="input-file"', $html);
+        $this->assertContains('<input', $html);
+        $this->assertContains('type="file"', $html);
+        $this->assertContains('value="test_value"', $html);
+        $this->assertContains(
+            '<a href="' . $url
+                . 'catalog/product/placeholder/test_value" onclick="imagePreview(\'_image\'); return false;"',
+            $html
+        );
+        $this->assertContains('<input type="checkbox"', $html);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php
index 365e8f698934c5caa3b14820a207fdb120dadc0e..a15a786a7db12ac29a822c22c43ac987c2fe1763 100644
--- a/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backup/Helper/DataTest.php
@@ -23,35 +23,111 @@
  */
 namespace Magento\Backup\Helper;
 
+use Magento\Framework\App\Filesystem;
+use Magento\Framework\App\State\MaintenanceMode;
+
 class DataTest extends \PHPUnit_Framework_TestCase
 {
-    public function testInvalidateIndexer()
+    /**
+     * @var \Magento\Backup\Helper\Data
+     */
+    protected $helper;
+
+    /**
+     * @var \Magento\Framework\App\Filesystem | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filesystem;
+
+    /**
+     * @var \Magento\Index\Model\Resource\Process\CollectionFactory | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $processFactory;
+
+    public function setUp()
     {
-        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->filesystem = $this->getMockBuilder('Magento\Framework\App\Filesystem')->disableOriginalConstructor()
+            ->getMock();
+        $this->processFactory = $this->getMockBuilder('Magento\Index\Model\Resource\Process\CollectionFactory')
+            ->setMethods(['create'])->disableOriginalConstructor()->getMock();
 
+        $this->helper = (new \Magento\TestFramework\Helper\ObjectManager($this))
+            ->getObject('Magento\Backup\Helper\Data', [
+                'filesystem' => $this->filesystem,
+                'processFactory' => $this->processFactory
+            ]);
+    }
+
+    public function testInvalidateIndexer()
+    {
         $process = $this->getMockBuilder('Magento\Index\Model\Process')->disableOriginalConstructor()->getMock();
         $process->expects(
             $this->once()
         )->method(
-            'changeStatus'
-        )->with(
-            \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX
-        );
-        $iterator = $this->returnValue(new \ArrayIterator(array($process)));
-
+                'changeStatus'
+            )->with(
+                \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX
+            );
+        $iterator = $this->returnValue(new \ArrayIterator([$process]));
         $collection = $this->getMockBuilder(
             'Magento\Index\Model\Resource\Process\Collection'
         )->disableOriginalConstructor()->getMock();
         $collection->expects($this->at(0))->method('getIterator')->will($iterator);
+        $this->processFactory->expects($this->any())->method('create')->will($this->returnValue($collection));
 
-        $processFactory = $this->getMockBuilder(
-            'Magento\Index\Model\Resource\Process\CollectionFactory'
-        )->setMethods(
-            array('create')
-        )->disableOriginalConstructor()->getMock();
-        $processFactory->expects($this->any())->method('create')->will($this->returnValue($collection));
+        $this->helper->invalidateIndexer();
+    }
+
+    public function testGetBackupIgnorePaths()
+    {
+        $this->filesystem->expects($this->any())->method('getPath')
+            ->will($this->returnValueMap([
+                [MaintenanceMode::FLAG_DIR, MaintenanceMode::FLAG_DIR],
+                [Filesystem::SESSION_DIR, Filesystem::SESSION_DIR],
+                [Filesystem::CACHE_DIR, Filesystem::CACHE_DIR],
+                [Filesystem::LOG_DIR, Filesystem::LOG_DIR],
+                [Filesystem::VAR_DIR, Filesystem::VAR_DIR],
+            ]));
+
+        $this->assertEquals(
+            [
+                '.git',
+                '.svn',
+                'var/maintenance.flag',
+                Filesystem::SESSION_DIR,
+                Filesystem::CACHE_DIR,
+                Filesystem::LOG_DIR,
+                Filesystem::VAR_DIR . '/full_page_cache',
+                Filesystem::VAR_DIR . '/locks',
+                Filesystem::VAR_DIR . '/report',
+            ],
+            $this->helper->getBackupIgnorePaths()
+        );
+    }
 
-        $object = $helper->getObject('Magento\Backup\Helper\Data', array('processFactory' => $processFactory));
-        $object->invalidateIndexer();
+    public function testGetRollbackIgnorePaths()
+    {
+        $this->filesystem->expects($this->any())->method('getPath')
+            ->will($this->returnValueMap([
+                [MaintenanceMode::FLAG_DIR, MaintenanceMode::FLAG_DIR],
+                [Filesystem::SESSION_DIR, Filesystem::SESSION_DIR],
+                [Filesystem::ROOT_DIR, Filesystem::ROOT_DIR],
+                [Filesystem::LOG_DIR, Filesystem::LOG_DIR],
+                [Filesystem::VAR_DIR, Filesystem::VAR_DIR],
+            ]));
+
+        $this->assertEquals(
+            [
+                '.svn',
+                '.git',
+                'var/maintenance.flag',
+                Filesystem::SESSION_DIR,
+                Filesystem::LOG_DIR,
+                Filesystem::VAR_DIR . '/locks',
+                Filesystem::VAR_DIR . '/report',
+                Filesystem::ROOT_DIR . '/errors',
+                Filesystem::ROOT_DIR . '/index.php',
+            ],
+            $this->helper->getRollbackIgnorePaths()
+        );
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/ProgressTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/ProgressTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..07d4674b5b13409bd2f6868fb01c848d81c6a170
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Block/Onepage/ProgressTest.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Checkout\Block\Onepage;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class ProgressTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Selected shipping method
+     */
+    const SHIPPING_METHOD = 'shipping method';
+
+    /**
+     * Price of selected shipping method
+     */
+    const SHIPPING_PRICE = 13.02;
+
+    /**
+     * Price of selected shipping method wrapped with tax helper
+     */
+    const SHIPPING_PRICE_WITH_TAX = 13.03;
+
+    /**
+     * Price of selected shipping method formatted with current store
+     */
+    const SHIPPING_PRICE_FORMATTED = '$13.38';
+
+    /**
+     * @var \Magento\Checkout\Block\Onepage\Progress
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\Checkout\Model\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $checkoutSession;
+
+    /**
+     * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $store;
+
+    /**
+     * @var \Magento\Tax\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $taxHelper;
+
+    /**
+     * @var \Magento\Sales\Model\Quote\Address|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $shippingAddress;
+
+    protected function setUp()
+    {
+        $this->checkoutSession = $this->getMock('Magento\Checkout\Model\Session', [], [], '', false);
+        $this->taxHelper = $this->getMock('Magento\Tax\Helper\Data', [], [], '', false);
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->model = $objectManagerHelper->getObject(
+            'Magento\Checkout\Block\Onepage\Progress',
+            ['resourceSession' => $this->checkoutSession, 'taxData' => $this->taxHelper]
+        );
+        $this->shippingAddress = $this->getMock(
+            'Magento\Sales\Model\Quote\Address',
+            ['getShippingRateByCode', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $this->store = $this->getMock('Magento\Store\Model\Store', [], [], '', false);
+        $quote = $this->getMock('Magento\Sales\Model\Quote', [], [], '', false);
+        $quote->expects($this->any())->method('getShippingAddress')->will($this->returnValue($this->shippingAddress));
+        $quote->expects($this->any())->method('getStore')->will($this->returnValue($this->store));
+        $this->checkoutSession->expects($this->any())->method('getQuote')->will($this->returnValue($quote));
+    }
+
+    /**
+     * @param bool $inclTax
+     */
+    private function _prepareTestGetShippingPrice($inclTax)
+    {
+        $rate = $this->getMock('Magento\Sales\Model\Quote\Address\Rate', ['__wakeup'], [], '', false);
+        $rate->setPrice(self::SHIPPING_PRICE);
+        $this->shippingAddress->setShippingMethod(self::SHIPPING_METHOD);
+        $this->shippingAddress->expects($this->once())
+            ->method('getShippingRateByCode')
+            ->with(self::SHIPPING_METHOD)
+            ->will($this->returnValue($rate));
+        $this->taxHelper->expects($this->once())
+            ->method('getShippingPrice')
+            ->with(self::SHIPPING_PRICE, $inclTax ? $this->isTrue() : $this->isFalse(), $this->shippingAddress)
+            ->will($this->returnValue(self::SHIPPING_PRICE_WITH_TAX));
+        $this->store->expects($this->once())
+            ->method('formatPrice')
+            ->with(self::SHIPPING_PRICE_WITH_TAX)
+            ->will($this->returnValue(self::SHIPPING_PRICE_FORMATTED));
+    }
+
+    public function testGetShippingPriceInclTax()
+    {
+        $this->_prepareTestGetShippingPrice(true);
+        $this->assertEquals(self::SHIPPING_PRICE_FORMATTED, $this->model->getShippingPriceInclTax());
+
+    }
+
+    public function testGetShippingPriceExclTax()
+    {
+        $this->_prepareTestGetShippingPrice(false);
+        $this->assertEquals(self::SHIPPING_PRICE_FORMATTED, $this->model->getShippingPriceExclTax());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/App/StateTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/App/StateTest.php
index 85bda142a8ecee02f998de393b8e56c29a97ded5..93cecc96275016af3d264ffbacb235cb92211462 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/App/StateTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/App/StateTest.php
@@ -23,13 +23,10 @@
  */
 namespace Magento\Core\Model\App;
 
+use Magento\Framework\App\State;
+
 class StateTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * @var \Magento\Framework\App\State
-     */
-    protected $_model;
-
     /**
      * @param string $mode
      * @dataProvider constructorDataProvider
diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Helper/DownloadTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Helper/DownloadTest.php
index 7d91ade57577c30ce408b018bbd7f7cd055a4930..f0a63231c88bf9c9d0a6e82d1b0d430a941d45e6 100644
--- a/dev/tests/unit/testsuite/Magento/Downloadable/Helper/DownloadTest.php
+++ b/dev/tests/unit/testsuite/Magento/Downloadable/Helper/DownloadTest.php
@@ -48,6 +48,8 @@ class DownloadTest extends \PHPUnit_Framework_TestCase
 
     /** @var DownloadableFile|\PHPUnit_Framework_MockObject_MockObject */
     protected $_downloadableFileMock;
+    /** @var  \Magento\Framework\Session\SessionManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $sessionManager;
 
     /** @var bool Result of function_exists() */
     public static $functionExists;
@@ -86,14 +88,15 @@ class DownloadTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->_downloadableFileMock = $this->getMock('Magento\Downloadable\Helper\File', array(), array(), '', false);
-
+        $this->sessionManager = $this->getMockForAbstractClass('Magento\Framework\Session\SessionManagerInterface');
         $this->_helper = new DownloadHelper(
             $this->getMock('Magento\Framework\App\Helper\Context', array(), array(), '', false),
             $this->getMock('Magento\Core\Helper\Data', array(), array(), '', false),
             $this->_downloadableFileMock,
             $this->getMock('Magento\Core\Helper\File\Storage\Database', array(), array(), '', false),
             $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface'),
-            $this->_filesystemMock
+            $this->_filesystemMock,
+            $this->sessionManager
         );
     }
 
@@ -262,4 +265,12 @@ class DownloadTest extends \PHPUnit_Framework_TestCase
 
         $this->_helper->setResource($url, DownloadHelper::LINK_TYPE_URL);
     }
+
+    public function testOutput()
+    {
+        $this->sessionManager
+            ->expects($this->once())->method('writeClose');
+        $this->_setupUrlMocks(self::FILE_SIZE, self::URL, array('disposition' => "inline; filename=test.txt"));
+        $this->_helper->output();
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/State/MaintenanceModeTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/State/MaintenanceModeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b64a61335c43f36acc74eb6cff1ee0d16e396482
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/State/MaintenanceModeTest.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\App\State;
+
+class MaintenanceModeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\State\MaintenanceMode
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\Framework\Filesystem\Directory\Write | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $directoryWrite;
+
+    /**
+     * @var \Magento\Framework\App\Filesystem | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filesystem;
+
+    protected function setUp()
+    {
+        $this->directoryWrite = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false);
+        $this->filesystem = $this->getMock('Magento\Framework\App\Filesystem', [], [], '', false);
+
+        $this->model = (new \Magento\TestFramework\Helper\ObjectManager($this))->getObject(
+            'Magento\Framework\App\State\MaintenanceMode',
+            ['filesystem' => $this->filesystem]
+        );
+    }
+
+    protected function getDirectory()
+    {
+        $this->filesystem->expects($this->once())->method('getDirectoryWrite')->with(MaintenanceMode::FLAG_DIR)
+            ->will($this->returnValue($this->directoryWrite));
+    }
+
+    public function testTurnOnMaintenanceMode()
+    {
+        $this->getDirectory();
+        $this->directoryWrite->expects($this->once())->method('writeFile')
+            ->with(MaintenanceMode::FLAG_FILENAME, 'data')
+            ->will($this->returnValue(123));
+
+        $this->assertTrue($this->model->turnOn('data'));
+    }
+
+    public function testTurnOnMaintenanceModeFailed()
+    {
+        $this->getDirectory();
+        $this->directoryWrite->expects($this->once())->method('writeFile')
+            ->with(MaintenanceMode::FLAG_FILENAME, 'data')
+            ->will($this->throwException(new \Magento\Framework\Filesystem\FilesystemException('failed')));
+
+        $this->assertFalse($this->model->turnOn('data'));
+    }
+
+    public function testTurnOffMaintenanceMode()
+    {
+        $this->getDirectory();
+        $this->directoryWrite->expects($this->once())->method('delete')->with(MaintenanceMode::FLAG_FILENAME);
+
+        $this->assertTrue($this->model->turnOff());
+    }
+
+    public function testTurnOffMaintenanceModeFailed()
+    {
+        $this->getDirectory();
+        $this->directoryWrite->expects($this->once())->method('delete')->with(MaintenanceMode::FLAG_FILENAME)
+            ->will($this->throwException(new \Magento\Framework\Filesystem\FilesystemException('failed')));
+
+        $this->assertFalse($this->model->turnOff());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Math/RandomTest.php b/dev/tests/unit/testsuite/Magento/Framework/Math/RandomTest.php
index 26f9fd3f02128f05d43aaf822da95c184a3f65d0..23d1ce477bdef5c121a779e6d457e06ffc6e5851 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Math/RandomTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Math/RandomTest.php
@@ -28,7 +28,7 @@ namespace Magento\Framework\Math;
 class RandomTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @param int $length
+     * @param int    $length
      * @param string $chars
      *
      * @dataProvider getRandomStringDataProvider
@@ -81,4 +81,30 @@ class RandomTest extends \PHPUnit_Framework_TestCase
             $this->fail(sprintf('Unexpected char "%s" found', $matches[0]));
         }
     }
+
+    /**
+     * @param $min
+     * @param $max
+     *
+     * @dataProvider testGetRandomNumberProvider
+     */
+    public function testGetRandomNumber($min, $max)
+    {
+        $number = \Magento\Framework\Math\Random::getRandomNumber($min, $max);
+        $this->assertLessThanOrEqual($max, $number);
+        $this->assertGreaterThanOrEqual($min, $number);
+    }
+
+    public function testGetRandomNumberProvider()
+    {
+        return [
+            [0, 100],
+            [0, 1],
+            [0, 0],
+            [-1, 0],
+            [-100, 0],
+            [-1, 1],
+            [-100, 100]
+        ];
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/CalendarTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/CalendarTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1f1fc04c882eaf71316535f0130e1fb9a641fcdb
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/Element/Html/CalendarTest.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\Element\Html;
+
+class CalendarTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Framework\View\Element\Html\Calendar */
+    protected $block;
+
+    /** @var \Magento\Framework\View\Element\Template\Context */
+    protected $context;
+
+    /** @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $localeDate;
+
+    protected function setUp()
+    {
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->localeDate = $this->getMockBuilder('Magento\Framework\Stdlib\DateTime\TimezoneInterface')
+            ->getMock();
+
+        /** @var  \Magento\Framework\View\Element\Template\Context $context */
+        $this->context = $this->objectManagerHelper->getObject(
+            'Magento\Framework\View\Element\Template\Context',
+            array(
+                'localeDate' => $this->localeDate,
+            )
+        );
+
+        /** @var \Magento\Framework\View\Element\Html\Links $block */
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\Framework\View\Element\Html\Calendar',
+            array('context' => $this->context)
+        );
+    }
+
+    /**
+     * @test
+     */
+    public function testGetYearRange()
+    {
+        $testCurrentYear = 2123;
+        $date = $this->getMockBuilder('Magento\Framework\Stdlib\DateTime\DateInterface')
+            ->getMock();
+
+        $date->expects($this->any())
+            ->method('__toString')
+            ->will($this->returnValue($testCurrentYear));
+
+        $this->localeDate->expects($this->any())
+            ->method('date')
+            ->with($this->equalTo('Y'))
+            ->will($this->returnValue($date));
+
+        $this->assertEquals((int)$testCurrentYear - 100 . ':' . $testCurrentYear, $this->block->getYearRange());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Ogone/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Ogone/Model/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d4ae5ff18b5b052e42cb8464b55f087f8d21c556
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Ogone/Model/ConfigTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Model;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    const EXPECTED_VALUE = 'abcdef1234567890';
+
+    /**
+     * @var Config
+     */
+    protected $_model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_scopeConfig;
+
+    protected function setUp()
+    {
+        $this->_scopeConfig = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface', [], [], '', false);
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_model = $helper->getObject('Magento\Ogone\Model\Config', [
+                'scopeConfig' => $this->_scopeConfig
+            ]);
+    }
+
+    public function testGetShaInCode()
+    {
+        $this->_scopeConfig->expects($this->any())->method('getValue')->with('payment/ogone/secret_key_in')->will(
+            $this->returnValue(self::EXPECTED_VALUE)
+        );
+        $this->assertEquals(self::EXPECTED_VALUE, $this->_model->getShaInCode());
+    }
+
+    public function testGetShaOutCode()
+    {
+        $this->_scopeConfig->expects($this->any())->method('getValue')->with('payment/ogone/secret_key_out')->will(
+            $this->returnValue(self::EXPECTED_VALUE)
+        );
+        $this->assertEquals(self::EXPECTED_VALUE, $this->_model->getShaOutCode());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php
index efe3186c900399af98ea352ce2f63100399c57c1..84b1dbe72ebd1d195e88f80fc363486ec4770290 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Block/Adminhtml/Order/Totals/TaxTest.php
@@ -30,123 +30,85 @@ namespace Magento\Sales\Block\Adminhtml\Order\Totals;
 class TaxTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Sales\Block\Adminhtml\Order\Totals\Tax
+     * Test method for getFullTaxInfo
+     *
+     * @param \Magento\Sales\Model\Order $source
+     * @param array $getCalculatedTax
+     * @param array $getShippingTax
+     * @param array $expectedResult
+     *
+     * @dataProvider getFullTaxInfoDataProvider
      */
-    protected $_block;
+    public function testGetFullTaxInfo($source, $getCalculatedTax, $getShippingTax, $expectedResult)
+    {
+        $taxHelperMock = $this->getMockBuilder('Magento\Tax\Helper\Data')
+            ->setMethods(array('getCalculatedTaxes', 'getShippingTax'))
+            ->disableOriginalConstructor()
+            ->getMock();
+        $taxHelperMock->expects($this->any())
+            ->method('getCalculatedTaxes')
+            ->will($this->returnValue($getCalculatedTax));
+        $taxHelperMock->expects($this->any())
+            ->method('getShippingTax')
+            ->will($this->returnValue($getShippingTax));
 
-    /**
-     * @var \Magento\Framework\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $_objectManager;
+        $mockObject = $this->getMockBuilder('Magento\Sales\Block\Adminhtml\Order\Totals\Tax')
+            ->setConstructorArgs($this->_getConstructArguments($taxHelperMock))
+            ->setMethods(array('getOrder'))
+            ->getMock();
+        $mockObject->expects($this->once())
+            ->method('getOrder')
+            ->will($this->returnValue($source));
 
-    /**
-     * Instantiate \Magento\Sales\Block\Adminhtml\Order\Totals\Tax block
-     */
-    protected function setUp()
-    {
-        $this->_block = $this->getMockBuilder(
-            'Magento\Sales\Block\Adminhtml\Order\Totals\Tax'
-        )->setConstructorArgs(
-            $this->_getModelArgument()
-        )->setMethods(
-            array('getOrder')
-        )->getMock();
+        $actualResult = $mockObject->getFullTaxInfo();
+        $this->assertEquals($expectedResult, $actualResult);
     }
 
     /**
-     * Module arguments for \Magento\Sales\Block\Adminhtml\Order\Totals\Tax
+     * Provide the tax helper mock as a constructor argument
      *
+     * @param $taxHelperMock
      * @return array
      */
-    protected function _getModelArgument()
+    protected function _getConstructArguments($taxHelperMock)
     {
         $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $attributeFactory = $this->getMock(
-            'Magento\Eav\Model\Entity\AttributeFactory',
-            array('create'),
-            array(),
-            '',
-            false
-        );
-        $taxItemFactory = $this->getMock(
-            'Magento\Tax\Model\Resource\Sales\Order\Tax\ItemFactory',
-            array('create'),
-            array(),
-            '',
-            false
-        );
-        $taxHelperMock = $objectManagerHelper->getObject(
-            'Magento\Tax\Helper\Data',
-            array('attributeFactory' => $attributeFactory, 'taxItemFactory' => $taxItemFactory)
-        );
-
-        $taxOrderFactory = $this->getMock(
-            'Magento\Tax\Model\Sales\Order\TaxFactory',
-            array('create'),
-            array(),
-            '',
-            false
-        );
-
         return $objectManagerHelper->getConstructArguments(
             'Magento\Sales\Block\Adminhtml\Order\Totals\Tax',
-            array('taxHelper' => $taxHelperMock, 'taxOrderFactory' => $taxOrderFactory)
+            array('taxHelper' => $taxHelperMock)
         );
     }
 
     /**
-     * @return \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected function _getSalesOrderMock()
-    {
-        $orderMock = $this->getMockBuilder(
-            'Magento\Sales\Model\Order'
-        )->setMethods(
-            array('getItemsCollection', '__wakeup')
-        )->disableOriginalConstructor()->getMock();
-        $orderMock->expects($this->any())->method('getItemsCollection')->will($this->returnValue(array()));
-        return $orderMock;
-    }
-
-    /**
-     * Test MAGETWO-1653: Incorrect tax summary for partial credit memos/invoices
-     *
-     * @dataProvider getSampleData
-     */
-    public function testAddAttributesToForm($actual, $expected)
-    {
-        $orderMock = $this->_getSalesOrderMock();
-        $orderMock->setData($actual);
-        $this->_block->expects($this->any())->method('getOrder')->will($this->returnValue($orderMock));
-        $fullTaxInfo = $this->_block->getFullTaxInfo();
-        $this->assertEquals(reset($fullTaxInfo), $expected);
-        $this->assertTrue(true);
-    }
-
-    /**
-     * Data provider with sample data for tax order
+     * Data provider.
+     * 1st Case : $source is not an instance of \Magento\Sales\Model\Order
+     * 2nd Case : getCalculatedTaxes and getShippingTax return value
      *
      * @return array
      */
-    public function getSampleData()
+    public function getFullTaxInfoDataProvider()
     {
+        $notAnInstanceOfASalesModelOrder = $this->getMock('stdClass');
+
+        $salesModelOrderMock = $this->getMockBuilder('Magento\Sales\Model\Order')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $getCalculatedTax = array(
+            'tax' => 'tax',
+            'shipping_tax' => 'shipping_tax'
+        );
+        $getShippingTax = array(
+            'shipping_tax' => 'shipping_tax',
+            'shipping_and_handing' => 'shipping_and_handing'
+        );
+
         return array(
-            array(
-                'actual' => array(
-                    'calculated_taxes' => array(),
-                    'shipping_tax' => array(),
-                    'shipping_tax_amount' => 1.25,
-                    'base_shipping_tax_amount' => 3.25,
-                    'tax_amount' => 0.16,
-                    'base_tax_amount' => 2
-                ),
-                'expected' => array(
-                    'tax_amount' => 1.25,
-                    'base_tax_amount' => 3.25,
-                    'title' => 'Shipping & Handling Tax',
-                    'percent' => null
-                )
-            )
+            'source is not an instance of \Magento\Sales\Model\Order' =>
+                array($notAnInstanceOfASalesModelOrder, $getCalculatedTax, $getShippingTax, array()),
+            'source is an instance of \Magento\Sales\Model\Order and has reasonable data' =>
+                array($salesModelOrderMock, $getCalculatedTax, $getShippingTax, array('tax' => 'tax',
+                'shipping_tax' => 'shipping_tax', 'shipping_and_handing' => 'shipping_and_handing'))
         );
     }
 }
diff --git a/dev/tools/Magento/Tools/Di/entity_generator.php b/dev/tools/Magento/Tools/Di/entity_generator.php
index 1739a98d104108947bb2ddc088fb942a706ad40a..0729797407b03125aeef083336d156652ac9bfe7 100644
--- a/dev/tools/Magento/Tools/Di/entity_generator.php
+++ b/dev/tools/Magento/Tools/Di/entity_generator.php
@@ -22,41 +22,49 @@
  * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+use Magento\Framework\Code\Generator;
+use Magento\Framework\Code\Generator\Io;
+use Magento\Framework\Filesystem\Driver\File;
+use Magento\Framework\ObjectManager\Code\Generator\Factory;
+use Magento\Framework\ObjectManager\Code\Generator\Proxy;
+use Magento\Framework\Interception\Code\Generator\Interceptor;
+use Magento\Framework\Exception;
+
 require __DIR__ . '/../../../../../app/bootstrap.php';
 
 // default generation dir
-$generationDir = BP . '/' . \Magento\Framework\Code\Generator\Io::DEFAULT_DIRECTORY;
+$generationDir = BP . '/' . Io::DEFAULT_DIRECTORY;
 
 try {
-    $opt = new Zend_Console_Getopt(
-        array(
+    $opt = new \Zend_Console_Getopt(
+        [
             'type|t=w' => 'entity type(required)',
-            'class|c=w' => 'entity class name(required)',
+            'class|c=s' => 'entity class name(required)',
             'generation|g=s' => 'generation dir. Default value ' . $generationDir
-        )
+        ]
     );
     $opt->parse();
 
     $entityType = $opt->getOption('t');
     if (empty($entityType)) {
-        throw new Zend_Console_Getopt_Exception('type is a required parameter');
+        throw new \Zend_Console_Getopt_Exception('type is a required parameter');
     }
 
     $className = $opt->getOption('c');
     if (empty($className)) {
-        throw new Zend_Console_Getopt_Exception('class is a required parameter');
+        throw new \Zend_Console_Getopt_Exception('class is a required parameter');
     }
-    $substitutions = array('proxy' => '_Proxy', 'factory' => 'Factory', 'interceptor' => '_Interceptor');
+    $substitutions = ['proxy' => '_Proxy', 'factory' => 'Factory', 'interceptor' => '_Interceptor'];
     if (!in_array($entityType, array_keys($substitutions))) {
-        throw new Zend_Console_Getopt_Exception('unrecognized type: ' . $entityType);
+        throw new \Zend_Console_Getopt_Exception('unrecognized type: ' . $entityType);
     }
     $className .= $substitutions[$entityType];
 
     if ($opt->getOption('g')) {
         $generationDir = $opt->getOption('g');
     }
-} catch (Zend_Console_Getopt_Exception $e) {
-    $generator = new \Magento\Framework\Code\Generator();
+} catch (\Zend_Console_Getopt_Exception $e) {
+    $generator = new Generator();
     $entities = $generator->getGeneratedEntities();
 
     $allowedTypes = 'Allowed entity types are: ' . implode(', ', $entities) . '.';
@@ -74,15 +82,26 @@ try {
 (new \Magento\Framework\Autoload\IncludePath())->addIncludePath($generationDir);
 
 //reinit generator with correct generation path
-$io = new \Magento\Framework\Code\Generator\Io(new \Magento\Framework\Filesystem\Driver\File(), null, $generationDir);
-$generator = new \Magento\Framework\Code\Generator(null, null, $io);
+$io = new Io(new File(), null, $generationDir);
+$generator = new Generator(
+    null,
+    $io,
+    [
+        Proxy::ENTITY_TYPE =>
+            'Magento\Framework\ObjectManager\Code\Generator\Proxy',
+        Factory::ENTITY_TYPE =>
+            'Magento\Framework\ObjectManager\Code\Generator\Factory',
+        Interceptor::ENTITY_TYPE =>
+            'Magento\Framework\Interception\Code\Generator\Interceptor'
+    ]
+);
 
 try {
-    if (\Magento\Framework\Code\Generator::GENERATION_SUCCESS == $generator->generateClass($className)) {
+    if (Generator::GENERATION_SUCCESS == $generator->generateClass($className)) {
         print "Class {$className} was successfully generated.\n";
     } else {
         print "Can't generate class {$className}. This class either not generated entity, or it already exists.\n";
     }
-} catch (\Magento\Framework\Exception $e) {
+} catch (Exception $e) {
     print "Error! {$e->getMessage()}\n";
 }
diff --git a/downloader/app/Magento/Downloader/Controller.php b/downloader/app/Magento/Downloader/Controller.php
index 02144621d07ca41be77935c3156ca2befb900a7a..7032bcdc51b2ee144c280e33daef6568ea00a8ed 100644
--- a/downloader/app/Magento/Downloader/Controller.php
+++ b/downloader/app/Magento/Downloader/Controller.php
@@ -876,13 +876,14 @@ final class Controller
 
     /**
      * Retrieve Maintenance Flag file path
+     * Path for maintenance flag: web_root/var/maintenance.flag
      *
      * @return string
      */
     protected function _getMaintenanceFilePath()
     {
         if (is_null($this->_maintenanceFile)) {
-            $path = dirname(dirname(__DIR__)) . '/';
+            $path = dirname(dirname(__DIR__)) . '/var/';
             $this->_maintenanceFile = $path . 'maintenance.flag';
         }
         return $this->_maintenanceFile;
@@ -897,7 +898,7 @@ final class Controller
     public function startInstall()
     {
         if ($this->_getMaintenanceFlag()) {
-            $maintenance_filename = 'maintenance.flag';
+            $maintenance_filename = 'var/maintenance.flag';
             $config = $this->config();
             if (!$this->isWritable() || strlen($config->__get('remote_config')) > 0) {
                 $ftpObj = new \Magento\Framework\Connect\Ftp();
@@ -987,7 +988,7 @@ final class Controller
         }
 
         if ($result && $this->_getMaintenanceFlag()) {
-            $maintenance_filename = 'maintenance.flag';
+            $maintenance_filename = 'var/maintenance.flag';
             $config = $this->config();
             if (!$this->isWritable() && strlen($config->__get('remote_config')) > 0) {
                 $ftpObj = new \Magento\Framework\Connect\Ftp();
@@ -1115,7 +1116,7 @@ final class Controller
         return array(
             '.git',
             '.svn',
-            'maintenance.flag',
+            'var/maintenance.flag',
             \Mage::getBaseDir('var') . '/session',
             \Mage::getBaseDir('var') . '/cache',
             \Mage::getBaseDir('var') . '/full_page_cache',
diff --git a/lib/Magento/Framework/App/State/MaintenanceMode.php b/lib/Magento/Framework/App/State/MaintenanceMode.php
new file mode 100644
index 0000000000000000000000000000000000000000..adc1bb357a60cb152dd50256604bab65caca23f9
--- /dev/null
+++ b/lib/Magento/Framework/App/State/MaintenanceMode.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\App\State;
+
+use Magento\Framework\App\Filesystem;
+
+/**
+ * Application Maintenance Mode
+ */
+class MaintenanceMode
+{
+    /**
+     * Maintenance flag name
+     */
+    const FLAG_FILENAME = 'maintenance.flag';
+
+    /**
+     * Maintenance flag dir
+     */
+    const FLAG_DIR = Filesystem::VAR_DIR;
+
+    /**
+     * @var \Magento\Framework\App\Filesystem
+     */
+    protected $filesystem;
+
+    /**
+     * @param \Magento\Framework\App\Filesystem $filesystem
+     */
+    public function __construct(Filesystem $filesystem)
+    {
+        $this->filesystem = $filesystem;
+    }
+
+    /**
+     * Turn on store maintenance mode
+     *
+     * @param string $data
+     * @return bool
+     */
+    public function turnOn($data = 'maintenance')
+    {
+        try {
+            $this->filesystem->getDirectoryWrite(self::FLAG_DIR)
+                ->writeFile(self::FLAG_FILENAME, $data);
+        } catch (\Exception $e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Turn off store maintenance mode
+     *
+     * @return bool
+     */
+    public function turnOff()
+    {
+        try {
+            $this->filesystem->getDirectoryWrite(self::FLAG_DIR)->delete(self::FLAG_FILENAME);
+        } catch (\Exception $e) {
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/lib/Magento/Framework/AppInterface.php b/lib/Magento/Framework/AppInterface.php
index 0f3b4661142754630d326deec1e915aae2a23bdf..bedbc39d1cb6afddc4b593985ed7b0d183e07a62 100644
--- a/lib/Magento/Framework/AppInterface.php
+++ b/lib/Magento/Framework/AppInterface.php
@@ -35,7 +35,7 @@ interface AppInterface
     /**
      * Magento version
      */
-    const VERSION = '2.0.0.0-dev78';
+    const VERSION = '2.0.0.0-dev79';
 
     /**
      * Launch application
diff --git a/lib/Magento/Framework/Math/Random.php b/lib/Magento/Framework/Math/Random.php
index 15db9373707f7adb75d28f8d467a579294b5ed53..ca701b15a3f900ed835a740d14e2b06943c1ec39 100644
--- a/lib/Magento/Framework/Math/Random.php
+++ b/lib/Magento/Framework/Math/Random.php
@@ -42,20 +42,79 @@ class Random
     /**
      * Get random string
      *
-     * @param int $length
+     * @param int         $length
      * @param null|string $chars
      * @return string
      */
     public function getRandomString($length, $chars = null)
     {
-        if (is_null($chars)) {
+        $str = '';
+        if (null === $chars) {
             $chars = self::CHARS_LOWERS . self::CHARS_UPPERS . self::CHARS_DIGITS;
         }
-        mt_srand(10000000 * (double)microtime());
-        for ($i = 0,$string = '',$lc = strlen($chars) - 1; $i < $length; $i++) {
-            $string .= $chars[mt_rand(0, $lc)];
+
+        if (function_exists('openssl_random_pseudo_bytes')) {
+            // use openssl lib if it is installed
+            for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) {
+                $bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE);
+                $hex = bin2hex($bytes); // hex() doubles the length of the string
+                $rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc
+                $str .= $chars[$rand]; // random character in $chars
+            }
+        } elseif ($fp = @fopen('/dev/urandom', 'rb')) {
+            // attempt to use /dev/urandom if it exists but openssl isn't available
+            for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) {
+                $bytes = @fread($fp, PHP_INT_SIZE);
+                $hex = bin2hex($bytes); // hex() doubles the length of the string
+                $rand = abs(hexdec($hex) % $lc); // random integer from 0 to $lc
+                $str .= $chars[$rand]; // random character in $chars
+            }
+            fclose($fp);
+        } else {
+            // fallback to mt_rand() if all else fails
+            mt_srand(10000000 * (double)microtime());
+            for ($i = 0, $lc = strlen($chars) - 1; $i < $length; $i++) {
+                $rand = mt_rand(0, $lc); // random integer from 0 to $lc
+                $str .= $chars[$rand]; // random character in $chars
+            }
+        }
+
+        return $str;
+    }
+
+    /**
+     * Return a random number in the specified range
+     *
+     * @param $min [optional]
+     * @param $max [optional]
+     * @return int A random integer value between min (or 0) and max
+     */
+    public static function getRandomNumber($min = 0, $max = null)
+    {
+        if (null === $max) {
+            $max = mt_getrandmax();
         }
-        return $string;
+        $range = $max - $min + 1;
+        $offset = 0;
+
+        if (function_exists('openssl_random_pseudo_bytes')) {
+            // use openssl lib if it is installed
+            $bytes = openssl_random_pseudo_bytes(PHP_INT_SIZE);
+            $hex = bin2hex($bytes); // hex() doubles the length of the string
+            $offset = abs(hexdec($hex) % $range); // random integer from 0 to $range
+        } elseif ($fp = @fopen('/dev/urandom', 'rb')) {
+            // attempt to use /dev/urandom if it exists but openssl isn't available
+            $bytes = @fread($fp, PHP_INT_SIZE);
+            $hex = bin2hex($bytes); // hex() doubles the length of the string
+            $offset = abs(hexdec($hex) % $range); // random integer from 0 to $range
+            fclose($fp);
+        } else {
+            // fallback to mt_rand() if all else fails
+            mt_srand(mt_rand() + (100000000 * microtime()) % PHP_INT_MAX);
+            return mt_rand($min, $max); // random integer from $min to $max
+        }
+
+        return $min + $offset; // random integer from $min to $max
     }
 
     /**
@@ -66,6 +125,6 @@ class Random
      */
     public function getUniqueHash($prefix = '')
     {
-        return $prefix . md5(uniqid(microtime() . mt_rand(), true));
+        return $prefix . md5(uniqid(microtime() . self::getRandomNumber(), true));
     }
 }
diff --git a/lib/Magento/Framework/Oauth/Helper/Oauth.php b/lib/Magento/Framework/Oauth/Helper/Oauth.php
index ef40a39875fd566ce99a799a44edd813ed384071..acddceabb8a2bd733ea0fb4051df7987ff36e016 100644
--- a/lib/Magento/Framework/Oauth/Helper/Oauth.php
+++ b/lib/Magento/Framework/Oauth/Helper/Oauth.php
@@ -80,22 +80,10 @@ class Oauth
      */
     public function generateRandomString($length)
     {
-        if (function_exists('openssl_random_pseudo_bytes')) {
-            // use openssl lib if it is install. It provides a better randomness.
-            $bytes = openssl_random_pseudo_bytes(ceil($length / 2));
-            // hex() doubles the length of the string
-            $hex = bin2hex($bytes);
-            // truncate at most 1 char if length parameter is an odd number
-            $randomString = substr($hex, 0, $length);
-        } else {
-            // fallback to mt_rand() if openssl is not installed
-            $randomString = $this->_mathRandom->getRandomString(
-                $length,
-                \Magento\Framework\Math\Random::CHARS_DIGITS . \Magento\Framework\Math\Random::CHARS_LOWERS
-            );
-        }
-
-        return $randomString;
+        return $this->_mathRandom->getRandomString(
+            $length,
+            \Magento\Framework\Math\Random::CHARS_DIGITS . \Magento\Framework\Math\Random::CHARS_LOWERS
+        );
     }
 
     /**
diff --git a/lib/Magento/Framework/View/Element/Html/Calendar.php b/lib/Magento/Framework/View/Element/Html/Calendar.php
index 97a6a28b9c64162598e0e456cd6b6e48659df063..03d54d9c9efe5f51b371b7bc2a620c7c90a02568 100644
--- a/lib/Magento/Framework/View/Element/Html/Calendar.php
+++ b/lib/Magento/Framework/View/Element/Html/Calendar.php
@@ -174,4 +174,15 @@ class Calendar extends \Magento\Framework\View\Element\Template
     {
         return $this->_localeDate->scopeTimeStamp($store);
     }
+
+    /**
+     * Getter for yearRange option in datepicker
+     *
+     * @return string
+     */
+    public function getYearRange()
+    {
+        return (int)$this->_localeDate->date('Y')->__toString() - 100
+            . ':' . $this->_localeDate->date('Y')->__toString();
+    }
 }
diff --git a/lib/Magento/Framework/View/Element/Template.php b/lib/Magento/Framework/View/Element/Template.php
index 9b285ab74bed3a7846e4325b9ad2f9cecc3ab680..ed5dfa921d3f2080d584be77ba180f3f92fb173e 100644
--- a/lib/Magento/Framework/View/Element/Template.php
+++ b/lib/Magento/Framework/View/Element/Template.php
@@ -219,7 +219,7 @@ class Template extends AbstractBlock
      */
     public function getArea()
     {
-        return $this->_appState->getAreaCode();
+        return $this->_getData('area') ? $this->_getData('area') : $this->_appState->getAreaCode();
     }
 
     /**
diff --git a/pub/lib/css/source/lib/dropdowns.less b/pub/lib/css/source/lib/dropdowns.less
index 4e52aeeea26a1d626eaaa8e84741e9095844c29c..66e1826036c9409d12a5391f7a6f1d9fd305fe8c 100644
--- a/pub/lib/css/source/lib/dropdowns.less
+++ b/pub/lib/css/source/lib/dropdowns.less
@@ -28,7 +28,9 @@
     @_options-selector : ~"ul.dropdown",
 
     @_dropdown-actions-padding: @dropdown-actions-padding,
-
+    @_dropdown-list-min-width: @dropdown-list-min-width,
+    @_dropdown-list-width: @dropdown-list-width,
+    @_dropdown-list-height: @dropdown-list-height,
     @_dropdown-list-position-top: @dropdown-list-position-top,
     @_dropdown-list-position-bottom: @dropdown-list-position-bottom,
     @_dropdown-list-position-left: @dropdown-list-position-left,
@@ -37,6 +39,9 @@
     @_dropdown-list-border: @dropdown-list-border,
     @_dropdown-list-pointer: @dropdown-list-pointer,
     @_dropdown-list-pointer-border: @dropdown-list-pointer-border,
+    @_dropdown-list-pointer-position: @dropdown-list-pointer-position,
+    @_dropdown-list-pointer-position-top: @dropdown-list-pointer-position-top,
+    @_dropdown-list-pointer-position-left-right: @dropdown-list-pointer-position-left-right,
     @_dropdown-list-item-border: @dropdown-list-item-border,
     @_dropdown-list-item-padding: @dropdown-list-item-padding,
     @_dropdown-list-item-margin: @dropdown-list-item-margin,
@@ -82,13 +87,14 @@
     }
     ._dropdown-styles(
         @_options-selector: @_options-selector,
+        @_dropdown-list-min-width,
+        @_dropdown-list-width,
+        @_dropdown-list-height,
         @_dropdown-list-background,
         @_dropdown-list-border,
         @_dropdown-list-z-index,
         @_dropdown-list-shadow,
-        @_dropdown-list-pointer,
         @_dropdown-list-background,
-        @_dropdown-list-pointer-border,
         @_dropdown-list-item-padding,
         @_dropdown-list-item-margin,
         @_dropdown-list-item-border,
@@ -96,7 +102,12 @@
         @_dropdown-list-position-top,
         @_dropdown-list-position-bottom,
         @_dropdown-list-position-left,
-        @_dropdown-list-position-right
+        @_dropdown-list-position-right,
+        @_dropdown-list-pointer,
+        @_dropdown-list-pointer-border,
+        @_dropdown-list-pointer-position,
+        @_dropdown-list-pointer-position-top,
+        @_dropdown-list-pointer-position-left-right
     );
 }
 
@@ -110,6 +121,9 @@
     @_dropdown-split-button-actions-padding: @dropdown-split-button-actions-padding,
     @_dropdown-split-toggle-actions-padding: @dropdown-split-toggle-actions-padding,
     @_dropdown-split-toggle-position: @dropdown-split-toggle-position,
+    @_dropdown-split-list-min-width: @dropdown-split-list-min-width,
+    @_dropdown-split-list-width: @dropdown-split-list-width,
+    @_dropdown-split-list-height: @dropdown-split-list-height,
     @_dropdown-split-list-position-top: @dropdown-split-list-position-top,
     @_dropdown-split-list-position-bottom: @dropdown-split-list-position-bottom,
     @_dropdown-split-list-position-left: @dropdown-split-list-position-left,
@@ -118,6 +132,9 @@
     @_dropdown-split-list-border: @dropdown-split-list-border,
     @_dropdown-split-list-pointer: @dropdown-split-list-pointer,
     @_dropdown-split-list-pointer-border: @dropdown-split-list-pointer-border,
+    @_dropdown-split-list-pointer-position: @dropdown-split-list-pointer-position,
+    @_dropdown-split-list-pointer-position-top: @dropdown-split-list-pointer-position-top,
+    @_dropdown-split-list-pointer-position-left-right: @dropdown-split-list-pointer-position-left-right,
     @_dropdown-split-list-item-border: @dropdown-split-list-item-border,
     @_dropdown-split-list-item-padding: @dropdown-split-list-item-padding,
     @_dropdown-split-list-item-margin: @dropdown-split-list-item-margin,
@@ -172,13 +189,14 @@
     }
     ._dropdown-styles(
         @_options-selector: @_options-selector,
+        @_dropdown-split-list-min-width,
+        @_dropdown-split-list-width,
+        @_dropdown-split-list-height,
         @_dropdown-split-list-background,
         @_dropdown-split-list-border,
         @_dropdown-split-list-z-index,
         @_dropdown-split-list-shadow,
-        @_dropdown-split-list-pointer,
         @_dropdown-split-list-background,
-        @_dropdown-split-list-pointer-border,
         @_dropdown-split-list-item-padding,
         @_dropdown-split-list-item-margin,
         @_dropdown-split-list-item-border,
@@ -186,29 +204,26 @@
         @_dropdown-split-list-position-top,
         @_dropdown-split-list-position-bottom,
         @_dropdown-split-list-position-left,
-        @_dropdown-split-list-position-right
+        @_dropdown-split-list-position-right,
+        @_dropdown-split-list-pointer,
+        @_dropdown-split-list-pointer-border,
+        @_dropdown-split-list-pointer-position,
+        @_dropdown-split-list-pointer-position-top,
+        @_dropdown-split-list-pointer-position-left-right
     );
-    @{_options-selector} {
-        ._dropdown-split-list-position-default (
-            @_dropdown-split-list-position-top,
-            @_dropdown-split-list-position-bottom,
-            @_dropdown-split-list-position-left,
-            @_dropdown-split-list-position-right,
-            @_dropdown-split-toggle-position
-        );
-    }
 }
 
 // Internal use mixins
 ._dropdown-styles(
     @_options-selector,
+    @_dropdown-list-min-width,
+    @_dropdown-list-width,
+    @_dropdown-list-height,
     @_dropdown-list-background,
     @_dropdown-list-border,
     @_dropdown-list-z-index,
     @_dropdown-list-shadow,
-    @_dropdown-list-pointer,
     @_dropdown-list-background,
-    @_dropdown-list-pointer-border,
     @_dropdown-list-item-padding,
     @_dropdown-list-item-margin,
     @_dropdown-list-item-border,
@@ -216,7 +231,12 @@
     @_dropdown-list-position-top,
     @_dropdown-list-position-bottom,
     @_dropdown-list-position-left,
-    @_dropdown-list-position-right
+    @_dropdown-list-position-right,
+    @_dropdown-list-pointer,
+    @_dropdown-list-pointer-border,
+    @_dropdown-list-pointer-position,
+    @_dropdown-list-pointer-position-top,
+    @_dropdown-list-pointer-position-left-right,
 ) {
     @{_options-selector} {
         .list-reset-styles();
@@ -231,7 +251,9 @@
             @_dropdown-list-position-left,
             @_dropdown-list-position-right
         );
-        min-width: 100%;
+        .css(min-width, @_dropdown-list-min-width);
+        .css(width, @_dropdown-list-width);
+        .css(height, @_dropdown-list-height);
         display: none;
         ._dropdown-list-shadow(@_dropdown-list-shadow);
         li {
@@ -246,9 +268,11 @@
             }
         }
         ._dropdown-list-pointer(
-            @_dropdown-list-pointer,
             @_dropdown-list-background,
-            @_dropdown-list-pointer-border
+            @_dropdown-list-pointer-border,
+            @_dropdown-list-pointer-position,
+            @_dropdown-list-pointer-position-top,
+            @_dropdown-list-pointer-position-left-right,
         );
     }
     &.active {
@@ -296,30 +320,6 @@
     .css(right, @_dropdown-list-position-right);
 }
 
-// Dropdown list position - Default
-._dropdown-split-list-position-default (
-    @_dropdown-list-position-top,
-    @_dropdown-list-position-bottom,
-    @_dropdown-list-position-left,
-    @_dropdown-list-position-right,
-    @_dropdown-split-toggle-position
-) when (@_dropdown-list-position-top = false) and (@_dropdown-list-position-left = false) and (@_dropdown-list-position-right = false) and (@_dropdown-list-position-bottom = false) and (@_dropdown-split-toggle-position = right) {
-    top: 100%;
-    left: 100%;
-    margin-left: -36px;
-}
-
-._dropdown-split-list-position-default (
-    @_dropdown-list-position-top,
-    @_dropdown-list-position-bottom,
-    @_dropdown-list-position-left,
-    @_dropdown-list-position-right,
-    @_dropdown-split-toggle-position
-) when (@_dropdown-list-position-top = false) and (@_dropdown-list-position-left = false) and (@_dropdown-list-position-right = false) and (@_dropdown-list-position-bottom = false) and (@_dropdown-split-toggle-position = left) {
-    top: 100%;
-    left: 0;
-}
-
 // Simple dropdown icon
 ._dropdown-icon(
     @_dropdown-toggle-icon-content,
@@ -494,18 +494,65 @@
 
 // Dropdown show pointer
 ._dropdown-list-pointer(
-    @_dropdown-list-pointer,
     @_dropdown-list-background,
-    @_dropdown-list-pointer-border
+    @_dropdown-list-pointer-border,
+    @_dropdown-list-pointer-position,
+    @_dropdown-list-pointer-position-top,
+    @_dropdown-list-pointer-position-left-right
 ) when (@_dropdown-list-pointer = true) {
     margin-top: 4px;
     ._dropdown-pointer(
+        @_dropdown-list-background,
+        @_dropdown-list-pointer-border,
+        @_dropdown-list-pointer-position,
+        @_dropdown-list-pointer-position-top,
+        @_dropdown-list-pointer-position-left-right
+    );
+}
+
+._dropdown-pointer(
+    @_dropdown-list-background,
+    @_dropdown-list-pointer-border,
+    @_dropdown-list-pointer-position,
+    @_dropdown-list-pointer-position-top,
+    @_dropdown-list-pointer-position-left-right
+) when (@_dropdown-list-pointer-position = left) {
+    ._dropdown-pointer-default(
         @_dropdown-list-background,
         @_dropdown-list-pointer-border
     );
+    &:before {
+        .css(top, @_dropdown-list-pointer-position-top);
+        .css(left, @_dropdown-list-pointer-position-left-right);
+    }
+    &:after {
+        .css(top, @_dropdown-list-pointer-position-top - 2);
+        .css(left, @_dropdown-list-pointer-position-left-right - 1);
+    }
 }
 
 ._dropdown-pointer(
+    @_dropdown-list-background,
+    @_dropdown-list-pointer-border,
+    @_dropdown-list-pointer-position,
+    @_dropdown-list-pointer-position-top,
+    @_dropdown-list-pointer-position-left-right
+) when (@_dropdown-list-pointer-position = right) {
+    ._dropdown-pointer-default(
+        @_dropdown-list-background,
+        @_dropdown-list-pointer-border
+    );
+    &:before {
+        .css(top, @_dropdown-list-pointer-position-top);
+        .css(right, @_dropdown-list-pointer-position-left-right);
+    }
+    &:after {
+        .css(top, @_dropdown-list-pointer-position-top - 2);
+        .css(right, @_dropdown-list-pointer-position-left-right - 1);
+    }
+}
+
+._dropdown-pointer-default(
     @_dropdown-list-background,
     @_dropdown-list-pointer-border
 ) {
@@ -519,15 +566,11 @@
         border-bottom-style: solid;
     }
     &:before {
-        top: -12px;
-        left: 10px;
         z-index: 99;
         border: solid 6px;
         border-color: transparent transparent @_dropdown-list-background transparent;
     }
     &:after {
-        top: -14px;
-        left: 9px;
         z-index: 98;
         border: solid 7px;
         border-color: transparent transparent @_dropdown-list-pointer-border transparent;
diff --git a/pub/lib/css/source/lib/variables.less b/pub/lib/css/source/lib/variables.less
index 1240fe0a81fec65f30a89642fdc8eb090e78b6a4..a4e01f2aff2e1eb1b4ca2df1e5bae00d074f8cd8 100644
--- a/pub/lib/css/source/lib/variables.less
+++ b/pub/lib/css/source/lib/variables.less
@@ -1182,6 +1182,9 @@
 //--------------------------------------
 // Variables simple dropdown
 @dropdown-actions-padding: false;
+@dropdown-list-min-width: 100%; // Also used in: @dropdown-split-list-min-width
+@dropdown-list-width: false; // Also used in: @dropdown-split-list-width
+@dropdown-list-height: false; // Also used in: @dropdown-split-list-height
 @dropdown-list-position-top: false;
 @dropdown-list-position-bottom: false;
 @dropdown-list-position-left: false;
@@ -1190,6 +1193,9 @@
 @dropdown-list-background: #fff;
 @dropdown-list-border: 1px solid #bbb;
 @dropdown-list-pointer-border: #bbb;
+@dropdown-list-pointer-position: left; // right
+@dropdown-list-pointer-position-top: -12px;
+@dropdown-list-pointer-position-left-right: 10px;
 @dropdown-list-item-border: 0;
 @dropdown-list-item-padding: 3px 5px;
 @dropdown-list-item-margin: 0;
@@ -1214,7 +1220,10 @@
 @dropdown-split-actions-padding: 0 5px;
 @dropdown-split-toggle-actions-padding: false;
 @dropdown-split-button-actions-padding: false;
-@dropdown-split-toggle-position: right;
+@dropdown-split-toggle-position: right; // Also used in: @dropdown-split-list-pointer-position
+@dropdown-split-list-min-width: @dropdown-list-min-width;
+@dropdown-split-list-width: @dropdown-list-width;
+@dropdown-split-list-height: @dropdown-list-height;
 @dropdown-split-list-position-top: @dropdown-list-position-top;
 @dropdown-split-list-position-bottom: @dropdown-list-position-bottom;
 @dropdown-split-list-position-left: @dropdown-list-position-left;
@@ -1223,6 +1232,9 @@
 @dropdown-split-list-border: @dropdown-list-border;
 @dropdown-split-list-pointer: @dropdown-list-pointer;
 @dropdown-split-list-pointer-border: @dropdown-list-pointer-border;
+@dropdown-split-list-pointer-position: @dropdown-split-toggle-position;
+@dropdown-split-list-pointer-position-top: @dropdown-list-pointer-position-top;
+@dropdown-split-list-pointer-position-left-right: @dropdown-list-pointer-position-left-right;
 @dropdown-split-list-item-border: @dropdown-list-item-border;
 @dropdown-split-list-item-padding: @dropdown-list-item-padding;
 @dropdown-split-list-item-margin: @dropdown-list-item-margin;