diff --git a/CHANGELOG.md b/CHANGELOG.md
index 24f9cc16de182d879ab702411ed8981cfdf1916e..f81444dc9b1ad197de07401b0d741ad4a65a085a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,70 @@
+2.0.0.0-dev81
+=============
+* Framework improvements:
+  * Covered the following Magento application components with unit tests:
+      * `SalesRule/Model/Observer`
+      * `SalesRule/Helper/*`
+      * `SalesRule/Model/Plugin/*`
+      * `SalesRule/Model/System/Config*`
+      * `Sales/Model/Config.php`
+      * `Sales/Model/Download.php`
+      * `Sales/Model/Quote.php`
+  * Covered the following Magento lib form elements with unit tests:
+      * `lib/Magento/Framework/Flag.php`
+      * `lib/Magento/Framework/Escaper`
+      * `lib/Magento/Framework/Event`
+      * `lib/Magento/Framework/Logger`
+      * `lib/Magento/Framework/Util`
+      * `lib/Magento/Framework/Registry.php`
+      * `lib/Magento/Framework/Backup/Media`
+      * `lib/Magento/Framework/Backup/NoMedia`
+      * `lib/Magento/Framework/Archive`
+      * `lib/Magento/Framework/Translate.php`
+  * Created Service API for Magento_Catalog module:
+      * AttributeSet service
+      * AttributeSetGroup service
+      * ProductLinks service
+      * ProductType service
+* Payments Improvements:
+  * Resolved a performance issue with Merchant Country selector under Payment Methods settings
+  * Removed the PayPal Payments Pro Payflow Edition payment solution
+  * Removed the Saved Credit Card payment method
+* Added the following functional tests:
+  * Delete Admin User
+  * Delete Backend Customer
+  * Delete Product UrlRewrite
+  * Downloadable Product Creation
+  * Update Simple Product
+  * Update Tax Rule
+  * Update Tax Rate
+  * Suggest Searching Result
+* Fixed bugs:
+  * Fixed an issue where the Create Order page title was not correct when scrolling down was performed
+  * Fixed the concurrent test running in MTF
+  * Fixed an issue where product custom options were merged incorrectly
+  * Fixed an issue where customer group discount was not applied for bundle products
+  * Fixed an issue where it was impossible to  create a refund for the PayPal Exprecch Checkout Payflow Edition if captured from the PayPal admin
+  * Fixed an issue where adding customer review caused an error in system.log
+  * Fixed an issue where  the Manage Stock option was automatically reset to No after changing the Stock Availability option
+  * Fixed an issue where the recurring profile attributes where displayed for a product when they were not included in the product attribute set.
+  * Fixed an issue where a fatal error appeared in some cases on attempt to add a product to  cart when FPT was enabled
+  * Fixed an issue where back in stock product alert emails showed HTML markup
+  * Fixed an issue where the Refresh Statistics link on the Sales Report page redirected to the frontend after setting  Add Store Code to Urls to Yes
+  * Fixed an issue where the selected bundle options price was included to the price displayed in the MAP popup
+  * Fixed an issue where the wrong allowed countries list was used in Checkout
+  * Fixed an issue where configurable products with out of stock associated simple products were displayed in layered navigation
+  * Fixed an issue where configurable products lost options  after being duplicated using the Save and Duplicate button
+  * Fixed issues with simple product custom options where it was impossible to import them from a product page and they were not duplicated correctly using the Save and Duplicate button
+  * Fixed an issue where it was impossible to create a customer on the backend in a single store mode
+  * Fixed an issue where reviews created on the backend appeared with the Guest status
+  * Fixed an issue where it was impossible to add an image for a configurable product variation during editing
+* Processed GitHub requests:
+  * [#539] (https://github.com/magento/magento2/issues/539) The "{config.xml,*/config.xml}" pattern cannot be processed
+  * [#564] (https://github.com/magento/magento2/issues/564) Catalog product images - Do not removing from file system
+  * [#256] (https://github.com/magento/magento2/issues/256) Unused file app\code\core\Mage\Backend\view\adminhtml\store\switcher\enhanced.phtml
+  * [#561] (https://github.com/magento/magento2/pull/561) Bugfix Magento\Framework\DB\Adapter\Pdo\Mysql::getForeignKeys()
+  * [#576] (https://github.com/magento/magento2/pull/576) Change Request for InvokerDefault::_callObserverMethod()
+
 2.0.0.0-dev80
 =============
 * Framework improvements:
@@ -104,7 +171,7 @@
   * 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 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
@@ -122,7 +189,7 @@
   * Catalog Price Rule Creation
   * Category Url Rewrite Creation
   * Admin User Role Deletion
-* Update composer.json.dist in order to download and install MTF from Public GitHub (MAGETWO-24698)
+* Update composer.json.dist in order to download and install MTF from Public GitHub
 * 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
diff --git a/app/code/Magento/Backend/Block/System/Config/Form/Fieldset.php b/app/code/Magento/Backend/Block/System/Config/Form/Fieldset.php
index 588687e731b568f283c95b7ee7b6ab0162685af2..df38a6839a450cdf329dd3d75edd0a29dbe10994 100644
--- a/app/code/Magento/Backend/Block/System/Config/Form/Fieldset.php
+++ b/app/code/Magento/Backend/Block/System/Config/Form/Fieldset.php
@@ -92,7 +92,7 @@ class Fieldset extends \Magento\Backend\Block\AbstractBlock implements
         if ($element->getIsNested()) {
             $html = '<tr class="nested"><td colspan="4"><div class="' . $this->_getFrontendClass($element) . '">';
         } else {
-            $html = '<div class="' . $this->_getFrontendClass($element) . ' ">';
+            $html = '<div class="' . $this->_getFrontendClass($element) . '">';
         }
 
         $html .= '<div class="entry-edit-head collapseable">' .
diff --git a/app/code/Magento/Backend/Model/Url.php b/app/code/Magento/Backend/Model/Url.php
index 71e887d201544e3a8da6354e432d24ebb581db18..ca5f3dff77ff2bdd865e10028e0eb974f453e27a 100644
--- a/app/code/Magento/Backend/Model/Url.php
+++ b/app/code/Magento/Backend/Model/Url.php
@@ -93,12 +93,13 @@ class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlIn
      * @param \Magento\Framework\App\Route\ConfigInterface $routeConfig
      * @param \Magento\Framework\App\RequestInterface $request
      * @param \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo
-     * @param \Magento\Backend\Model\Url\ScopeResolver $scopeResolver
+     * @param \Magento\Framework\Url\ScopeResolverInterface $scopeResolver
      * @param \Magento\Framework\Session\Generic $session
      * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
      * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver
      * @param \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param string $scopeType
      * @param \Magento\Backend\Helper\Data $backendHelper
      * @param Menu\Config $menuConfig
      * @param \Magento\Framework\App\CacheInterface $cache
@@ -106,7 +107,6 @@ class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlIn
      * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
      * @param \Magento\Store\Model\StoreFactory $storeFactory
      * @param \Magento\Framework\Data\Form\FormKey $formKey
-     * @param string $scopeType
      * @param array $data
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -115,12 +115,13 @@ class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlIn
         \Magento\Framework\App\Route\ConfigInterface $routeConfig,
         \Magento\Framework\App\RequestInterface $request,
         \Magento\Framework\Url\SecurityInfoInterface $urlSecurityInfo,
-        \Magento\Backend\Model\Url\ScopeResolver $scopeResolver,
+        \Magento\Framework\Url\ScopeResolverInterface $scopeResolver,
         \Magento\Framework\Session\Generic $session,
         \Magento\Framework\Session\SidResolverInterface $sidResolver,
         \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver,
         \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        $scopeType,
         \Magento\Backend\Helper\Data $backendHelper,
         \Magento\Backend\Model\Menu\Config $menuConfig,
         \Magento\Framework\App\CacheInterface $cache,
@@ -128,7 +129,6 @@ class Url extends \Magento\Framework\Url implements \Magento\Backend\Model\UrlIn
         \Magento\Framework\Encryption\EncryptorInterface $encryptor,
         \Magento\Store\Model\StoreFactory $storeFactory,
         \Magento\Framework\Data\Form\FormKey $formKey,
-        $scopeType,
         array $data = array()
     ) {
         $this->_encryptor = $encryptor;
diff --git a/app/code/Magento/Backend/etc/di.xml b/app/code/Magento/Backend/etc/di.xml
index b37ec543458cf6637489c743bbc40cf8417032b8..331df7123659feb25f09bc653c35cc9b487dd920 100644
--- a/app/code/Magento/Backend/etc/di.xml
+++ b/app/code/Magento/Backend/etc/di.xml
@@ -97,6 +97,7 @@
     </type>
     <type name="Magento\Backend\Model\Url">
         <arguments>
+            <argument name="scopeResolver" xsi:type="object">Magento\Backend\Model\Url\ScopeResolver</argument>
             <argument name="authSession" xsi:type="object">Magento\Backend\Model\Auth\Session\Proxy</argument>
             <argument name="formKey" xsi:type="object">Magento\Framework\Data\Form\FormKey\Proxy</argument>
             <argument name="scopeType" xsi:type="const">Magento\Store\Model\ScopeInterface::SCOPE_STORE</argument>
@@ -186,7 +187,7 @@
 
     <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>
diff --git a/app/code/Magento/Backend/etc/events.xml b/app/code/Magento/Backend/etc/events.xml
index 57598dd668cf0cca7fc9a1d2b7af6fcf1c1206cf..2fe0fd68510e59365c971f2f571e8516a6b4d08c 100644
--- a/app/code/Magento/Backend/etc/events.xml
+++ b/app/code/Magento/Backend/etc/events.xml
@@ -24,9 +24,6 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
-    <event name="adminhtml_controller_action_predispatch_start">
-        <observer name="massaction" instance="Magento\Backend\Model\Observer" method="massactionPrepareKey" />
-    </event>
     <event name="admin_user_authenticate_after">
         <observer name="configuration_files_access_level_verification" instance="Magento\Backend\Model\Observer" method="clearCacheConfigurationFilesAccessLevelVerification" />
     </event>
diff --git a/app/code/Magento/Backend/etc/system.xsd b/app/code/Magento/Backend/etc/system.xsd
index 48e99fb830902005a3ecaaa52a04f8fa2e163cf5..3c7db2918d8953d095616c90a886b2e21415c6d9 100644
--- a/app/code/Magento/Backend/etc/system.xsd
+++ b/app/code/Magento/Backend/etc/system.xsd
@@ -106,7 +106,7 @@
 
         <xs:complexType>
             <xs:sequence>
-                <xs:choice minOccurs="2" maxOccurs="unbounded">
+                <xs:choice minOccurs="1" maxOccurs="unbounded">
                     <xs:element name="label" type="xs:string" />
                     <xs:element name="class" type="xs:string" />
                     <xs:element name="tab" type="typeTabId" />
@@ -144,7 +144,6 @@
                     <xs:element name="frontend_model" type="typeModel" />
                     <xs:element name="clone_model" type="typeModel" />
                     <xs:element name="clone_fields" type="xs:int" />
-                    <xs:element name="expanded" type="xs:int" />
                     <xs:element name="help_url" type="typeUrl" />
                     <xs:element name="more_url" type="typeUrl" />
                     <xs:element name="demo_link" type="typeUrl" />
diff --git a/app/code/Magento/Backend/etc/system_file.xsd b/app/code/Magento/Backend/etc/system_file.xsd
index 0479c648b79d1881c4fdab448c868d3014251ec7..e9836a2eda2cb2aa4fff5c00a6e9b60b6d9a57a3 100644
--- a/app/code/Magento/Backend/etc/system_file.xsd
+++ b/app/code/Magento/Backend/etc/system_file.xsd
@@ -145,7 +145,6 @@
                     <xs:element name="frontend_model" type="typeModel" />
                     <xs:element name="clone_model" type="typeModel" />
                     <xs:element name="clone_fields" type="xs:int" />
-                    <xs:element name="expanded" type="xs:int" />
                     <xs:element name="help_url" type="typeUrl" />
                     <xs:element name="more_url" type="typeUrl" />
                     <xs:element name="demo_link" type="typeUrl" />
diff --git a/app/code/Magento/Backend/view/adminhtml/templates/store/switcher/enhanced.phtml b/app/code/Magento/Backend/view/adminhtml/templates/store/switcher/enhanced.phtml
deleted file mode 100644
index 9402a98fd51bef258c749e2dfb90dcfc184c018b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Backend/view/adminhtml/templates/store/switcher/enhanced.phtml
+++ /dev/null
@@ -1,119 +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 $_websiteCollection = $this->getWebsiteCollection() ?>
-<?php if ($_websiteCollection->getSize()): ?>
-<div id="store_switcher_container">
-    <div class="field field-store-switcher">
-        <label for="store_switcher" class="label"><?php echo __('Choose Store View:') ?></label>
-        <div class="control">
-            <select name="store_switcher" id="store_switcher">
-                <option value=""><?php echo $this->getDefaultStoreName() ?></option>
-                <?php foreach ($_websiteCollection as $_website): ?>
-                    <?php $showWebsite=false; ?>
-                    <?php foreach ($this->getGroupCollection($_website) as $_group): ?>
-                        <?php $showGroup=false; ?>
-                        <?php foreach ($this->getStoreCollection($_group) as $_store): ?>
-                            <?php if ($showWebsite == false): ?>
-                                <?php $showWebsite = true; ?>
-                                <optgroup label="<?php echo $_website->getName() ?>"></optgroup>
-                            <?php endif; ?>
-                            <?php if ($showGroup == false): ?>
-                                <?php $showGroup = true; ?>
-                                <optgroup label="&nbsp;&nbsp;&nbsp;<?php echo $_group->getName() ?>">
-                            <?php endif; ?>
-                            <option group="<?php echo $_group->getId() ?>" value="<?php echo $_store->getId() ?>"<?php if($this->getStoreId() == $_store->getId()): ?> selected="selected"<?php endif; ?>>&nbsp;&nbsp;&nbsp;&nbsp;<?php echo $_store->getName() ?></option>
-                        <?php endforeach; ?>
-                        <?php if ($showGroup): ?>
-                            </optgroup>
-                        <?php endif; ?>
-                    <?php endforeach; ?>
-                <?php endforeach; ?>
-            </select>
-        </div>
-        <?php echo $this->getHintHtml() ?>
-    </div>
-</div>
-<script type="text/javascript">
-//<![CDATA[
-var varienStore = new Class.create();
-
-varienStore.prototype = {
-    initialize : function(containerId, storeSwitcher, url, useAjax, useConfirm){
-
-        this.containerId    = containerId;
-        this.storeSwitcher  = storeSwitcher
-        this.url            = url;
-        this.useAjax        = useAjax;
-        this.useConfirm     = useConfirm;
-
-        this.storeSelectorClickCallback = false;
-
-        this.selectorOnChange = this.optionOnChange.bindAsEventListener(this);
-
-        this.storesGroup = {};
-
-        this.initSwitcher();
-    },
-
-    optionOnChange : function (event)
-    {
-        if (this.storeSelectorClickCallback) {
-            try {
-                this.storeSelectorClickCallback(event, this);
-            }
-            catch (e) {}
-        }
-    },
-
-    initSwitcher : function()
-    {
-        if ($(this.storeSwitcher)) {
-            this.options = $$('#'+this.containerId+' option');
-            for (var option=0; option<this.options.length; option++) {
-                if (option%2==0) {
-                    Element.addClassName(this.options[option], 'even');
-                }
-                var id = this.options[option].value*1;
-                this.storesGroup[id] = this.options[option].getAttribute('group');
-            }
-            Event.observe(this.storeSwitcher, 'change', this.selectorOnChange);
-        }
-    },
-
-    getContainerId : function()
-    {
-        return this.containerId;
-    },
-
-    isSameSore: function(checkId, currentId)
-    {
-        return (this.storesGroup[currentId] == this.storesGroup[checkId]);
-    }
-}
-
-var varienStoreSwitcher = new varienStore('store_switcher_container', 'store_switcher', '<?php echo $this->getSwitchUrl() ?>', <?php echo $this->getUseAjax() ?>, <?php echo $this->getUseConfirm() ?>);
-//]]>
-</script>
-<?php endif; ?>
diff --git a/app/code/Magento/Bundle/Pricing/Price/BasePrice.php b/app/code/Magento/Bundle/Pricing/Price/BasePrice.php
deleted file mode 100644
index 28df06a393d01d27f943c6ce0c4936c3a9e7f97b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Bundle/Pricing/Price/BasePrice.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Bundle\Pricing\Price;
-
-use Magento\Catalog\Pricing\Price as CatalogPrice;
-
-/**
- * Bundle Base Price model
- */
-class BasePrice extends CatalogPrice\BasePrice implements BasePriceInterface
-{
-    /**
-     * Get Base Price Value
-     *
-     * @return float|bool
-     */
-    public function getValue()
-    {
-        if ($this->value === null) {
-            $this->value = $this->calculateBaseValue(parent::getValue());
-        }
-        return $this->value;
-    }
-
-    /**
-     * Calculate base price for passed regular one
-     *
-     * @param float $price
-     * @return float
-     */
-    public function calculateBaseValue($price)
-    {
-        $discount = [
-            0,
-            $this->priceInfo->getPrice(CatalogPrice\TierPrice::PRICE_CODE, $this->quantity)->getValue(),
-            $this->priceInfo->getPrice(CatalogPrice\GroupPrice::PRICE_CODE, $this->quantity)->getValue(),
-            $this->priceInfo->getPrice(CatalogPrice\SpecialPrice::PRICE_CODE, $this->quantity)->getValue()
-        ];
-        $discount = max($discount);
-        if ($discount) {
-            $price = $price - $price * ($discount / 100);
-        }
-        return $price;
-    }
-}
diff --git a/app/code/Magento/Bundle/Pricing/Price/BundleOptionPrice.php b/app/code/Magento/Bundle/Pricing/Price/BundleOptionPrice.php
index 5cecd761e8c9a6d18bab8c8eda85aa988c56fe91..871a2cdbd8369be81fb5b026030b7ced5b94ddca 100644
--- a/app/code/Magento/Bundle/Pricing/Price/BundleOptionPrice.php
+++ b/app/code/Magento/Bundle/Pricing/Price/BundleOptionPrice.php
@@ -125,7 +125,8 @@ class BundleOptionPrice extends AbstractPrice implements BundleOptionPriceInterf
      */
     public function getOptionSelectionAmount($selection)
     {
-        $selectionPrice = $this->selectionFactory->create($this->product, $selection, $selection->getSelectionQty());
+        $selectionPrice = $this->selectionFactory
+            ->create($this->product, $selection, $selection->getSelectionQty());
         return $selectionPrice->getAmount();
     }
 
diff --git a/app/code/Magento/Bundle/Pricing/Price/BundleSelectionPrice.php b/app/code/Magento/Bundle/Pricing/Price/BundleSelectionPrice.php
index b7cf63a490f3852d7ded8eb5209cc19e5df50f16..8f773a152263ad1e120aea0a817462a812824e4e 100644
--- a/app/code/Magento/Bundle/Pricing/Price/BundleSelectionPrice.php
+++ b/app/code/Magento/Bundle/Pricing/Price/BundleSelectionPrice.php
@@ -46,11 +46,6 @@ class BundleSelectionPrice extends AbstractPrice
      */
     protected $bundleProduct;
 
-    /**
-     * @var BasePrice
-     */
-    protected $bundleBasePrice;
-
     /**
      * Event manager
      *
@@ -58,25 +53,31 @@ class BundleSelectionPrice extends AbstractPrice
      */
     protected $eventManager;
 
+    /**
+     * @var DiscountCalculator
+     */
+    protected $discountCalculator;
+
     /**
      * @param Product $saleableItem
      * @param float $quantity
      * @param CalculatorInterface $calculator
      * @param SaleableInterface $bundleProduct
      * @param ManagerInterface $eventManager
+     * @param DiscountCalculator $discountCalculator
      */
     public function __construct(
         Product $saleableItem,
         $quantity,
         CalculatorInterface $calculator,
         SaleableInterface $bundleProduct,
-        ManagerInterface $eventManager
+        ManagerInterface $eventManager,
+        DiscountCalculator $discountCalculator
     ) {
         parent::__construct($saleableItem, $quantity, $calculator);
         $this->bundleProduct = $bundleProduct;
-        $this->bundleBasePrice = $this->bundleProduct->getPriceInfo()
-            ->getPrice(CatalogPrice\BasePrice::PRICE_CODE, $this->quantity);
         $this->eventManager = $eventManager;
+        $this->discountCalculator = $discountCalculator;
     }
 
     /**
@@ -92,15 +93,15 @@ class BundleSelectionPrice extends AbstractPrice
 
         if ($this->bundleProduct->getPriceType() == Price::PRICE_TYPE_DYNAMIC) {
             $value = $this->priceInfo
-                ->getPrice(FinalPrice::PRICE_CODE, $this->quantity)
+                ->getPrice(FinalPrice::PRICE_CODE)
                 ->getValue();
         } else {
             if ($this->product->getSelectionPriceType()) {
                 // calculate price for selection type percent
-                $product = clone $this->bundleProduct;
-                $price = $product->getPriceInfo()
-                    ->getPrice(CatalogPrice\RegularPrice::PRICE_CODE, $this->quantity)
+                $price = $this->bundleProduct->getPriceInfo()
+                    ->getPrice(CatalogPrice\RegularPrice::PRICE_CODE)
                     ->getValue();
+                $product = clone $this->bundleProduct;
                 $product->setFinalPrice($price);
                 $this->eventManager->dispatch(
                     'catalog_product_get_final_price',
@@ -112,7 +113,7 @@ class BundleSelectionPrice extends AbstractPrice
                 $value = $this->product->getSelectionPriceValue() * $this->quantity;
             }
         }
-        $this->value = $this->bundleBasePrice->calculateBaseValue($value);
+        $this->value = $this->discountCalculator->calculateDiscount($this->bundleProduct, $value);
         return $this->value;
     }
 }
diff --git a/app/code/Magento/Bundle/Pricing/Price/ConfiguredPrice.php b/app/code/Magento/Bundle/Pricing/Price/ConfiguredPrice.php
index c5ccf76c17a294e3a35f0e78fc085d21005b879b..fee3a136a41e72bfe747dd9bb686afdd68d1348d 100644
--- a/app/code/Magento/Bundle/Pricing/Price/ConfiguredPrice.php
+++ b/app/code/Magento/Bundle/Pricing/Price/ConfiguredPrice.php
@@ -45,6 +45,11 @@ class ConfiguredPrice extends CatalogPrice\FinalPrice implements ConfiguredPrice
      */
     protected $calculator;
 
+    /**
+     * @var DiscountCalculator
+     */
+    protected $discountCalculator;
+
     /**
      * @var null|ItemInterface
      */
@@ -54,12 +59,14 @@ class ConfiguredPrice extends CatalogPrice\FinalPrice implements ConfiguredPrice
      * @param Product $saleableItem
      * @param float $quantity
      * @param BundleCalculatorInterface $calculator
+     * @param DiscountCalculator $discountCalculator
      * @param ItemInterface $item
      */
     public function __construct(
         Product $saleableItem,
         $quantity,
         BundleCalculatorInterface $calculator,
+        DiscountCalculator $discountCalculator,
         ItemInterface $item = null
     ) {
         $this->item = $item;
@@ -136,7 +143,10 @@ class ConfiguredPrice extends CatalogPrice\FinalPrice implements ConfiguredPrice
     {
         if ($this->item) {
             $configuredOptionsAmount = $this->getConfiguredAmount()->getBaseAmount();
-            return parent::getValue() + $this->basePrice->calculateBaseValue($configuredOptionsAmount);
+            return parent::getValue() +
+                $this->priceInfo
+                    ->getPrice(BundleDiscountPrice::PRICE_CODE)
+                    ->calculateDiscount($configuredOptionsAmount);
         } else {
             return parent::getValue();
         }
diff --git a/app/code/Magento/Bundle/Pricing/Price/DiscountCalculator.php b/app/code/Magento/Bundle/Pricing/Price/DiscountCalculator.php
new file mode 100644
index 0000000000000000000000000000000000000000..0578caaf9f782e54ef8d1c2065532b2ce37768da
--- /dev/null
+++ b/app/code/Magento/Bundle/Pricing/Price/DiscountCalculator.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\Bundle\Pricing\Price;
+
+use Magento\Catalog\Model\Product;
+
+/**
+ * Class DiscountCalculator
+ */
+class DiscountCalculator
+{
+    /**
+     * Apply percentage discount
+     *
+     * @param Product $product
+     * @param float|null $value
+     * @return float|null
+     */
+    public function calculateDiscount(Product $product, $value = null)
+    {
+        if (!$value) {
+            $value = $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue();
+        }
+
+        $discount = null;
+        foreach ($product->getPriceInfo()->getPrices() as $price) {
+            if ($price instanceof DiscountProviderInterface && $price->getDiscountPercent()) {
+                $discount = min($price->getDiscountPercent(), $discount ?: $price->getDiscountPercent());
+            }
+        }
+        return (null !== $discount) ?  $discount/100 * $value : $value;
+    }
+}
diff --git a/app/code/Magento/Bundle/Pricing/Price/BasePriceInterface.php b/app/code/Magento/Bundle/Pricing/Price/DiscountProviderInterface.php
similarity index 83%
rename from app/code/Magento/Bundle/Pricing/Price/BasePriceInterface.php
rename to app/code/Magento/Bundle/Pricing/Price/DiscountProviderInterface.php
index 0ba4fa0f70bcced0c1269919b4e82ed0ac8f4f36..9290d970457be8aa9a9fce3a9613241fa0d45f7d 100644
--- a/app/code/Magento/Bundle/Pricing/Price/BasePriceInterface.php
+++ b/app/code/Magento/Bundle/Pricing/Price/DiscountProviderInterface.php
@@ -25,15 +25,12 @@
 namespace Magento\Bundle\Pricing\Price;
 
 /**
- * Bundle base price interface
+ * Interface DiscountProviderInterface
  */
-interface BasePriceInterface
+interface DiscountProviderInterface
 {
     /**
-     * Calculate base price for passed regular one
-     *
-     * @param float $price
      * @return float
      */
-    public function calculateBaseValue($price);
+    public function getDiscountPercent();
 }
diff --git a/app/code/Magento/Bundle/Pricing/Price/FinalPrice.php b/app/code/Magento/Bundle/Pricing/Price/FinalPrice.php
index 9cee50e6073ae7b8c80d5754ad4afe7aac6f90cf..20b476821d730f4af98b3c189bd7247e6b1eac60 100644
--- a/app/code/Magento/Bundle/Pricing/Price/FinalPrice.php
+++ b/app/code/Magento/Bundle/Pricing/Price/FinalPrice.php
@@ -24,8 +24,9 @@
 
 namespace Magento\Bundle\Pricing\Price;
 
+use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
 use Magento\Catalog\Model\Product;
-use Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface;
+use Magento\Catalog\Pricing\Price\BasePrice;
 
 /**
  * Final price model
@@ -33,29 +34,33 @@ use Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface;
 class FinalPrice extends \Magento\Catalog\Pricing\Price\FinalPrice
 {
     /**
-     * Price type final
+     * @param Product $saleableItem
+     * @param float $quantity
+     * @param CalculatorInterface $calculator
      */
-    const PRICE_CODE = 'final_price';
-
-    /**
-     * @var BundleCalculatorInterface
-     */
-    protected $calculator;
-
-    /**
-     * @var BasePrice
-     */
-    protected $basePrice;
+    public function __construct(
+        Product $saleableItem,
+        $quantity,
+        CalculatorInterface $calculator
+    ) {
+        parent::__construct($saleableItem, $quantity, $calculator);
+        $this->basePrice = $this->priceInfo->getPrice(BasePrice::PRICE_CODE);
+    }
 
     /**
+     * Returns price value
+     *
      * @return float
      */
     public function getValue()
     {
-        return parent::getValue() + $this->basePrice->calculateBaseValue($this->getBundleOptionPrice()->getValue());
+        return parent::getValue() +
+            $this->getBundleOptionPrice()->getValue();
     }
 
     /**
+     * Returns max price
+     *
      * @return \Magento\Framework\Pricing\Amount\AmountInterface
      */
     public function getMaximalPrice()
@@ -64,6 +69,8 @@ class FinalPrice extends \Magento\Catalog\Pricing\Price\FinalPrice
     }
 
     /**
+     * Returns min price
+     *
      * @return \Magento\Framework\Pricing\Amount\AmountInterface
      */
     public function getMinimalPrice()
@@ -72,6 +79,8 @@ class FinalPrice extends \Magento\Catalog\Pricing\Price\FinalPrice
     }
 
     /**
+     * Returns price amount
+     *
      * @return \Magento\Framework\Pricing\Amount\AmountInterface
      */
     public function getAmount()
@@ -80,10 +89,12 @@ class FinalPrice extends \Magento\Catalog\Pricing\Price\FinalPrice
     }
 
     /**
+     * Returns option price
+     *
      * @return \Magento\Bundle\Pricing\Price\BundleOptionPrice
      */
     protected function getBundleOptionPrice()
     {
-        return $this->priceInfo->getPrice(BundleOptionPrice::PRICE_CODE, $this->quantity);
+        return $this->priceInfo->getPrice(BundleOptionPrice::PRICE_CODE);
     }
 }
diff --git a/app/code/Magento/Bundle/Pricing/Price/GroupPrice.php b/app/code/Magento/Bundle/Pricing/Price/GroupPrice.php
index 4395eecc3970dcf428a9134443ef765e1efbf70b..03769bb671116a4f22e07533ca84e39684741b99 100644
--- a/app/code/Magento/Bundle/Pricing/Price/GroupPrice.php
+++ b/app/code/Magento/Bundle/Pricing/Price/GroupPrice.php
@@ -24,19 +24,35 @@
 
 namespace Magento\Bundle\Pricing\Price;
 
-use Magento\Customer\Model\Session;
+use Magento\Catalog\Pricing\Price\RegularPrice;
 
 /**
- * Bundle droup price model
+ * Bundle group price model
  */
-class GroupPrice extends \Magento\Catalog\Pricing\Price\GroupPrice
+class GroupPrice extends \Magento\Catalog\Pricing\Price\GroupPrice implements DiscountProviderInterface
 {
     /**
-     * Price type group
+     * @var float|false
      */
-    const PRICE_CODE = 'group_price';
+    protected $percent;
 
     /**
+     * Returns percent discount value
+     *
+     * @return bool|float
+     */
+    public function getDiscountPercent()
+    {
+        if ($this->percent === null) {
+            $percent = parent::getValue();
+            $this->percent = ($percent) ? max(0, min(100, 100 - $percent)) : null;
+        }
+        return $this->percent;
+    }
+
+    /**
+     * Returns pice value
+     *
      * @return float|bool
      */
     public function getValue()
@@ -45,10 +61,10 @@ class GroupPrice extends \Magento\Catalog\Pricing\Price\GroupPrice
             return $this->value;
         }
 
-        $groupPrice = parent::getValue();
+        $groupPrice = $this->getDiscountPercent();
         if ($groupPrice) {
-            $basePrice = $this->getBasePrice();
-            $this->value = $basePrice - $basePrice * ($groupPrice / 100);
+            $regularPrice = $this->getRegularPrice();
+            $this->value = $regularPrice * ($groupPrice / 100);
         } else {
             $this->value = false;
         }
@@ -56,13 +72,12 @@ class GroupPrice extends \Magento\Catalog\Pricing\Price\GroupPrice
     }
 
     /**
-     * @param null|float $qty
+     * Returns regular price
+     *
      * @return bool|float
      */
-    protected function getBasePrice($qty = null)
+    protected function getRegularPrice()
     {
-        return $this->priceInfo
-            ->getPrice(\Magento\Catalog\Pricing\Price\BasePrice::PRICE_CODE)
-            ->getValue();
+        return $this->priceInfo->getPrice(RegularPrice::PRICE_CODE)->getValue();
     }
 }
diff --git a/app/code/Magento/Bundle/Pricing/Price/SpecialPrice.php b/app/code/Magento/Bundle/Pricing/Price/SpecialPrice.php
index a77e9116b499e8078bcbc0fe98af6b99f93ce677..79d70ef4f071195bf89e18f6b68d45d35d43e5f3 100644
--- a/app/code/Magento/Bundle/Pricing/Price/SpecialPrice.php
+++ b/app/code/Magento/Bundle/Pricing/Price/SpecialPrice.php
@@ -24,19 +24,34 @@
 
 namespace Magento\Bundle\Pricing\Price;
 
-use Magento\Catalog\Pricing\Price\BasePrice as CatalogBasePrice;
+use Magento\Catalog\Pricing\Price\RegularPrice;
 
 /**
  * Special price model
  */
-class SpecialPrice extends \Magento\Catalog\Pricing\Price\SpecialPrice
+class SpecialPrice extends \Magento\Catalog\Pricing\Price\SpecialPrice implements DiscountProviderInterface
 {
     /**
-     * Price type special
+     * @var float|false
      */
-    const PRICE_CODE = 'special_price';
+    protected $percent;
 
     /**
+     * Returns discount percent
+     *
+     * @return bool|float
+     */
+    public function getDiscountPercent()
+    {
+        if ($this->percent === null) {
+            $this->percent = parent::getValue();
+        }
+        return $this->percent;
+    }
+
+    /**
+     * Returns price value
+     *
      * @return bool|float
      */
     public function getValue()
@@ -45,10 +60,10 @@ class SpecialPrice extends \Magento\Catalog\Pricing\Price\SpecialPrice
             return $this->value;
         }
 
-        $specialPrice = parent::getValue();
+        $specialPrice = $this->getDiscountPercent();
         if ($specialPrice) {
-            $basePrice = $this->getBasePrice();
-            $this->value = $basePrice - $basePrice * ($specialPrice / 100);
+            $regularPrice = $this->getRegularPrice();
+            $this->value = $regularPrice * ($specialPrice / 100);
         } else {
             $this->value = false;
         }
@@ -56,12 +71,12 @@ class SpecialPrice extends \Magento\Catalog\Pricing\Price\SpecialPrice
     }
 
     /**
+     * Returns regular price
+     *
      * @return bool|float
      */
-    protected function getBasePrice()
+    protected function getRegularPrice()
     {
-        return $this->priceInfo
-            ->getPrice(CatalogBasePrice::PRICE_CODE)
-            ->getValue();
+        return $this->priceInfo->getPrice(RegularPrice::PRICE_CODE)->getValue();
     }
 }
diff --git a/app/code/Magento/Bundle/Pricing/Price/TierPrice.php b/app/code/Magento/Bundle/Pricing/Price/TierPrice.php
index da2b8654b4000caf1b80d5a8cd45ef3601c6cfdb..9797f4fb57686f1452d4eb83936ffd1215162106 100644
--- a/app/code/Magento/Bundle/Pricing/Price/TierPrice.php
+++ b/app/code/Magento/Bundle/Pricing/Price/TierPrice.php
@@ -24,20 +24,67 @@
 
 namespace Magento\Bundle\Pricing\Price;
 
+use Magento\Catalog\Pricing\Price\RegularPrice;
+
 /**
- * Bundle tire prices model
+ * Bundle tier prices model
  */
-class TierPrice extends \Magento\Catalog\Pricing\Price\TierPrice
+class TierPrice extends \Magento\Catalog\Pricing\Price\TierPrice implements DiscountProviderInterface
 {
     /**
-     * Price type tier
+     * @var bool
      */
-    const PRICE_CODE = 'tier_price';
+    protected $filterByBasePrice = false;
 
     /**
-     * @var bool
+     * @var float|false
      */
-    protected $filterByBasePrice = false;
+    protected $percent;
+
+    /**
+     * Returns percent discount
+     *
+     * @return bool|float
+     */
+    public function getDiscountPercent()
+    {
+        if ($this->percent === null) {
+            $percent = parent::getValue();
+            $this->percent = ($percent) ? max(0, min(100, 100 - $percent)) : null;
+        }
+        return $this->percent;
+    }
+
+    /**
+     * Returns pricing value
+     *
+     * @return bool|float
+     */
+    public function getValue()
+    {
+        if ($this->value !== null) {
+            return $this->value;
+        }
+
+        $tierPrice = $this->getDiscountPercent();
+        if ($tierPrice) {
+            $regularPrice = $this->getRegularPrice();
+            $this->value = $regularPrice * ($tierPrice / 100);
+        } else {
+            $this->value = false;
+        }
+        return $this->value;
+    }
+
+    /**
+     * Returns regular price
+     *
+     * @return bool|float
+     */
+    protected function getRegularPrice()
+    {
+        return $this->priceInfo->getPrice(RegularPrice::PRICE_CODE)->getValue();
+    }
 
     /**
      * Returns true if first price is better
diff --git a/app/code/Magento/Bundle/etc/di.xml b/app/code/Magento/Bundle/etc/di.xml
index ecdb2efc911202029fa9f527d29a96e2326fdbe3..9db37f542c83653600408db3a21d3eb4c6b19378 100644
--- a/app/code/Magento/Bundle/etc/di.xml
+++ b/app/code/Magento/Bundle/etc/di.xml
@@ -68,10 +68,10 @@
                 <item name="regular_price" xsi:type="string">Magento\Catalog\Pricing\Price\RegularPrice</item>
                 <item name="final_price" xsi:type="string">Magento\Bundle\Pricing\Price\FinalPrice</item>
                 <item name="tier_price" xsi:type="string">Magento\Bundle\Pricing\Price\TierPrice</item>
-                <item name="group_price" xsi:type="string">Magento\Catalog\Pricing\Price\GroupPrice</item>
-                <item name="special_price" xsi:type="string">Magento\Catalog\Pricing\Price\SpecialPrice</item>
+                <item name="group_price" xsi:type="string">Magento\Bundle\Pricing\Price\GroupPrice</item>
+                <item name="special_price" xsi:type="string">Magento\Bundle\Pricing\Price\SpecialPrice</item>
                 <item name="msrp_price" xsi:type="string">Magento\Catalog\Pricing\Price\MsrpPrice</item>
-                <item name="base_price" xsi:type="string">Magento\Bundle\Pricing\Price\BasePrice</item>
+                <item name="base_price" xsi:type="string">Magento\Catalog\Pricing\Price\BasePrice</item>
                 <item name="configured_price" xsi:type="string">Magento\Bundle\Pricing\Price\ConfiguredPrice</item>
                 <item name="bundle_option" xsi:type="string">Magento\Bundle\Pricing\Price\BundleOptionPrice</item>
             </argument>
diff --git a/app/code/Magento/Bundle/view/frontend/templates/js/components.phtml b/app/code/Magento/Bundle/view/frontend/templates/js/components.phtml
index a5ce58abec93f4b1bf82421523bbe8c063136925..231b8c0bc5d6cf82948e982afbef33f2c22aa4b3 100644
--- a/app/code/Magento/Bundle/view/frontend/templates/js/components.phtml
+++ b/app/code/Magento/Bundle/view/frontend/templates/js/components.phtml
@@ -33,6 +33,7 @@
                     '<?php echo $this->getViewFileUrl('mage/sticky.js') ?>'
                 ],
                 bundleOption: [
+                    '<?php echo $this->getViewFileUrl('Magento_Catalog::js/price-option.js') ?>',
                     '<?php echo $this->getViewFileUrl('Magento_Bundle::bundle.js') ?>'
                 ],
                 slide: [
diff --git a/app/code/Magento/Bundle/view/frontend/web/bundle.js b/app/code/Magento/Bundle/view/frontend/web/bundle.js
index e5b6ae3ccd6291cce94d3f4890bd91e8c2d9cd59..4ac75e5ae6083585dff48cf70122164ed15bb78e 100644
--- a/app/code/Magento/Bundle/view/frontend/web/bundle.js
+++ b/app/code/Magento/Bundle/view/frontend/web/bundle.js
@@ -60,6 +60,9 @@
             }
         },
         _create: function() {
+            this.element.on('reloadPrice', $.proxy(function() {
+                this.reloadPrice();
+            }, this));
             $(this.options.productBundleSelector).each(
                 $.proxy(function(key, value) {
                     var element = $(value),
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Options/Ajax.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Options/Ajax.php
index 3c03cf2539e59aa4bd8e272eca46fcef31e6d415..9b3806ed2a1128c5e96a3face771717b97f245b5 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Options/Ajax.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Options/Ajax.php
@@ -29,6 +29,8 @@
  */
 namespace Magento\Catalog\Block\Adminhtml\Product\Options;
 
+use \Magento\Store\Model\Store;
+
 class Ajax extends \Magento\Backend\Block\AbstractBlock
 {
     /**
@@ -96,7 +98,9 @@ class Ajax extends \Magento\Backend\Block\AbstractBlock
         $products = $this->_coreRegistry->registry('import_option_products');
         if (is_array($products)) {
             foreach ($products as $productId) {
-                $product = $this->_productFactory->create()->load((int)$productId);
+                $product = $this->_productFactory->create();
+                $product->setStoreId($this->getRequest()->getParam('store', Store::DEFAULT_STORE_ID));
+                $product->load((int)$productId);
                 if (!$product->getId()) {
                     continue;
                 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product.php
index ccacef68d5b494ecbf1b515e96361bbcfcc116d4..590abfe64646bba73df782d74dc6f529f3dced73 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product.php
@@ -196,7 +196,11 @@ class Product extends \Magento\Backend\App\Action
         $this->_eventManager->dispatch('catalog_product_new_action', array('product' => $product));
 
         if ($this->getRequest()->getParam('popup')) {
-            $this->_view->loadLayout('popup');
+            $this->_view->loadLayout(array(
+                'popup',
+                strtolower($this->_request->getFullActionName()),
+                'catalog_product_' . $product->getTypeId()
+            ));
         } else {
             $this->_view->loadLayout(
                 array(
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
index ac0cfcd7a40bbe9a5f2e044dc396cb957e41fea5..e16c7a36c3bd545ff43b264389efb381a8cbd835 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php
@@ -41,26 +41,34 @@ class Helper
     protected $stockFilter;
 
     /**
-     * @var Helper\ProductLinks
+     * @var \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks
      */
     protected $productLinks;
 
+    /**
+     * @var \Magento\Backend\Helper\Js
+     */
+    protected $jsHelper;
+
     /**
      * @param \Magento\Framework\App\RequestInterface $request
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param StockDataFilter $stockFilter
-     * @param Helper\ProductLinks $productLinks
+     * @param \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $productLinks
+     * @param \Magento\Backend\Helper\Js $jsHelper
      */
     public function __construct(
         \Magento\Framework\App\RequestInterface $request,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         StockDataFilter $stockFilter,
-        Helper\ProductLinks $productLinks
+        \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $productLinks,
+        \Magento\Backend\Helper\Js $jsHelper
     ) {
         $this->request = $request;
         $this->storeManager = $storeManager;
         $this->stockFilter = $stockFilter;
         $this->productLinks = $productLinks;
+        $this->jsHelper = $jsHelper;
     }
 
     /**
@@ -117,7 +125,15 @@ class Helper
             }
         }
 
-        $product = $this->productLinks->initializeLinks($product);
+        $links = $this->request->getPost('links');
+        $links = is_array($links) ? $links : array();
+        $linkTypes = array('related', 'upsell', 'crosssell');
+        foreach ($linkTypes as $type) {
+            if (isset($links[$type])) {
+                $links[$type] = $this->jsHelper->decodeGridSerializedInput($links[$type]);
+            }
+        }
+        $product = $this->productLinks->initializeLinks($product, $links);
 
         /**
          * Initialize product options
diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index 7db9c80726f6820bfc457cc690dd36bd427bafab..ff187dc7908451852e3e70c6e2c5a4f274557b48 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -36,6 +36,7 @@ use Magento\Framework\Object\IdentityInterface;
  * @method array getAssociatedProductIds()
  * @method \Magento\Catalog\Model\Product setNewVariationsAttributeSetId(int $value)
  * @method int getNewVariationsAttributeSetId()
+ * @method int getPriceType
  * @method \Magento\Catalog\Model\Resource\Product\Collection getCollection()
  *
  * @SuppressWarnings(PHPMD.LongVariable)
@@ -735,7 +736,9 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         /**
          * Product Options
          */
-        $this->getOptionInstance()->setProduct($this)->saveOptions();
+        if (!$this->getIsDuplicate()) {
+            $this->getOptionInstance()->setProduct($this)->saveOptions();
+        }
 
         $result = parent::_afterSave();
 
@@ -1945,7 +1948,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
     protected function _clearData()
     {
         foreach ($this->_data as $data) {
-            if (is_object($data) && method_exists($data, 'reset')) {
+            if (is_object($data) && method_exists($data, 'reset') && is_callable([$data, 'reset'])) {
                 $data->reset();
             }
         }
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php
index f71b38cdd269acd17baedaf9ff3cb1bbd0f492b8..a6b2cd70383d98c4f2a7ee9df06cf4227eac4967 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Backend/Media.php
@@ -311,12 +311,13 @@ class Media extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
             $picturesInOtherStores[$image['filepath']] = true;
         }
 
-        $toDelete = array();
-        $filesToValueIds = array();
+        $recordsToDelete = array();
+        $filesToDelete = array();
         foreach ($value['images'] as &$image) {
             if (!empty($image['removed'])) {
                 if (!empty($image['value_id']) && !isset($picturesInOtherStores[$image['file']])) {
-                    $toDelete[] = $image['value_id'];
+                    $recordsToDelete[] = $image['value_id'];
+                    $filesToDelete[] = ltrim($image['file'], '/');
                 }
                 continue;
             }
@@ -343,18 +344,31 @@ class Media extends \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend
             $this->_getResource()->insertGalleryValueInStore($data);
         }
 
-        $this->_getResource()->deleteGallery($toDelete);
+        $this->_getResource()->deleteGallery($recordsToDelete);
+        $this->removeDeletedImages($filesToDelete);
+    }
+
+    /**
+     * @param array $files
+     * @return null
+     */
+    protected function removeDeletedImages(array $files)
+    {
+        $catalogPath = $this->_mediaConfig->getBaseMediaPath();
+        foreach ($files as $filePath) {
+            $this->_mediaDirectory->delete($catalogPath . '/' . $filePath);
+        }
     }
 
     /**
      * Add image to media gallery and return new filename
      *
      * @param \Magento\Catalog\Model\Product $product
-     * @param string                     $file              file path of image in file system
-     * @param string|string[]            $mediaAttribute    code of attribute with type 'media_image',
+     * @param string $file file path of image in file system
+     * @param string|string[] $mediaAttribute code of attribute with type 'media_image',
      *                                                      leave blank if image should be only in gallery
-     * @param boolean                    $move              if true, it will move source file
-     * @param boolean                    $exclude           mark image as disabled in product page view
+     * @param boolean $move if true, it will move source file
+     * @param boolean $exclude mark image as disabled in product page view
      * @return string
      * @throws Exception
      */
diff --git a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Countryofmanufacture.php b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Countryofmanufacture.php
index 4ba00a2019e3129f19fca53f88abf463944fd565..c32408dcee690840715f288ee2e1f2cb251fbef1 100644
--- a/app/code/Magento/Catalog/Model/Product/Attribute/Source/Countryofmanufacture.php
+++ b/app/code/Magento/Catalog/Model/Product/Attribute/Source/Countryofmanufacture.php
@@ -74,7 +74,7 @@ class Countryofmanufacture extends \Magento\Eav\Model\Entity\Attribute\Source\Ab
      */
     public function getAllOptions()
     {
-        $cacheKey = 'DIRECTORY_COUNTRY_SELECT_STORE_' . $this->_storeManager->getStore()->getCode();
+        $cacheKey = 'COUNTRYOFMANUFACTURE_SELECT_STORE_' . $this->_storeManager->getStore()->getCode();
         if ($cache = $this->_configCacheType->load($cacheKey)) {
             $options = unserialize($cache);
         } else {
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks.php b/app/code/Magento/Catalog/Model/Product/Initialization/Helper/ProductLinks.php
similarity index 57%
rename from app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks.php
rename to app/code/Magento/Catalog/Model/Product/Initialization/Helper/ProductLinks.php
index b5e7c7277e48bcf82a7b358c634273be8ffebc50..0059bcddf8f2dfc6736db7305a46319474db6c27 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks.php
+++ b/app/code/Magento/Catalog/Model/Product/Initialization/Helper/ProductLinks.php
@@ -21,50 +21,29 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper;
+namespace Magento\Catalog\Model\Product\Initialization\Helper;
 
 class ProductLinks
 {
-    /**
-     * @var \Magento\Framework\App\RequestInterface
-     */
-    protected $request;
-
-    /**
-     * @var \Magento\Backend\Helper\Js
-     */
-    protected $jsHelper;
-
-    /**
-     * @param \Magento\Framework\App\RequestInterface $request
-     * @param \Magento\Backend\Helper\Js $jsHelper
-     */
-    public function __construct(\Magento\Framework\App\RequestInterface $request, \Magento\Backend\Helper\Js $jsHelper)
-    {
-        $this->request = $request;
-        $this->jsHelper = $jsHelper;
-    }
-
-    /**
-     * Init product links data (related, upsell, crosssel)
+     /**
+     * Init product links data (related, upsell, cross sell)
      *
      * @param \Magento\Catalog\Model\Product $product
+     * @param array $links link data
      * @return \Magento\Catalog\Model\Product
      */
-    public function initializeLinks(\Magento\Catalog\Model\Product $product)
+    public function initializeLinks(\Magento\Catalog\Model\Product $product, array $links)
     {
-        $links = $this->request->getPost('links');
-
         if (isset($links['related']) && !$product->getRelatedReadonly()) {
-            $product->setRelatedLinkData($this->jsHelper->decodeGridSerializedInput($links['related']));
+            $product->setRelatedLinkData($links['related']);
         }
 
         if (isset($links['upsell']) && !$product->getUpsellReadonly()) {
-            $product->setUpSellLinkData($this->jsHelper->decodeGridSerializedInput($links['upsell']));
+            $product->setUpSellLinkData($links['upsell']);
         }
 
         if (isset($links['crosssell']) && !$product->getCrosssellReadonly()) {
-            $product->setCrossSellLinkData($this->jsHelper->decodeGridSerializedInput($links['crosssell']));
+            $product->setCrossSellLinkData($links['crosssell']);
         }
 
         return $product;
diff --git a/app/code/Magento/Catalog/Model/Resource/Product.php b/app/code/Magento/Catalog/Model/Resource/Product.php
index a85a27dac44c3101e093a1c2b9c7035740e74df9..c7b0aaefd0e4580e0d3ee2084a10fd03644b9d0e 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product.php
@@ -504,6 +504,29 @@ class Product extends AbstractResource
         return $this->_getReadAdapter()->fetchAll($select);
     }
 
+    /**
+     * Get product ids by their sku
+     *
+     * @param  array $productSkuList
+     * @return array
+     */
+    public function getProductsIdsBySkus(array $productSkuList)
+    {
+        $select = $this->_getReadAdapter()->select()->from(
+            $this->getTable('catalog_product_entity'),
+            array('sku', 'entity_id')
+        )->where(
+            'sku IN (?)',
+            $productSkuList
+        );
+
+        $result = array();
+        foreach ($this->_getReadAdapter()->fetchAll($select) as $row) {
+            $result[$row['sku']] = $row['entity_id'];
+        }
+        return $result;
+    }
+
     /**
      * Retrieve product entities info
      *
diff --git a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php
index 74586a381070334c77126f44f08a52f712484830..fea812a89549cd69ef023cbdfa8699b29547afa9 100644
--- a/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php
+++ b/app/code/Magento/Catalog/Model/Resource/Product/Indexer/Eav/Source.php
@@ -140,6 +140,14 @@ class Source extends AbstractEav
             array('d' => $this->getTable('catalog_product_entity_int')),
             '1 = 1 AND d.store_id = 0',
             array('entity_id', 'attribute_id', 'value')
+        )->joinInner(
+            array('d2' => $this->getTable('catalog_product_entity_int')),
+            sprintf(
+                'd.entity_id = d2.entity_id AND d2.attribute_id = %s AND d2.value = %s AND d.store_id = 0',
+                $this->_eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'status')->getId(),
+                ProductStatus::STATUS_ENABLED
+            ),
+            array()
         )->where(
             's.store_id != 0'
         );
diff --git a/app/code/Magento/Catalog/Pricing/Price/BasePrice.php b/app/code/Magento/Catalog/Pricing/Price/BasePrice.php
index 8323a941037c2372ef27b3aa451999e4a4fcfc6c..ec2c1790c750ae30570e603b967e6659ee59d064 100644
--- a/app/code/Magento/Catalog/Pricing/Price/BasePrice.php
+++ b/app/code/Magento/Catalog/Pricing/Price/BasePrice.php
@@ -25,6 +25,7 @@
 namespace Magento\Catalog\Pricing\Price;
 
 use Magento\Framework\Pricing\Price\AbstractPrice;
+use Magento\Framework\Pricing\Price\BasePriceProviderInterface;
 
 /**
  * Class BasePrice
@@ -45,9 +46,8 @@ class BasePrice extends AbstractPrice
     {
         if ($this->value === null) {
             $this->value = false;
-            foreach ($this->priceInfo->getPrices() as $code => $price) {
-                if ($price instanceof \Magento\Framework\Pricing\Price\BasePriceProviderInterface && $price->getValue()
-                ) {
+            foreach ($this->priceInfo->getPrices() as $price) {
+                if ($price instanceof BasePriceProviderInterface && $price->getValue()) {
                     $this->value = min($price->getValue(), $this->value ? : $price->getValue());
                 }
             }
diff --git a/app/code/Magento/Catalog/Pricing/Price/TierPrice.php b/app/code/Magento/Catalog/Pricing/Price/TierPrice.php
index 8a34bf7b83453f59e0689ffcbf9f666efc74beef..8d0f92769d46b80ec9e22fd9bd116bbcf2fda291 100644
--- a/app/code/Magento/Catalog/Pricing/Price/TierPrice.php
+++ b/app/code/Magento/Catalog/Pricing/Price/TierPrice.php
@@ -86,6 +86,7 @@ class TierPrice extends AbstractPrice implements TierPriceInterface, BasePricePr
         CalculatorInterface $calculator,
         Session $customerSession
     ) {
+        $quantity = $quantity ?: 1;
         parent::__construct($saleableItem, $quantity, $calculator);
         $this->customerSession = $customerSession;
         if ($saleableItem->hasCustomerGroupId()) {
diff --git a/app/code/Magento/Catalog/Service/V1/Data/Eav/Attribute.php b/app/code/Magento/Catalog/Service/V1/Data/Eav/Attribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..33c971db73b9b108a80881160af15669011d8633
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Data/Eav/Attribute.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Data\Eav;
+
+use Magento\Framework\Service\Data\AbstractObject;
+
+class Attribute extends AbstractObject
+{
+    const ID = 'id';
+    const CODE = 'code';
+    const IS_REQUIRED = 'is_required';
+    const IS_USER_DEFINED = 'is_user_defined';
+    const LABEL = 'frontend_label';
+    const DEFAULT_VALUE = 'default_value';
+
+    /**
+     * Get attribute ID
+     *
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->_get(self::ID);
+    }
+
+    /**
+     * Get attribute code
+     *
+     * @return string
+     */
+    public function getCode()
+    {
+        return $this->_get(self::CODE);
+    }
+
+    /**
+     * Get attribute frontend label
+     *
+     * @return string|null
+     */
+    public function getFrontendLabel()
+    {
+        return $this->_get(self::LABEL);
+    }
+
+    /**
+     * Get attribute default value
+     *
+     * @return string|null
+     */
+    public function getDefaultValue()
+    {
+        return $this->_get(self::DEFAULT_VALUE);
+    }
+
+    /**
+     * Get attribute is_required flag
+     *
+     * @return boolean
+     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     */
+    public function getIsRequired()
+    {
+        return $this->_get(self::IS_REQUIRED);
+    }
+
+    /**
+     * Get attribute is_user_defined flag
+     *
+     * @return boolean
+     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     */
+    public function getIsUserDefined()
+    {
+        return $this->_get(self::IS_USER_DEFINED);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeBuilder.php b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..55cbfbabcc41a019388c21b70a7b56f77a9cc56c
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeBuilder.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Data\Eav;
+
+use Magento\Framework\Service\Data\AbstractObjectBuilder;
+
+class AttributeBuilder extends AbstractObjectBuilder
+{
+    /**
+     * Set attribute ID
+     *
+     * @param int $attributeId
+     * @return $this
+     */
+    public function setId($attributeId)
+    {
+        return $this->_set(Attribute::ID, $attributeId);
+    }
+
+    /**
+     * Set attribute code
+     *
+     * @param string $code
+     * @return $this
+     */
+    public function setCode($code)
+    {
+        return $this->_set(Attribute::CODE, $code);
+    }
+
+    /**
+     * Set attribute frontend label
+     *
+     * @param string|null $frontendLabel
+     * @return $this
+     */
+    public function setFrontendLabel($frontendLabel)
+    {
+        return $this->_set(Attribute::LABEL, $frontendLabel);
+    }
+
+    /**
+     * Set attribute default value
+     *
+     * @param string|null $defaultValue
+     * @return $this
+     */
+    public function setDefaultValue($defaultValue)
+    {
+        return $this->_set(Attribute::DEFAULT_VALUE, $defaultValue);
+    }
+
+    /**
+     * Set attribute is_required flag
+     *
+     * @param boolean $isRequired
+     * @return $this
+     */
+    public function setIsRequired($isRequired)
+    {
+        return $this->_set(Attribute::IS_REQUIRED, $isRequired);
+    }
+
+    /**
+     * Set attribute is_user_defined flag
+     *
+     * @param boolean $isUserDefined
+     * @return $this
+     */
+    public function setIsUserDefined($isUserDefined)
+    {
+        return $this->_set(Attribute::IS_USER_DEFINED, $isUserDefined);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/Links.php b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeGroup.php
similarity index 63%
rename from dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/Links.php
rename to app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeGroup.php
index b5277047efe2209ea0fa56fc02f352b8aa2be611..6c171121b09307f23beae613ddaea40f23389b3f 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/Links.php
+++ b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeGroup.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,28 +22,37 @@
  * @copyright   Copyright (c) 2014 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\Block\Catalog\Product;
 
-use Mtf\Block\Block;
-use Mtf\Client\Element\Locator;
+namespace Magento\Catalog\Service\V1\Data\Eav;
+
 
-class Links extends Block
+class AttributeGroup extends \Magento\Framework\Service\Data\AbstractObject
 {
+    /**#@+
+     * Constants defined for keys of array, make typos less likely
+     */
+    const KEY_ID = 'id';
+
+    const KEY_NAME = 'name';
+    /**#@-*/
+
     /**
-     * Selector to find label of checkbox by link title
+     * Retrieve id
      *
-     * @var string
+     * @return string
      */
-    protected $labelByTitleSelectorTemplate = '//*[text()="%s"]';
+    public function getId()
+    {
+        return $this->_get(self::KEY_ID);
+    }
 
     /**
-     * @param array $links
+     * Retrieve name
+     *
+     * @return string
      */
-    public function check($links)
+    public function getName()
     {
-        foreach ($links as $link) {
-            $xpath = sprintf($this->labelByTitleSelectorTemplate, $link['title']);
-            $this->_rootElement->find($xpath, Locator::SELECTOR_XPATH)->click();
-        }
+        return $this->_get(self::KEY_NAME);
     }
 }
diff --git a/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeGroupBuilder.php b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeGroupBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..84b2a10e7033a4950d368b20c21604f07a0e76f3
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeGroupBuilder.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Data\Eav;
+
+class AttributeGroupBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
+{
+    /**
+     * Set Id
+     *
+     * @param string $id
+     * @return $this
+     */
+    public function setId($id)
+    {
+        $this->_set(AttributeGroup::KEY_ID, $id);
+        return $this;
+    }
+
+    /**
+     * Set name
+     *
+     * @param string $name
+     * @return $this
+     */
+    public function setName($name)
+    {
+        $this->_set(AttributeGroup::KEY_NAME, $name);
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet.php b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet.php
new file mode 100644
index 0000000000000000000000000000000000000000..5252a88c30ce9bc657153dc56ee60465a21d8b85
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet.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\Service\V1\Data\Eav;
+
+/**
+ * Contains basic attribute set data
+ */
+class AttributeSet extends \Magento\Framework\Service\Data\AbstractObject
+{
+    /**
+     * table field for id
+     */
+    const ID = 'id';
+
+    /**
+     * table field for name
+     */
+    const NAME = 'name';
+
+    /**
+     * table field for sort order index
+     */
+    const ORDER = 'sort_order';
+
+    /**
+     * Get attribute set id
+     *
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->_get(self::ID);
+    }
+
+    /**
+     * Get attribute set name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_get(self::NAME);
+    }
+
+    /**
+     * Get attribute set sort order index
+     *
+     * @return int
+     */
+    public function getSortOrder()
+    {
+        return $this->_get(self::ORDER);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet/Attribute.php b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet/Attribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..09162ff996916dec46893207e9f88b77046fbe0a
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet/Attribute.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\Catalog\Service\V1\Data\Eav\AttributeSet;
+
+class Attribute extends \Magento\Framework\Service\Data\AbstractObject
+{
+    /**
+     * table field for attribute_id
+     */
+    const ATTRIBUTE_ID = 'attribute_id';
+
+    /**
+     * table field for attribute_group_id
+     */
+    const ATTRIBUTE_GROUP_ID = 'attribute_group_id';
+
+    /**
+     * table field for sort order index
+     */
+    const SORT_ORDER = 'sort_order';
+
+    /**
+     * Get attribute id
+     *
+     * @return string
+     */
+    public function getAttributeId()
+    {
+        return $this->_get(self::ATTRIBUTE_ID);
+    }
+
+    /**
+     * Get attribute id
+     *
+     * @return string
+     */
+    public function getAttributeGroupId()
+    {
+        return $this->_get(self::ATTRIBUTE_GROUP_ID);
+    }
+
+    /**
+     * Get attribute set sort order index
+     *
+     * @return int
+     */
+    public function getSortOrder()
+    {
+        return $this->_get(self::SORT_ORDER);
+    }
+}
diff --git a/app/code/Magento/Payment/Model/Config/Source/Allowedmethods.php b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet/AttributeBuilder.php
similarity index 57%
rename from app/code/Magento/Payment/Model/Config/Source/Allowedmethods.php
rename to app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet/AttributeBuilder.php
index cf670020111a664bc9aa808fb85605aafb840309..e7d5faf8f021fc033c4ff248bd397b55f27515b8 100644
--- a/app/code/Magento/Payment/Model/Config/Source/Allowedmethods.php
+++ b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSet/AttributeBuilder.php
@@ -21,38 +21,40 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Payment\Model\Config\Source;
+namespace Magento\Catalog\Service\V1\Data\Eav\AttributeSet;
 
-class Allowedmethods extends \Magento\Payment\Model\Config\Source\Allmethods
+class AttributeBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
 {
     /**
-     * Payment config model
+     * Set attribute group id
      *
-     * @var \Magento\Payment\Model\Config
+     * @param string $id
+     * @return $this
      */
-    protected $_paymentConfig;
+    public function setAttributeGroupId($id)
+    {
+        return $this->_set(Attribute::ATTRIBUTE_GROUP_ID, $id);
+    }
 
     /**
-     * Construct
+     * Get attribute id
      *
-     * @param \Magento\Payment\Helper\Data $paymentData
-     * @param \Magento\Payment\Model\Config $paymentConfig
+     * @param string $id
+     * @return $this
      */
-    public function __construct(
-        \Magento\Payment\Helper\Data $paymentData,
-        \Magento\Payment\Model\Config $paymentConfig
-    ) {
-        parent::__construct($paymentData);
-        $this->_paymentConfig = $paymentConfig;
+    public function setAttributeId($id)
+    {
+        return $this->_set(Attribute::ATTRIBUTE_ID, $id);
     }
 
     /**
-     * Get payment methods
+     * Set attribute set sort order index
      *
-     * @return array
+     * @param int $index
+     * @return $this
      */
-    protected function _getPaymentMethods()
+    public function setSortOrder($index)
     {
-        return $this->_paymentConfig->getActiveMethods();
+        return $this->_set(Attribute::SORT_ORDER, $index);
     }
 }
diff --git a/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSetBuilder.php b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSetBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf90d2ce147d4fd680af70eba7e845e3cfc9f7bf
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Data/Eav/AttributeSetBuilder.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Data\Eav;
+
+/**
+ * Builder for AttributeSet
+ */
+class AttributeSetBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
+{
+    /**
+     * Set attribute set id
+     *
+     * @param int $id
+     * @return $this
+     */
+    public function setId($id)
+    {
+        return $this->_set(AttributeSet::ID, $id);
+    }
+
+    /**
+     * Set attribute set name
+     *
+     * @param string $name
+     * @return $this
+     */
+    public function setName($name)
+    {
+        return $this->_set(AttributeSet::NAME, $name);
+    }
+
+    /**
+     * Set attribute set sort order index
+     *
+     * @param int $index
+     * @return $this
+     */
+    public function setSortOrder($index)
+    {
+        return $this->_set(AttributeSet::ORDER, $index);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Data/ProductType.php b/app/code/Magento/Catalog/Service/V1/Data/ProductType.php
new file mode 100644
index 0000000000000000000000000000000000000000..b7a4a49e5ecb14eca10fe3bed26e52c57c9bb2eb
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Data/ProductType.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Product type data object
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1\Data;
+
+use \Magento\Framework\Service\Data\AbstractObject;
+
+class ProductType extends AbstractObject
+{
+    const NAME = 'name';
+    const LABEL = 'label';
+
+    /**
+     * Retrieve product type name
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->_get(self::NAME);
+    }
+
+    /**
+     * Retrieve product type label
+     *
+     * @return string
+     */
+    public function getLabel()
+    {
+        return $this->_get(self::LABEL);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Data/ProductTypeBuilder.php b/app/code/Magento/Catalog/Service/V1/Data/ProductTypeBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..df36d34454c5e949ca7c417114fbe66ecc3cec62
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Data/ProductTypeBuilder.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Builder for product type service data object
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1\Data;
+
+use Magento\Framework\Service\Data\AbstractObjectBuilder;
+
+class ProductTypeBuilder extends AbstractObjectBuilder
+{
+    /**
+     * Set product type name
+     *
+     * @param string $name
+     * @return $this
+     */
+    public function setName($name)
+    {
+        return $this->_set(ProductType::NAME, $name);
+    }
+
+    /**
+     * Set product type label
+     *
+     * @param string $label
+     * @return $this
+     */
+    public function setLabel($label)
+    {
+        return $this->_set(ProductType::LABEL, $label);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadService.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadService.php
new file mode 100644
index 0000000000000000000000000000000000000000..3307a26979be8018d9c019a38e41d343f1c84f2c
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadService.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\Service\V1\Product\AttributeGroup;
+
+use \Magento\Catalog\Service\V1\Data;
+use \Magento\Eav\Model\Resource\Entity\Attribute\Group\CollectionFactory as AttributeGroupCollectionFactory;
+
+class ReadService implements ReadServiceInterface
+{
+    /**
+     * @var \Magento\Eav\Model\Resource\Entity\Attribute\Group\CollectionFactory
+     */
+    protected $groupListFactory;
+
+    /**
+     * @var \Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder
+     */
+    protected $groupBuilder;
+
+    /**
+     * @param AttributeGroupCollectionFactory $groupListFactory
+     * @param \Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder $groupBuilder
+     */
+    public function __construct(
+        AttributeGroupCollectionFactory $groupListFactory,
+        Data\Eav\AttributeGroupBuilder $groupBuilder
+    ) {
+        $this->groupListFactory = $groupListFactory;
+        $this->groupBuilder = $groupBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getList($attributeSetId)
+    {
+        $collection = $this->groupListFactory->create();
+        $collection->setAttributeSetFilter($attributeSetId);
+        $collection->setSortOrder();
+
+        $groups = array();
+
+        /** @var $group \Magento\Eav\Model\Entity\Attribute\Group */
+        foreach ($collection->getItems() as $group) {
+            $this->groupBuilder->setId(
+                $group->getId()
+            )->setName(
+                $group->getAttributeGroupName()
+            );
+            $groups[] = $this->groupBuilder->create();
+        }
+        return $groups;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadServiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae4eaba782b5766f4cf6f420f229772742e4a6ee
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadServiceInterface.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Product\AttributeGroup;
+
+interface ReadServiceInterface
+{
+    /**
+     * Retrieve list of attribute groups
+     *
+     * @param string $attributeSetId
+     * @return \Magento\Catalog\Service\V1\Data\Eav\AttributeGroup[]
+     */
+    public function getList($attributeSetId);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteService.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteService.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6074d36a26e9031a464d611874b7b2693fd11cd
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteService.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\Catalog\Service\V1\Product\AttributeGroup;
+
+use \Magento\Catalog\Model\Product\Attribute\GroupFactory;
+use \Magento\Catalog\Model\Product\Attribute\Group;
+use Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder;
+use Magento\Framework\Exception\CouldNotSaveException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Exception\StateException;
+
+class WriteService implements WriteServiceInterface
+{
+    /**
+     * @var \Magento\Catalog\Model\Product\Attribute\GroupFactory
+     */
+    protected $groupFactory;
+
+    /**
+     * @var \Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder
+     */
+    protected $groupBuilder;
+
+    /**
+     * @param GroupFactory $groupFactory
+     * @param AttributeGroupBuilder $groupBuilder
+     */
+    public function __construct(GroupFactory $groupFactory, AttributeGroupBuilder $groupBuilder)
+    {
+        $this->groupFactory = $groupFactory;
+        $this->groupBuilder = $groupBuilder;
+    }
+
+    /**
+     * {inheritdoc}
+     */
+    public function create($attributeSetId, \Magento\Catalog\Service\V1\Data\Eav\AttributeGroup $groupData)
+    {
+        try {
+            /** @var Group $attributeGroup */
+            $attributeGroup = $this->groupFactory->create();
+            $attributeGroup->setAttributeGroupName($groupData->getName());
+            $attributeGroup->setAttributeSetId($attributeSetId);
+            $attributeGroup->save();
+            return $this->groupBuilder->setId(
+                $attributeGroup->getId()
+            )->setName(
+                $attributeGroup->getAttributeGroupName()
+            )->create();
+        } catch (\Exception $e) {
+            throw new CouldNotSaveException('Could not create attribute group');
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update($groupId, \Magento\Catalog\Service\V1\Data\Eav\AttributeGroup $groupData)
+    {
+        /** @var Group $attributeGroup */
+        $attributeGroup = $this->groupFactory->create();
+        $attributeGroup->load($groupId);
+        if (!$attributeGroup->getId()) {
+            throw new NoSuchEntityException();
+        }
+        try {
+            $attributeGroup->setId($groupData->getId());
+            $attributeGroup->setAttributeGroupName($groupData->getName());
+            $attributeGroup->save();
+        } catch (\Exception $e) {
+            throw new CouldNotSaveException('Could not update attribute group');
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($groupId)
+    {
+        /** @var Group $attributeGroup */
+        $attributeGroup = $this->groupFactory->create();
+        $attributeGroup->load($groupId);
+        if ($attributeGroup->hasSystemAttributes()) {
+            throw new StateException('Attribute group that contains system attributes can not be deleted');
+        }
+        if (!$attributeGroup->getId()) {
+            throw new NoSuchEntityException();
+        }
+        $attributeGroup->delete();
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteServiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d3c396539eed9b409fb70fb23af30355f5982fa
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteServiceInterface.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Product\AttributeGroup;
+
+interface WriteServiceInterface
+{
+    /**
+     * Create attribute group
+     *
+     * @param string $attributeSetId
+     * @param \Magento\Catalog\Service\V1\Data\Eav\AttributeGroup $groupData
+     * @return \Magento\Catalog\Service\V1\Data\Eav\AttributeGroup
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function create($attributeSetId, \Magento\Catalog\Service\V1\Data\Eav\AttributeGroup $groupData);
+
+    /**
+     * Update attribute group
+     *
+     * @param string $groupId
+     * @param \Magento\Catalog\Service\V1\Data\Eav\AttributeGroup $groupData
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @return bool
+     */
+    public function update($groupId, \Magento\Catalog\Service\V1\Data\Eav\AttributeGroup $groupData);
+
+    /**
+     * Remove attribute group
+     *
+     * @param string $groupId
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\StateException
+     * @return bool
+     */
+    public function delete($groupId);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeService.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeService.php
new file mode 100644
index 0000000000000000000000000000000000000000..96ed5dada869ebf053223173a3756dd6412cb3f6
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeService.php
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Product\AttributeSet;
+
+use Magento\Catalog\Service\V1\Data;
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Exception\StateException;
+
+class AttributeService implements AttributeServiceInterface
+{
+    /**
+     * @var \Magento\Eav\Model\Entity\AttributeFactory
+     */
+    protected $attributeFactory;
+
+    /**
+     * @var \Magento\Eav\Model\Entity\Attribute\SetFactory
+     */
+    protected $setFactory;
+
+    /**
+     * @var \Magento\Eav\Model\Entity\Attribute\GroupFactory
+     */
+    protected $groupFactory;
+
+    /**
+     * @var \Magento\Eav\Model\Resource\Entity\Attribute
+     */
+    protected $attributeResource;
+
+    /**
+     * @var \Magento\Eav\Model\ConfigFactory
+     */
+    protected $entityTypeFactory;
+
+    /**
+     * @param \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory
+     * @param \Magento\Eav\Model\Entity\Attribute\GroupFactory $groupFactory
+     * @param \Magento\Eav\Model\Entity\Attribute\SetFactory $setFactory
+     * @param \Magento\Eav\Model\Resource\Entity\Attribute $attributeResource
+     * @param \Magento\Eav\Model\ConfigFactory $entityTypeFactory
+     */
+    public function __construct(
+        \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory,
+        \Magento\Eav\Model\Entity\Attribute\GroupFactory $groupFactory,
+        \Magento\Eav\Model\Entity\Attribute\SetFactory $setFactory,
+        \Magento\Eav\Model\ConfigFactory $entityTypeFactory,
+        \Magento\Eav\Model\Resource\Entity\Attribute $attributeResource
+    ) {
+        $this->attributeFactory = $attributeFactory;
+        $this->groupFactory = $groupFactory;
+        $this->setFactory = $setFactory;
+        $this->attributeResource = $attributeResource;
+        $this->entityTypeFactory = $entityTypeFactory;
+    }
+
+    /**
+     * Add attribute to attribute set and group
+     *
+     * @param int $attributeSetId
+     * @param Data\Eav\AttributeSet\Attribute $data
+     * @return int
+     * @throws \Magento\Framework\Exception\InputException
+     */
+    public function addAttribute($attributeSetId, \Magento\Catalog\Service\V1\Data\Eav\AttributeSet\Attribute $data)
+    {
+        $attributeSet = $this->setFactory->create()->load($attributeSetId);
+        if (!$attributeSet->getId()) {
+            throw new InputException('Attribute set does not exist');
+        }
+
+        $setEntityType = $this->entityTypeFactory->create()->getEntityType($attributeSet->getEntityTypeId());
+        if ($setEntityType->getEntityTypeCode() != \Magento\Catalog\Model\Product::ENTITY) {
+            throw new InputException('Wrong attribute set id provided');
+        }
+
+        if (!$this->groupFactory->create()->load($data->getAttributeGroupId())->getId()) {
+            throw new InputException('Attribute group does not exist');
+        }
+
+        $attribute = $this->attributeFactory->create();
+        if (!$attribute->load($data->getAttributeId())->getId()) {
+            throw new InputException('Attribute does not exist');
+        }
+
+        $attribute->setId($data->getAttributeId());
+        $attribute->setEntityTypeId($setEntityType->getId());
+        $attribute->setAttributeSetId($attributeSetId);
+        $attribute->setAttributeGroupId($data->getAttributeGroupId());
+        $attribute->setSortOrder($data->getSortOrder());
+
+        $this->attributeResource->saveInSetIncluding($attribute);
+        return $attribute->loadEntityAttributeIdBySet()->getData('entity_attribute_id');
+    }
+
+    /**
+     * @param string $attributeSetId
+     * @param string $attributeId
+     * @return bool
+     * @throws \Magento\Framework\Exception\InputException
+     * @throws \Magento\Framework\Exception\StateException
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function deleteAttribute($attributeSetId, $attributeId)
+    {
+        $attributeSet = $this->setFactory->create()->load($attributeSetId);
+        if (!$attributeSet->getId()) {
+            // Attribute set does not exist
+            throw NoSuchEntityException::singleField('attributeSetId', $attributeSetId);
+        }
+        // check that attribute set has type catalog_product
+        $setEntityType = $this->entityTypeFactory->create()->getEntityType($attributeSet->getEntityTypeId());
+        if ($setEntityType->getEntityTypeCode() != \Magento\Catalog\Model\Product::ENTITY) {
+            throw new InputException('Attribute with wrong attribute type is provided');
+        }
+
+        // check if attribute with requested id exists
+        $attribute = $this->attributeFactory->create()->load($attributeId);
+        if (!$attribute->getId()) {
+            // Attribute set does not exist
+            throw NoSuchEntityException::singleField('attributeId', $attributeId);
+        }
+        // check if attribute is in set
+        $attribute->setAttributeSetId($attributeSet->getId())->loadEntityAttributeIdBySet();
+        if (!$attribute->getEntityAttributeId()) {
+            throw  new InputException('Requested attribute is not in requested attribute set.');
+        }
+        if (!$attribute->getIsUserDefined()) {
+            throw new StateException('System attribute can not be deleted');
+        }
+        $attribute->deleteEntity();
+        return true;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeServiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e6d39281ba0e4f5c9c1b76ed0329be214bec0e3
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeServiceInterface.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Product\AttributeSet;
+
+interface AttributeServiceInterface
+{
+    /**
+     * @param int $attributeSetId
+     * @param \Magento\Catalog\Service\V1\Data\Eav\AttributeSet\Attribute $data
+     * @return int
+     */
+    public function addAttribute($attributeSetId, \Magento\Catalog\Service\V1\Data\Eav\AttributeSet\Attribute $data);
+
+    /**
+     * Remove attribute from attribute set
+     *
+     * @param string $attributeSetId
+     * @param string $attributeId
+     * @throws \Magento\Framework\Exception\InputException
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\StateException
+     * @return bool
+     */
+    public function deleteAttribute($attributeSetId, $attributeId);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/ReadService.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/ReadService.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5ffb524804b3870c62aa394528150a9a56896f3
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/ReadService.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\Service\V1\Product\AttributeSet;
+
+use Magento\Catalog\Service\V1\Data;
+use Magento\Framework\Exception\NoSuchEntityException;
+
+class ReadService implements ReadServiceInterface
+{
+    /**
+     * @var \Magento\Eav\Model\Entity\Attribute\SetFactory
+     */
+    protected $setFactory;
+
+    /**
+     * @var \Magento\Eav\Model\Config
+     */
+    protected $eavConfig;
+
+    /**
+     * @var \Magento\Eav\Model\Resource\Entity\Attribute\Set\CollectionFactory
+     */
+    protected $setCollectionFactory;
+
+    /**
+     * @var Data\Eav\AttributeSetBuilder
+     */
+    protected $attributeSetBuilder;
+
+    /**
+     * @var \Magento\Eav\Model\Resource\Entity\Attribute\Collection
+     */
+    protected $attributeCollection;
+
+    /**
+     * @var \Magento\Catalog\Service\V1\Data\Eav\AttributeBuilder
+     */
+    protected $attributeBuilder;
+
+    /**
+     * @param \Magento\Eav\Model\Entity\Attribute\SetFactory $setFactory
+     * @param \Magento\Eav\Model\Resource\Entity\Attribute\Set\CollectionFactory $setCollectionFactory
+     * @param \Magento\Eav\Model\Config $eavConfig
+     * @param Data\Eav\AttributeSetBuilder $attributeSetBuilder
+     * @param \Magento\Eav\Model\Resource\Entity\Attribute\Collection $attributeCollection
+     * @param Data\Eav\AttributeBuilder $attributeBuilder
+     */
+    public function __construct(
+        \Magento\Eav\Model\Entity\Attribute\SetFactory $setFactory,
+        \Magento\Eav\Model\Resource\Entity\Attribute\Set\CollectionFactory $setCollectionFactory,
+        \Magento\Eav\Model\Config $eavConfig,
+        \Magento\Catalog\Service\V1\Data\Eav\AttributeSetBuilder $attributeSetBuilder,
+        \Magento\Eav\Model\Resource\Entity\Attribute\Collection $attributeCollection,
+        \Magento\Catalog\Service\V1\Data\Eav\AttributeBuilder $attributeBuilder
+    ) {
+        $this->setFactory = $setFactory;
+        $this->setCollectionFactory = $setCollectionFactory;
+        $this->eavConfig = $eavConfig;
+        $this->attributeSetBuilder = $attributeSetBuilder;
+        $this->attributeCollection = $attributeCollection;
+        $this->attributeBuilder = $attributeBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getList()
+    {
+        $sets = array();
+
+        $attributeSetsCollection = $this->setCollectionFactory->create()
+            ->setEntityTypeFilter($this->eavConfig->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getId())
+            ->load();
+
+        /** @var $attributeSet \Magento\Eav\Model\Resource\Entity\Attribute\Set */
+        foreach ($attributeSetsCollection as $attributeSet) {
+            $this->attributeSetBuilder->setId($attributeSet->getId());
+            $this->attributeSetBuilder->setName($attributeSet->getAttributeSetName());
+            $this->attributeSetBuilder->setSortOrder($attributeSet->getSortOrder());
+            $sets[] = $this->attributeSetBuilder->create();
+        }
+
+        return $sets;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getInfo($attributeSetId)
+    {
+        $attributeSet = $this->setFactory->create()->load($attributeSetId);
+        $requiredEntityTypeId = $this->eavConfig->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getId();
+        if (!$attributeSet->getId() || $attributeSet->getEntityTypeId() != $requiredEntityTypeId) {
+            // Attribute set does not exist
+            throw NoSuchEntityException::singleField('attributeSetId', $attributeSetId);
+        }
+        $attrSetDataObject = $this->attributeSetBuilder->setId($attributeSet->getId())
+            ->setName($attributeSet->getAttributeSetName())
+            ->setSortOrder($attributeSet->getSortOrder())
+            ->create();
+        return $attrSetDataObject;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getAttributeList($attributeSetId)
+    {
+        /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
+        $attributeSet = $this->setFactory->create()->load($attributeSetId);
+        $requiredEntityTypeId = $this->eavConfig->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getId();
+        if (!$attributeSet->getId() || $attributeSet->getEntityTypeId() != $requiredEntityTypeId) {
+            // Attribute set does not exist
+            throw NoSuchEntityException::singleField('attributeSetId', $attributeSetId);
+        }
+        $attributeCollection = $this->attributeCollection->setAttributeSetFilter($attributeSet->getId())->load();
+
+        $attributes = array();
+        /** @var \Magento\Eav\Model\Entity\Attribute $attribute */
+        foreach ($attributeCollection as $attribute) {
+            $attributes[] = $this->attributeBuilder->setId($attribute->getAttributeId())
+                ->setCode($attribute->getAttributeCode())
+                ->setFrontendLabel($attribute->getData('frontend_label'))
+                ->setDefaultValue($attribute->getDefaultValue())
+                ->setIsRequired((boolean)$attribute->getData('is_required'))
+                ->setIsUserDefined((boolean)$attribute->getData('is_user_defined'))
+                ->create();
+        }
+        return $attributes;
+
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/ReadServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/ReadServiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..dc9e766fbab2d882135337e4c27fd817cc411611
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/ReadServiceInterface.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\Catalog\Service\V1\Product\AttributeSet;
+
+interface ReadServiceInterface
+{
+    /**
+     * @return \Magento\Catalog\Service\V1\Data\Eav\AttributeSet[]
+     */
+    public function getList();
+
+    /**
+     * Retrieve attribute set information based on given ID
+     *
+     * @param int $attributeSetId
+     * @throws \Magento\Framework\Exception\NoSuchEntityException If $attributeSetId is not found
+     * @return \Magento\Catalog\Service\V1\Data\Eav\AttributeSet
+     */
+    public function getInfo($attributeSetId);
+
+    /**
+     * Retrieve related attributes based on given attribute set ID
+     *
+     * @param int $attributeSetId
+     * @throws \Magento\Framework\Exception\NoSuchEntityException If $attributeSetId is not found
+     * @return \Magento\Catalog\Service\V1\Data\Eav\Attribute[]
+     */
+    public function getAttributeList($attributeSetId);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/WriteService.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/WriteService.php
new file mode 100644
index 0000000000000000000000000000000000000000..70b97d184bdcba79f30fc32317ce43470f73861e
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/WriteService.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\Service\V1\Product\AttributeSet;
+
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Catalog\Service\V1\Data\Eav\AttributeSet;
+use Magento\Framework\Exception\StateException;
+
+/**
+ * Class WriteService
+ * Service to create/update/remove product attribute sets
+ */
+class WriteService implements WriteServiceInterface
+{
+    /**
+     * @var \Magento\Eav\Model\Entity\Attribute\SetFactory
+     */
+    protected $setFactory;
+
+    /**
+     * @param \Magento\Eav\Model\Entity\Attribute\SetFactory $setFactory
+     * @param \Magento\Eav\Model\Config $eavConfig
+     */
+    public function __construct(
+        \Magento\Eav\Model\Entity\Attribute\SetFactory $setFactory,
+        \Magento\Eav\Model\Config $eavConfig
+    ) {
+        $this->setFactory = $setFactory;
+        $this->eavConfig = $eavConfig;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function create(AttributeSet $setData, $skeletonId)
+    {
+        if ($setData->getId()) {
+            throw InputException::invalidFieldValue('id', $setData->getId());
+        }
+
+        $basicData = array(
+            'attribute_set_name' => $setData->getName(),
+            'sort_order' => $setData->getSortOrder(),
+            'entity_type_id' => $this->eavConfig->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getId(),
+        );
+
+        /** @var \Magento\Eav\Model\Entity\Attribute\Set $set */
+        $set = $this->setFactory->create();
+        foreach ($basicData as $key => $value) {
+            $set->setData($key, $value);
+        }
+        $set->validate();
+        $set->save();
+        //process skeleton data
+        $skeletonId = intval($skeletonId);
+        if (0 == $skeletonId) {
+            throw InputException::invalidFieldValue('skeletonId', $skeletonId);
+        }
+
+        $skeletonSet = $this->setFactory->create()->load($skeletonId);
+        $skeletonData = $skeletonSet->getData();
+        if (empty($skeletonData)) {
+            throw NoSuchEntityException::singleField('id', $skeletonId);
+        }
+        $set->initFromSkeleton($skeletonId);
+        $set->save();
+
+        return $set->getId();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update(AttributeSet $attributeSetData)
+    {
+        if (!$attributeSetData->getId()) {
+            throw InputException::requiredField('id');
+        }
+
+        $attributeSetModel = $this->setFactory->create()->load($attributeSetData->getId());
+        $requiredEntityTypeId = $this->eavConfig->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getId();
+        if (!$attributeSetModel->getId() || $attributeSetModel->getEntityTypeId() != $requiredEntityTypeId) {
+            throw NoSuchEntityException::singleField('id', $attributeSetData->getId());
+        }
+
+        $attributeSetModel->setAttributeSetName($attributeSetData->getName());
+        $attributeSetModel->setSortOrder($attributeSetData->getSortOrder());
+        $attributeSetModel->save();
+        return $attributeSetModel->getId();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function remove($attributeSetId)
+    {
+        $id = intval($attributeSetId);
+        if (0 == $id) {
+            throw InputException::invalidFieldValue('id', $id);
+        }
+
+        /** @var \Magento\Eav\Model\Entity\Attribute\Set $attributeSet */
+        $attributeSet = $this->setFactory->create()->load($id);
+        $defaultAttributeSetId =
+            $this->eavConfig->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getDefaultAttributeSetId();
+        $loadedData = $attributeSet->getData();
+        if (empty($loadedData)) {
+            throw NoSuchEntityException::singleField('id', $attributeSetId);
+        }
+        $productEntityId = $this->eavConfig->getEntityType(\Magento\Catalog\Model\Product::ENTITY)->getId();
+        if ($attributeSet->getEntityTypeId() != $productEntityId) {
+            throw InputException::invalidFieldValue('id', $attributeSetId);
+        }
+
+        if ($attributeSetId == $defaultAttributeSetId) {
+            throw new StateException('Default attribute set can not be deleted');
+        }
+        $attributeSet->delete();
+        return true;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/WriteServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/WriteServiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..39fb14686afce85dd03b17f969bcc728b8ebcacc
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/AttributeSet/WriteServiceInterface.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\Service\V1\Product\AttributeSet;
+
+use Magento\Catalog\Service\V1\Data\Eav\AttributeSet;
+
+/**
+ * Interface WriteServiceInterface
+ * Service interface to create/update/remove product attribute sets
+ */
+interface WriteServiceInterface
+{
+    /**
+     * Create attribute set from data
+     *
+     * @param \Magento\Catalog\Service\V1\Data\Eav\AttributeSet $attributeSet
+     * @param int $skeletonId
+     * @return int
+     * @throws \Magento\Framework\Exception\InputException
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Eav\Exception from validate()
+     */
+    public function create(AttributeSet $attributeSet, $skeletonId);
+
+    /**
+     * Update attribute set data
+     *
+     * @param \Magento\Catalog\Service\V1\Data\Eav\AttributeSet $attributeSetData
+     * @return int attribute set ID
+     * @throws \Magento\Framework\Model\Exception If attribute set is not found
+     */
+    public function update(AttributeSet $attributeSetData);
+
+    /**
+     * Remove attribute set by id
+     *
+     * @param int $attributeSetId
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\InputException
+     * @return bool
+     */
+    public function remove($attributeSetId);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkAttribute.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkAttribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..3531cbdadfba716b3e6e546ed065b537ba6dba19
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkAttribute.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\Service\V1\Product\Link\Data;
+
+/**
+ * LinkAttribute Service Data Object
+ */
+class LinkAttribute extends \Magento\Framework\Service\Data\AbstractObject
+{
+    /**#@+
+     * Constants for Data Object keys
+     */
+    const CODE = 'code';
+    const TYPE = 'type';
+
+    /**
+     * Get attribute code
+     *
+     * @return string
+     */
+    public function getCode()
+    {
+        return $this->_get(self::CODE);
+    }
+
+    /**
+     * Get attribute type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->_get(self::TYPE);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Backup/_files/Tar.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkAttributeBuilder.php
similarity index 62%
rename from dev/tests/unit/testsuite/Magento/Framework/Backup/_files/Tar.php
rename to app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkAttributeBuilder.php
index 6d496cefe1c38778fdf4b1cc5d64f5b389eff72a..24da159e9b56967cda27e3da24a49bc587a13cb7 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Backup/_files/Tar.php
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkAttributeBuilder.php
@@ -22,36 +22,34 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\Catalog\Service\V1\Product\Link\Data;
+
 /**
- * Mock class to work with tar archives
+ * Builder for the LinkAttribute Service Data Object
+ *
+ * @method LinkAttribute create()
  */
-namespace Magento\Framework\Backup\Archive;
-
-class Tar
+class LinkAttributeBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
 {
     /**
-     * Mock set files that shouldn't be added to tarball
+     * Set attribute code
      *
-     * @param array $skipFiles
+     * @param string $code
      * @return $this
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
-    public function setSkipFiles(array $skipFiles)
+    public function setCode($code)
     {
-        return $this;
+        return $this->_set(LinkAttribute::CODE, $code);
     }
 
     /**
-     * Mock pack file to TAR (Tape Archiver).
+     * Set type
      *
-     * @param $source
-     * @param $destination
-     * @param bool $skipRoot
-     * @return string
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @param string $type
+     * @return $this
      */
-    public function pack($source, $destination, $skipRoot = false)
+    public function setType($type)
     {
-        return '\unexistingpath';
+        return $this->_set(LinkAttribute::TYPE, $type);
     }
 }
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkType.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkType.php
new file mode 100644
index 0000000000000000000000000000000000000000..94269b810145ef9aeb189162a08f661f40fec1fb
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkType.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\Service\V1\Product\Link\Data;
+
+/**
+ * LinkType Service Data Object
+ */
+class LinkType extends \Magento\Framework\Service\Data\AbstractObject
+{
+    /**#@+
+     * Constants for Data Object keys
+     */
+    const TYPE = 'type';
+    const CODE = 'code';
+
+    /**
+     * Get type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->_get(self::TYPE);
+    }
+
+    /**
+     * Get code
+     *
+     * @return int
+     */
+    public function getCode()
+    {
+        return $this->_get(self::CODE);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkTypeBuilder.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkTypeBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..3abf3bfb8d268877f7c2e1ebfc066abea910dac2
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/LinkTypeBuilder.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\Service\V1\Product\Link\Data;
+
+/**
+ * Builder for the LinkType Service Data Object
+ *
+ * @method LinkType create()
+ */
+class LinkTypeBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
+{
+    /**
+     * Set type
+     *
+     * @param string $type
+     * @return $this
+     */
+    public function setType($type)
+    {
+        return $this->_set(LinkType::TYPE, $type);
+    }
+
+    /**
+     * Set code
+     *
+     * @param int $code
+     * @return $this
+     */
+    public function setCode($code)
+    {
+        return $this->_set(LinkType::CODE, $code);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink.php
new file mode 100644
index 0000000000000000000000000000000000000000..f809e6c5e1ad3da2a43aab18940fd3dc34038b12
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data;
+
+/**
+ * ProductLink Service Data Object
+ */
+class ProductLink extends \Magento\Framework\Service\Data\Eav\AbstractObject
+{
+    /**#@+
+     * Constants for Data Object keys
+     */
+    const TYPE = 'type';
+    const ATTRIBUTE_SET_ID = 'attribute_set_id';
+    const SKU = 'sku';
+    const POSITION = 'position';
+
+    /**
+     * Get type
+     *
+     * @return string
+     */
+    public function getType()
+    {
+        return $this->_get(self::TYPE);
+    }
+
+    /**
+     * Get product sku
+     *
+     * @return string
+     */
+    public function getSku()
+    {
+        return $this->_get(self::SKU);
+    }
+
+    /**
+     * Get product position
+     *
+     * @return int
+     */
+    public function getPosition()
+    {
+        return $this->_get(self::POSITION);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..52a5629b1da4f64c5445005834c909c3bdf40784
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+
+use \Magento\Framework\Exception\NoSuchEntityException;
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterPool;
+
+class CollectionProvider
+{
+    /**
+     * @var CollectionProviderInterface[]
+     */
+    protected $providers;
+
+    /**
+     * @var ConverterPool
+     */
+    protected $converterPool;
+
+    /**
+     * @param ConverterPool $converterPool
+     * @param CollectionProviderInterface[] $providers
+     */
+    public function __construct(ConverterPool $converterPool, array $providers = array())
+    {
+        $this->converterPool = $converterPool;
+        $this->providers = $providers;
+    }
+
+    /**
+     * Get product collection by link type
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @param string $type
+     * @return array
+     * @throws NoSuchEntityException
+     */
+    public function getCollection(\Magento\Catalog\Model\Product $product, $type)
+    {
+        if (!isset($this->providers[$type])) {
+            throw new NoSuchEntityException('Collection provider is not registered');
+        }
+
+        $products = $this->providers[$type]->getLinkedProducts($product);
+        $converter = $this->converterPool->getConverter($type);
+        $output = [];
+        foreach ($products as $item) {
+            $output[$item->getId()] = $converter->convert($item);
+        }
+        return $output;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Crosssell.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Crosssell.php
new file mode 100644
index 0000000000000000000000000000000000000000..972af9db72c9ae607e354a267870fcafe71597d1
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Crosssell.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider;
+
+class Crosssell implements \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProviderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getLinkedProducts(\Magento\Catalog\Model\Product $product)
+    {
+        return $product->getCrossSellProducts();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Backup/_files/Gz.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Related.php
similarity index 73%
rename from dev/tests/unit/testsuite/Magento/Framework/Backup/_files/Gz.php
rename to app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Related.php
index 209451d994ea6c70c9becccc116b232c521f09da..49afce18014024912b73023936394ad6d713bec3 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Backup/_files/Gz.php
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Related.php
@@ -22,23 +22,15 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-/**
- * Mock class to work with gz archives
- */
-namespace Magento\Framework\Archive;
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider;
 
-class Gz
+class Related implements \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProviderInterface
 {
     /**
-     * Mock pack file by GZ compressor.
-     *
-     * @param $source
-     * @param $destination
-     * @return string
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * {@inheritdoc}
      */
-    public function pack($source, $destination)
+    public function getLinkedProducts(\Magento\Catalog\Model\Product $product)
     {
-        return '\unexistingpath';
+        return $product->getRelatedProducts();
     }
 }
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Upsell.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Upsell.php
new file mode 100644
index 0000000000000000000000000000000000000000..f564dbd16561a5e8a4feb64a68e3bf5e5090535d
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Upsell.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider;
+
+class Upsell implements \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProviderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getLinkedProducts(\Magento\Catalog\Model\Product $product)
+    {
+        return $product->getUpSellProducts();
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProviderInterface.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProviderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..2223cfe80a3649935ce7ac26693555cb2b9d455a
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProviderInterface.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+
+interface CollectionProviderInterface
+{
+    /**
+     * Get linked products
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return \Magento\Catalog\Model\Product[]
+     */
+    public function getLinkedProducts(\Magento\Catalog\Model\Product $product);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapper/Composite.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapper/Composite.php
new file mode 100644
index 0000000000000000000000000000000000000000..a74a82602cd985ea5c2630907518b5e383b136b2
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapper/Composite.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapper;
+
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapperInterface;
+
+class Composite implements DataMapperInterface
+{
+    /**
+     * @var DataMapperInterface[]
+     */
+    protected $mappers;
+
+    /**
+     * @param DataMapperInterface[] $mappers
+     */
+    public function __construct(array $mappers = array())
+    {
+        $this->mappers = $mappers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function map(array $data)
+    {
+        foreach ($this->mappers as $mapper) {
+            $data = $mapper->map($data);
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/OfflinePayments/Block/Form/Ccsave.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapperInterface.php
similarity index 81%
rename from app/code/Magento/OfflinePayments/Block/Form/Ccsave.php
rename to app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapperInterface.php
index 804d8fa70792080ad61dc6c7276a384a8a548cfd..cbf50c17d587c06482d10d00996ae469fbfe2e39 100644
--- a/app/code/Magento/OfflinePayments/Block/Form/Ccsave.php
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapperInterface.php
@@ -21,14 +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\OfflinePayments\Block\Form;
 
-class Ccsave extends \Magento\Payment\Block\Form\Cc
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+
+interface DataMapperInterface
 {
     /**
-     * Cc save template
+     * Map data object
      *
-     * @var string
+     * @param array $data
+     * @return array
      */
-    protected $_template = 'Magento_OfflinePayments::form/ccsave.phtml';
+    public function map(array $data);
 }
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterInterface.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c64d526eb13e38ecbd4326b6644db8585463f25
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterInterface.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity;
+
+interface ConverterInterface
+{
+    /**
+     * Convert product to array representation
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @return array
+     */
+    public function convert(\Magento\Catalog\Model\Product $product);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterPool.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterPool.php
new file mode 100644
index 0000000000000000000000000000000000000000..d464e11d1031d4854ea964cd151df967c8860bf7
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterPool.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity;
+
+class ConverterPool
+{
+    /**
+     * @var ConverterInterface[]
+     */
+    protected $converters;
+
+    /**
+     * @var string
+     */
+    protected $defaultConverterCode = 'default';
+
+    /**
+     * @param  ConverterInterface[] $converters
+     */
+    public function __construct(array $converters)
+    {
+        $this->converters = $converters;
+    }
+
+    /**
+     * Get converter by link type
+     *
+     * @param string $linkType
+     * @return ConverterInterface
+     */
+    public function getConverter($linkType)
+    {
+        return isset($this->converters[$linkType])
+            ? $this->converters[$linkType]
+            : $this->converters[$this->defaultConverterCode];
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/DefaultConverter.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/DefaultConverter.php
new file mode 100644
index 0000000000000000000000000000000000000000..25e27b7ee202640ece09133fdef475172c8e1223
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/DefaultConverter.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity;
+
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+
+class DefaultConverter implements ConverterInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function convert(\Magento\Catalog\Model\Product $product)
+    {
+        return [
+            ProductLink::TYPE => $product->getTypeId(),
+            ProductLink::SKU => $product->getSku(),
+            ProductLink::POSITION => $product->getPosition()
+        ];
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLinkBuilder.php b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLinkBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..2355b2838ac53bed6ec5b1586339d027e73a9bb9
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/Data/ProductLinkBuilder.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data;
+
+use Magento\Framework\Service\Data\Eav\AttributeValueBuilder;
+
+/**
+ * Builder for the ProductLink Service Data Object
+ *
+ * @method ProductLink create()
+ */
+class ProductLinkBuilder extends \Magento\Framework\Service\Data\Eav\AbstractObjectBuilder
+{
+    /**
+     * @var array
+     */
+    protected $customAttributes = [];
+
+    /**
+     * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory
+     * @param AttributeValueBuilder $valueBuilder
+     * @param array $customAttributesCodes
+     */
+    public function __construct(
+        \Magento\Framework\Service\Data\ObjectFactory $objectFactory,
+        AttributeValueBuilder $valueBuilder,
+        array $customAttributesCodes = array()
+    ) {
+        $this->customAttributes = $customAttributesCodes;
+        parent::__construct($objectFactory, $valueBuilder);
+    }
+    
+    /**
+     * Set type
+     *
+     * @param string $type
+     * @return $this
+     */
+    public function setType($type)
+    {
+        return $this->_set(ProductLink::TYPE, $type);
+    }
+
+    /**
+     * Set product sku
+     *
+     * @param string $sku
+     * @return $this
+     */
+    public function setSku($sku)
+    {
+        return $this->_set(ProductLink::SKU, $sku);
+    }
+
+    /**
+     * Set product position
+     *
+     * @param int $position
+     * @return $this
+     */
+    public function setPosition($position)
+    {
+        return $this->_set(ProductLink::POSITION, $position);
+    }
+
+    /**
+     * Get custom attributes codes
+     *
+     * @return string[]
+     */
+    public function getCustomAttributesCodes()
+    {
+        return array_merge(parent::getCustomAttributesCodes(), $this->customAttributes);
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/LinkTypeResolver.php b/app/code/Magento/Catalog/Service/V1/Product/Link/LinkTypeResolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..1bc89fe85ceaab46cc7a25d6af77bafac18e6183
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/LinkTypeResolver.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link;
+
+use \Magento\Catalog\Model\Product\LinkTypeProvider;
+use \Magento\Framework\Exception\NoSuchEntityException;
+
+class LinkTypeResolver
+{
+    /**
+     * @var LinkTypeProvider
+     */
+    protected $linkTypeProvider;
+
+    /**
+     * @param LinkTypeProvider $linkTypeProvider
+     */
+    public function __construct(LinkTypeProvider $linkTypeProvider)
+    {
+        $this->linkTypeProvider = $linkTypeProvider;
+    }
+
+    /**
+     * Get link type id by code
+     *
+     * @param string $code
+     * @throws NoSuchEntityException
+     * @return int
+     */
+    public function getTypeIdByCode($code)
+    {
+        $types = $this->linkTypeProvider->getLinkTypes();
+        if (isset($types[$code])) {
+            return $types[$code];
+        }
+        throw new NoSuchEntityException('Unknown link type code is provided');
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/ProductLoader.php b/app/code/Magento/Catalog/Service/V1/Product/Link/ProductLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ebbe959f1cef87d6922e7b6b0e0148de7e0e436
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/ProductLoader.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link;
+
+use \Magento\Framework\Exception\NoSuchEntityException;
+
+class ProductLoader
+{
+    /**
+     * @var \Magento\Catalog\Model\ProductFactory
+     */
+    protected $productFactory;
+
+    /**
+     * @param \Magento\Catalog\Model\ProductFactory $productFactory
+     */
+    public function __construct(\Magento\Catalog\Model\ProductFactory $productFactory)
+    {
+        $this->productFactory = $productFactory;
+    }
+
+    /**
+     * Load product by SKU
+     *
+     * @param string $productSku
+     * @return \Magento\Catalog\Model\Product
+     * @throws NoSuchEntityException
+     */
+    public function load($productSku)
+    {
+        /** @var \Magento\Catalog\Model\Product $product */
+        $product = $this->productFactory->create();
+        $productId = $product->getIdBySku($productSku);
+
+        if (!$productId) {
+            throw new NoSuchEntityException('There is no product with provided SKU');
+        }
+        $product->load($productId);
+        return $product;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/ReadService.php b/app/code/Magento/Catalog/Service/V1/Product/Link/ReadService.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e2a652a8e64ae3807ce23190407a5f788bd0776
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/ReadService.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1\Product\Link;
+
+use \Magento\Catalog\Model\Product\LinkTypeProvider;
+use \Magento\Catalog\Service\V1\Product\Link\Data\LinkType;
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+use \Magento\Framework\Logger;
+
+/**
+ * Class ReadService
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class ReadService implements ReadServiceInterface
+{
+    /**
+     * @var LinkTypeProvider
+     */
+    protected $linkTypeProvider;
+
+    /**
+     * @var Data\LinkTypeBuilder
+     */
+    protected $builder;
+
+    /**
+     * @var ProductLoader
+     */
+    protected $productLoader;
+
+    /**
+     * @var LinkTypeResolver
+     */
+    protected $linkTypeResolver;
+
+    /**
+     * @var Data\ProductLinkBuilder
+     */
+    protected $productEntityBuilder;
+
+    /**
+     * @var Data\ProductLink\CollectionProvider
+     */
+    protected $entityCollectionProvider;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\LinkFactory
+     */
+    protected $linkFactory;
+
+    /**
+     * @var Data\LinkAttributeBuilder
+     */
+    protected $linkAttributeBuilder;
+
+    /**
+     * @param LinkTypeProvider $linkTypeProvider
+     * @param Data\LinkTypeBuilder $builder
+     * @param Data\ProductLinkBuilder $productEntityBuilder
+     * @param ProductLoader $productLoader
+     * @param ProductLink\CollectionProvider $entityCollectionProvider
+     * @param Data\LinkAttributeBuilder $linkAttributeBuilder
+     * @param \Magento\Catalog\Model\Product\LinkFactory $linkFactory
+     * @param LinkTypeResolver $linkTypeResolver
+     */
+    public function __construct(
+        LinkTypeProvider $linkTypeProvider,
+        Data\LinkTypeBuilder $builder,
+        Data\ProductLinkBuilder $productEntityBuilder,
+        ProductLoader $productLoader,
+        Data\ProductLink\CollectionProvider $entityCollectionProvider,
+        Data\LinkAttributeBuilder $linkAttributeBuilder,
+        \Magento\Catalog\Model\Product\LinkFactory $linkFactory,
+        LinkTypeResolver $linkTypeResolver
+    ) {
+        $this->linkTypeProvider = $linkTypeProvider;
+        $this->builder = $builder;
+        $this->productLoader = $productLoader;
+        $this->productEntityBuilder = $productEntityBuilder;
+        $this->entityCollectionProvider = $entityCollectionProvider;
+        $this->linkFactory = $linkFactory;
+        $this->linkAttributeBuilder = $linkAttributeBuilder;
+        $this->linkTypeResolver = $linkTypeResolver;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getProductLinkTypes()
+    {
+        $output = [];
+        foreach ($this->linkTypeProvider->getLinkTypes() as $type => $typeCode) {
+            $data = [LinkType::TYPE => $type, LinkType::CODE => $typeCode];
+            $output[] = $this->builder
+                ->populateWithArray($data)
+                ->create();
+        }
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLinkedProducts($productSku, $type)
+    {
+        $output = [];
+        $product = $this->productLoader->load($productSku);
+        $collection = $this->entityCollectionProvider->getCollection($product, $type);
+        foreach ($collection as $item) {
+            $output[] = $this->productEntityBuilder->populateWithArray($item)->create();
+        }
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getLinkAttributes($type)
+    {
+        $output = [];
+        $typeId = $this->linkTypeResolver->getTypeIdByCode($type);
+
+        /** @var \Magento\Catalog\Model\Product\Link $link */
+        $link = $this->linkFactory->create(['data' => ['link_type_id' => $typeId]]);
+        $attributes = $link->getAttributes();
+        foreach ($attributes as $item) {
+            $data = [
+                Data\LinkAttribute::CODE => $item['code'],
+                Data\LinkAttribute::TYPE => $item['type'],
+            ];
+            $output[] = $this->linkAttributeBuilder->populateWithArray($data)->create();
+        }
+        return $output;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/ReadServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/Link/ReadServiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a063cc52100de3c2127eb9abcd4f6d1c7569b05
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/ReadServiceInterface.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link;
+
+interface ReadServiceInterface
+{
+    /**
+     * Provide the list of product link types
+     *
+     * @return \Magento\Catalog\Service\V1\Product\Link\Data\LinkType[]
+     */
+    public function getProductLinkTypes();
+
+    /**
+     * Provide the list of linked products for a specific product
+     *
+     * @param string $productSku
+     * @param string $type
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @return \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink[]
+     */
+    public function getLinkedProducts($productSku, $type);
+
+    /**
+     * Provide a list of the product link type attributes
+     *
+     * @param string $type
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @return \Magento\Catalog\Service\V1\Product\Link\Data\LinkAttribute[]
+     */
+    public function getLinkAttributes($type);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/WriteService.php b/app/code/Magento/Catalog/Service/V1/Product/Link/WriteService.php
new file mode 100644
index 0000000000000000000000000000000000000000..dfc04fb088fee18fe5bc1ac4368e252a2fdd2321
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/WriteService.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+ 
+namespace Magento\Catalog\Service\V1\Product\Link;
+
+use \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks as LinksInitializer;
+use \Magento\Framework\Exception\CouldNotSaveException;
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+use \Magento\Framework\Exception\NoSuchEntityException;
+use \Magento\Catalog\Model\Resource\Product as ProductResource;
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterPool;
+
+class WriteService implements WriteServiceInterface
+{
+    /**
+     * @var LinksInitializer
+     */
+    protected $linkInitializer;
+
+    /**
+     * @var Data\ProductLink\CollectionProvider
+     */
+    protected $entityCollectionProvider;
+
+    /**
+     * @var ProductLoader
+     */
+    protected $productLoader;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product
+     */
+    protected $productResource;
+
+    /**
+     * @var Data\ProductLink\DataMapperInterface
+     */
+    protected $dataMapper;
+
+    /**
+     * @param LinksInitializer $linkInitializer
+     * @param ProductLink\CollectionProvider $entityCollectionProvider
+     * @param ProductLoader $productLoader
+     * @param ProductResource $productResource
+     * @param ProductLink\DataMapperInterface $dataMapper
+     */
+    public function __construct(
+        LinksInitializer $linkInitializer,
+        ProductLink\CollectionProvider $entityCollectionProvider,
+        ProductLoader $productLoader,
+        ProductResource $productResource,
+        Data\ProductLink\DataMapperInterface $dataMapper
+    ) {
+        $this->linkInitializer = $linkInitializer;
+        $this->entityCollectionProvider = $entityCollectionProvider;
+        $this->productLoader = $productLoader;
+        $this->productResource = $productResource;
+        $this->dataMapper = $dataMapper;
+    }
+
+    /**
+     * Save product links
+     *
+     * @param \Magento\Catalog\Model\Product $product
+     * @param array $links
+     * @throws CouldNotSaveException
+     * @return void
+     */
+    protected function saveLinks($product, array $links)
+    {
+        foreach ($links as $type => $linksData) {
+            $links[$type] = $this->dataMapper->map($linksData);
+        }
+        $this->linkInitializer->initializeLinks($product, $links);
+        try {
+            $product->save();
+        } catch (\Exception $exception) {
+            throw new CouldNotSaveException('Invalid data provided for linked products');
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function assign($productSku, array $assignedProducts, $type)
+    {
+        $product = $this->productLoader->load($productSku);
+        $assignedSkuList = array_map(
+            function ($item) {
+                return $item->getSku();
+            },
+            $assignedProducts
+        );
+        $linkedProductIds = $this->productResource->getProductsIdsBySkus($assignedSkuList);
+
+        $links = [];
+        /** @var Data\ProductLink[] $assignedProducts*/
+        foreach ($assignedProducts as $linkedProduct) {
+            $data = $linkedProduct->__toArray();
+            if (!isset($linkedProductIds[$linkedProduct->getSku()])) {
+                throw new NoSuchEntityException(
+                    sprintf("Product with SKU \"%s\" does not exist", $linkedProduct->getSku())
+                );
+            }
+            $data['product_id'] = $linkedProductIds[$linkedProduct->getSku()];
+            $links[$linkedProductIds[$linkedProduct->getSku()]] = $data;
+        }
+        $this->saveLinks($product, [$type => $links]);
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function update($productSku, Data\ProductLink $linkedProduct, $type)
+    {
+        $product = $this->productLoader->load($productSku);
+        $linkedProductEntity = $this->productLoader->load($linkedProduct->getSku());
+        $links = $this->entityCollectionProvider->getCollection($product, $type);
+
+        if (!isset($links[$linkedProductEntity->getId()])) {
+            throw new NoSuchEntityException(
+                sprintf(
+                    "Product with SKU \"%s\" is not linked to product with SKU %s",
+                    $linkedProduct->getSku(),
+                    $productSku
+                )
+            );
+        }
+
+        $data = $linkedProduct->__toArray();
+        $data['product_id'] = $linkedProductEntity->getId();
+        $links[$linkedProductEntity->getId()] = $data;
+        $this->saveLinks($product, [$type => $links]);
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function remove($productSku, $linkedProductSku, $type)
+    {
+        $linkedProduct = $this->productLoader->load($linkedProductSku);
+        $product = $this->productLoader->load($productSku);
+        $links = $this->entityCollectionProvider->getCollection($product, $type);
+
+        if (!isset($links[$linkedProduct->getId()])) {
+            throw new NoSuchEntityException(
+                sprintf('Product with SKU %s is not linked to product with SKU %s', $linkedProductSku, $productSku)
+            );
+        }
+
+        //Remove product from the linked product list
+        unset($links[$linkedProduct->getId()]);
+
+        $this->saveLinks($product, [$type => $links]);
+
+        return true;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/Product/Link/WriteServiceInterface.php b/app/code/Magento/Catalog/Service/V1/Product/Link/WriteServiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4a4569616120ae6b925824c6daed6eccde94ec9
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/Product/Link/WriteServiceInterface.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\Service\V1\Product\Link;
+
+interface WriteServiceInterface
+{
+    /**
+     * Assign a product link to another product
+     *
+     * @param string $productSku
+     * @param \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink[] $assignedProducts
+     * @param string $type
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @return bool
+     */
+    public function assign($productSku, array $assignedProducts, $type);
+
+    /**
+     * Update product link
+     *
+     * @param string $productSku
+     * @param \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink $linkedProduct
+     * @param string $type
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @return bool
+     */
+    public function update($productSku, Data\ProductLink $linkedProduct, $type);
+
+    /**
+     * Remove the product link from a specific product
+     *
+     * @param string $productSku
+     * @param string $linkedProductSku
+     * @param string $type
+     * @throws \Magento\Framework\Exception\NoSuchEntityException
+     * @throws \Magento\Framework\Exception\CouldNotSaveException
+     * @return bool
+     */
+    public function remove($productSku, $linkedProductSku, $type);
+}
diff --git a/app/code/Magento/Catalog/Service/V1/ProductTypeService.php b/app/code/Magento/Catalog/Service/V1/ProductTypeService.php
new file mode 100644
index 0000000000000000000000000000000000000000..094da8b8168751e681d923d5730259875042676f
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/ProductTypeService.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Product type service
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1;
+
+use Magento\Catalog\Model\ProductTypes\ConfigInterface;
+use Magento\Catalog\Service\V1\Data\ProductTypeBuilder;
+
+class ProductTypeService implements ProductTypeServiceInterface
+{
+    /**
+     * @var ConfigInterface
+     */
+    private $productTypeConfig;
+
+    /**
+     * @var ProductTypeBuilder
+     */
+    private $productTypeBuilder;
+
+    /**
+     * @param ConfigInterface $productTypeConfig
+     * @param ProductTypeBuilder $productTypeBuilder
+     */
+    public function __construct(
+        ConfigInterface $productTypeConfig,
+        ProductTypeBuilder $productTypeBuilder
+    ) {
+        $this->productTypeConfig = $productTypeConfig;
+        $this->productTypeBuilder = $productTypeBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getProductTypes()
+    {
+        $productTypes = array();
+        foreach ($this->productTypeConfig->getAll() as $productTypeData) {
+            $productTypes[] = $this->productTypeBuilder->setName($productTypeData['name'])
+                ->setLabel($productTypeData['label'])
+                ->create();
+        }
+        return $productTypes;
+    }
+}
diff --git a/app/code/Magento/Catalog/Service/V1/ProductTypeServiceInterface.php b/app/code/Magento/Catalog/Service/V1/ProductTypeServiceInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ad7a4011b5eaf988a40c20225ffe8912cbd7577
--- /dev/null
+++ b/app/code/Magento/Catalog/Service/V1/ProductTypeServiceInterface.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Product type service interface
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1;
+
+interface ProductTypeServiceInterface
+{
+    /**
+     * Retrieve the list of product types
+     *
+     * @return \Magento\Catalog\Service\V1\Data\ProductType[]
+     */
+    public function getProductTypes();
+}
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index ddd2b82bd7001009edd889482e6b43d5fabc9e47..36f1c3c652250383fdb6290271cda21c272f0ded 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -33,6 +33,15 @@
     <preference for="Magento\Framework\Pricing\PriceInfoInterface" type="Magento\Framework\Pricing\PriceInfo\Base" />
     <preference for="Magento\Framework\Pricing\PriceCurrencyInterface" type="Magento\Directory\Model\PriceCurrency" />
     <preference for="Magento\Framework\Pricing\Adjustment\CalculatorInterface" type="Magento\Framework\Pricing\Adjustment\Calculator" />
+    <preference for="Magento\Catalog\Service\V1\ProductTypeServiceInterface" type="Magento\Catalog\Service\V1\ProductTypeService" />
+    <preference for="Magento\Catalog\Service\V1\Product\AttributeGroup\ReadServiceInterface" type="Magento\Catalog\Service\V1\Product\AttributeGroup\ReadService" />
+    <preference for="Magento\Catalog\Service\V1\Product\AttributeGroup\WriteServiceInterface" type="Magento\Catalog\Service\V1\Product\AttributeGroup\WriteService" />
+    <preference for="Magento\Catalog\Service\V1\Product\AttributeSet\ReadServiceInterface" type="Magento\Catalog\Service\V1\Product\AttributeSet\ReadService" />
+    <preference for="Magento\Catalog\Service\V1\Product\AttributeSet\WriteServiceInterface" type="Magento\Catalog\Service\V1\Product\AttributeSet\WriteService" />
+    <preference for="Magento\Catalog\Service\V1\Product\AttributeSet\AttributeServiceInterface" type="Magento\Catalog\Service\V1\Product\AttributeSet\AttributeService" />
+    <preference for="Magento\Catalog\Service\V1\Product\Link\ReadServiceInterface" type="Magento\Catalog\Service\V1\Product\Link\ReadService" />
+    <preference for="Magento\Catalog\Service\V1\Product\Link\WriteServiceInterface" type="Magento\Catalog\Service\V1\Product\Link\WriteService" />
+    <preference for="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapperInterface" type="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapper\Composite" />
     <type name="Magento\Log\Model\Resource\Log">
         <plugin name="catalogLog" type="Magento\Catalog\Model\Plugin\Log" />
     </type>
@@ -237,9 +246,9 @@
     <type name="Magento\Catalog\Model\Product\LinkTypeProvider">
         <arguments>
             <argument name="linkTypes" xsi:type="array">
-                <item name="links_related" xsi:type="const">Magento\Catalog\Model\Product\Link::LINK_TYPE_RELATED</item>
-                <item name="links_crosssell" xsi:type="const">Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL</item>
-                <item name="links_upsell" xsi:type="const">Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL</item>
+                <item name="related" xsi:type="const">Magento\Catalog\Model\Product\Link::LINK_TYPE_RELATED</item>
+                <item name="crosssell" xsi:type="const">Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL</item>
+                <item name="upsell" xsi:type="const">Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL</item>
             </argument>
         </arguments>
     </type>
@@ -371,4 +380,20 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider">
+        <arguments>
+            <argument name="providers" xsi:type="array">
+                <item name="crosssell" xsi:type="object">Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider\Crosssell</item>
+                <item name="upsell" xsi:type="object">Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider\Upsell</item>
+                <item name="related" xsi:type="object">Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider\Related</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterPool">
+        <arguments>
+            <argument name="converters" xsi:type="array">
+                <item name="default" xsi:type="object">\Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\DefaultConverter</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Catalog/etc/webapi.xml b/app/code/Magento/Catalog/etc/webapi.xml
new file mode 100644
index 0000000000000000000000000000000000000000..480a7f47bf1c9a964bfaa9396bf717db7d6d7a03
--- /dev/null
+++ b/app/code/Magento/Catalog/etc/webapi.xml
@@ -0,0 +1,142 @@
+<?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)
+ */
+-->
+<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="../../../../../app/code/Magento/Webapi/etc/webapi.xsd">
+    <route url="/V1/products/types" method="GET">
+        <service class="Magento\Catalog\Service\V1\ProductTypeServiceInterface" method="getProductTypes"/>
+        <resources>
+            <resource ref="Magento_Catalog::products"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets" method="GET">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeSet\ReadServiceInterface" method="getList"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId" method="GET">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeSet\ReadServiceInterface" method="getInfo"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId" method="DELETE">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeSet\WriteServiceInterface" method="remove"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets" method="POST">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeSet\WriteServiceInterface" method="create"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets" method="PUT">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeSet\WriteServiceInterface" method="update"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId/attributes" method="GET">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeSet\ReadServiceInterface" method="getAttributeList"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId/attributes" method="POST">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeSet\AttributeServiceInterface" method="addAttribute"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId/attributes/:attributeId" method="DELETE">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeSet\AttributeServiceInterface" method="deleteAttribute"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId/groups" method="GET">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeGroup\ReadServiceInterface" method="getList"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId/groups" method="POST">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeGroup\WriteServiceInterface" method="create"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId/groups" method="PUT">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeGroup\WriteServiceInterface" method="update"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/attribute-sets/:attributeSetId/groups/:groupId" method="DELETE">
+        <service class="Magento\Catalog\Service\V1\Product\AttributeGroup\WriteServiceInterface" method="delete"/>
+        <resources>
+            <resource ref="Magento_Catalog::sets"/>
+        </resources>
+    </route>
+    <route url="/V1/products/links/types" method="GET">
+        <service class="Magento\Catalog\Service\V1\Product\Link\ReadServiceInterface" method="getProductLinkTypes"/>
+        <resources>
+            <resource ref="Magento_Catalog::catalog"/>
+        </resources>
+    </route>
+    <route url="/V1/products/:productSku/links/:type" method="GET">
+        <service class="Magento\Catalog\Service\V1\Product\Link\ReadServiceInterface" method="getLinkedProducts"/>
+        <resources>
+            <resource ref="Magento_Catalog::catalog"/>
+        </resources>
+    </route>
+    <route url="/V1/products/links/:type/attributes" method="GET">
+        <service class="Magento\Catalog\Service\V1\Product\Link\ReadServiceInterface" method="getLinkAttributes"/>
+        <resources>
+            <resource ref="Magento_Catalog::catalog"/>
+        </resources>
+    </route>
+    <route url="/V1/products/:productSku/links/:type" method="POST">
+        <service class="Magento\Catalog\Service\V1\Product\Link\WriteServiceInterface" method="assign"/>
+        <resources>
+            <resource ref="Magento_Catalog::catalog"/>
+        </resources>
+    </route>
+    <route url="/V1/products/:productSku/links/:type/:linkedProductSku" method="DELETE">
+        <service class="Magento\Catalog\Service\V1\Product\Link\WriteServiceInterface" method="remove"/>
+        <resources>
+            <resource ref="Magento_Catalog::catalog"/>
+        </resources>
+    </route>
+    <route url="/V1/products/:productSku/links/:type" method="PUT">
+        <service class="Magento\Catalog\Service\V1\Product\Link\WriteServiceInterface" method="update"/>
+        <resources>
+            <resource ref="Magento_Catalog::catalog"/>
+        </resources>
+    </route>
+</routes>
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml
index f118c406b4345eddc0430d211ba39e1b2d96b68b..ef4da6dd5d884dd7346c9ba087616fa3dfdd646a 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit.phtml
@@ -291,7 +291,7 @@ jQuery(function($) {
                 .removeClass('ignore-validate')
                 .removeClass(removedElementClass)
                 .each(function(i, fieldSet) {
-                $newPage.find('#product_info_tabs .fieldset').each(function(j, newFieldSet) {
+                var updateFieldsetElements = function(index, newFieldSet) {
                     if ($(fieldSet).attr('id') != $(newFieldSet).attr('id')) {
                         return
                     }
@@ -332,7 +332,21 @@ jQuery(function($) {
                         $elementToMove.removeClass(removedElementClass).removeClass('.ignore-validate');
                         $elements = $(fieldSet).find('>.field:not(.' + removedElementClass + ')');
                     });
-                });
+                };
+
+                $newPage.find('#product_info_tabs .fieldset').each(updateFieldsetElements);
+
+                fieldsetContainer = $(fieldSet).parents('[data-ui-id*=-tab-content-]').first();
+                var newFieldsetContainer = $newPage.find('[data-ui-id='+$(fieldsetContainer).data('uiId')+']');
+                if (newFieldsetContainer.length == 0) {
+                    $(fieldsetContainer).find('fieldset .field')
+                        .addClass('ignore-validate')
+                        .addClass(removedElementClass);
+                    $(fieldsetContainer).addClass(removedElementClass);
+                } else {
+                    $(newFieldsetContainer).find('fieldset').each(updateFieldsetElements);
+                    $(fieldsetContainer).removeClass(removedElementClass);
+                }
             });
             $('#product_info_tabs').tabs('refresh');
             if (!$('#' + activeTabId).closest('li').hasClass(removedElementClass)) {
diff --git a/app/code/Magento/Catalog/view/adminhtml/web/product/product.css b/app/code/Magento/Catalog/view/adminhtml/web/product/product.css
index 583795a4f7cd08ecdf659107b8c5ef592d7545db..804841ffe42de914bbf1c9adc5f136d9221d3422 100644
--- a/app/code/Magento/Catalog/view/adminhtml/web/product/product.css
+++ b/app/code/Magento/Catalog/view/adminhtml/web/product/product.css
@@ -520,6 +520,7 @@
 
 /* Change Attribute Set */
 #product_info_tabs li.removed,
+div.removed,
 .field.removed {
     display: none !important;
 }
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 5b6d8a6fbce64102dce11a9aec35701db756d165..db01776bfedfcb4d3c9a7e9c6b8ef2824b58a9fa 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
@@ -65,8 +65,7 @@
                 </arguments>
             </block>
             <block class="Magento\Catalog\Block\Product\View" name="product.info.review" template="product/view/review.phtml" after="product.info.sku"/>
-            <block class="Magento\Catalog\Block\Product\View" name="product.info.rating" template="product/view/rating.phtml" after="product.info.sku"/>
-            <block class="Magento\Catalog\Pricing\Render" name="product.price.final" after="product.info.rating">
+            <block class="Magento\Catalog\Pricing\Render" name="product.price.final" after="product.info.sku">
                 <arguments>
                     <argument name="price_render" xsi:type="string">product.price.render.default</argument>
                     <argument name="price_type_code" xsi:type="string">final_price</argument>
@@ -82,7 +81,7 @@
                     <argument name="zone" xsi:type="string">item_view</argument>
                 </arguments>
             </block>
-            <container name="alert.urls" as="alert_urls" label="Alert Urls" after="product.price"/>
+            <container name="alert.urls" as="alert_urls" label="Alert Urls" after="product.price.tier"/>
             <block class="Magento\Catalog\Block\Product\View" name="product.info" template="product/view/form.phtml">
                 <container name="product.info.form.content" label="invisible" as="product_info_form_content">
                     <block class="Magento\Catalog\Block\Product\View" name="product.info.addtocart" as="addtocart" template="product/view/addtocart.phtml"/>
diff --git a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
index e846f08a09386679ac969792f366588890539304..2df9e468fc5f180c7c5d0780f09eba2ab4aa8807 100644
--- a/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
+++ b/app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
@@ -182,8 +182,69 @@ class Stock extends \Magento\Framework\Data\Form\Element\Select
      */
     protected function _getJs($quantityFieldId, $inStockFieldId)
     {
-        // @codingStandardsIgnoreStart
-        return "\n            <script>\n                jQuery(function(\$) {\n                    var qty = \$('#{$quantityFieldId}'),\n                        productType = \$('#product_type_id').val(),\n                        stockAvailabilityField = \$('#{$inStockFieldId}'),\n                        manageStockField = \$('#inventory_manage_stock'),\n                        useConfigManageStockField = \$('#inventory_use_config_manage_stock');\n\n                    var disabler = function(event) {\n                        var stockBeforeDisable = \$.Event('stockbeforedisable', {productType: productType});\n                        \$('[data-tab-panel=product-details]').trigger(stockBeforeDisable);\n                        if (stockBeforeDisable.result !== false) {\n                            var manageStockValue = (qty.val() === '') ? 0 : 1;\n                            stockAvailabilityField.prop('disabled', !manageStockValue);\n                            if (manageStockField.val() != manageStockValue && !(event && event.type == 'keyup')) {\n                                if (useConfigManageStockField.val() == 1) {\n                                    useConfigManageStockField.removeAttr('checked').val(0);\n                                }\n                                manageStockField.toggleClass('disabled', false).prop('disabled', false);\n                                manageStockField.val(manageStockValue);\n                            }\n                        }\n                    };\n\n                    //Associated fields\n                    var fieldsAssociations = {\n                        '{$quantityFieldId}' : 'inventory_qty',\n                        '{$inStockFieldId}'  : 'inventory_stock_availability'\n                    };\n                    //Fill corresponding field\n                    var filler = function() {\n                        var id = \$(this).attr('id');\n                        if ('undefined' !== typeof fieldsAssociations[id]) {\n                            \$('#' + fieldsAssociations[id]).val(\$(this).val());\n                        } else {\n                            \$('#' + getKeyByValue(fieldsAssociations, id)).val(\$(this).val());\n                        }\n\n                        if (\$('#inventory_manage_stock').length) {\n                            fireEvent(\$('#inventory_manage_stock').get(0), 'change');\n                        }\n                    };\n                    //Get key by value from object\n                    var getKeyByValue = function(object, value) {\n                        var returnVal = false;\n                        \$.each(object, function(objKey, objValue){\n                            if (value === objValue) {\n                                returnVal = objKey;\n                            }\n                        });\n                        return returnVal;\n                    };\n                    \$.each(fieldsAssociations, function(generalTabField, advancedTabField) {\n                        \$('#' + generalTabField + ', #' + advancedTabField)\n                            .bind('focus blur change keyup click', filler)\n                            .bind('keyup change blur', disabler);\n                        filler.call(\$('#' + generalTabField));\n                        filler.call(\$('#' + advancedTabField));\n                    });\n                    disabler();\n                });\n            </script>\n        ";
-        // @codingStandardsIgnoreEnd
+        return "
+            <script type='text/javascript'>
+                jQuery(function($) {
+                    var qty = $('#{$quantityFieldId}'),
+                        productType = $('#product_type_id').val(),
+                        stockAvailabilityField = $('#{$inStockFieldId}'),
+                        manageStockField = $('#inventory_manage_stock'),
+                        useConfigManageStockField = $('#inventory_use_config_manage_stock'),
+                        fieldsAssociations = {
+                            '{$quantityFieldId}' : 'inventory_qty',
+                            '{$inStockFieldId}'  : 'inventory_stock_availability'
+                        };
+
+                    var disabler = function(event) {
+                        var stockBeforeDisable = $.Event('stockbeforedisable', {productType: productType});
+                        $('[data-tab-panel=product-details]').trigger(stockBeforeDisable);
+                        if (stockBeforeDisable.result !== false) {
+                            var manageStockValue = (qty.val() === '') ? 0 : 1;
+                            stockAvailabilityField.prop('disabled', !manageStockValue);
+                            $('#' + fieldsAssociations['{$inStockFieldId}']).prop('disabled', !manageStockValue);
+                            if (manageStockField.val() != manageStockValue && !(event && event.type == 'keyup')) {
+                                if (useConfigManageStockField.val() == 1) {
+                                    useConfigManageStockField.removeAttr('checked').val(0);
+                                }
+                                manageStockField.toggleClass('disabled', false).prop('disabled', false);
+                                manageStockField.val(manageStockValue);
+                            }
+                        }
+                    };
+
+                    //Fill corresponding field
+                    var filler = function() {
+                        var id = $(this).attr('id');
+                        if ('undefined' !== typeof fieldsAssociations[id]) {
+                            $('#' + fieldsAssociations[id]).val($(this).val());
+                        } else {
+                            $('#' + getKeyByValue(fieldsAssociations, id)).val($(this).val());
+                        }
+
+                        if (manageStockField.length) {
+                            fireEvent(manageStockField.get(0), 'change');
+                        }
+                    };
+                    //Get key by value from object
+                    var getKeyByValue = function(object, value) {
+                        var returnVal = false;
+                        $.each(object, function(objKey, objValue){
+                            if (value === objValue) {
+                                returnVal = objKey;
+                            }
+                        });
+                        return returnVal;
+                    };
+                    $.each(fieldsAssociations, function(generalTabField, advancedTabField) {
+                        $('#' + generalTabField + ', #' + advancedTabField)
+                            .bind('focus blur change keyup click', filler)
+                            .bind('keyup change blur', disabler);
+                        filler.call($('#' + generalTabField));
+                        filler.call($('#' + advancedTabField));
+                    });
+                    disabler();
+                });
+            </script>
+        ";
     }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index 3b7a81088c645d705f75ff3fbc71256e87da0330..a8be0223e6a67968ddaae23ce8c649a6af4823db 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -550,13 +550,15 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
             foreach ($data as $attributeData) {
                 /** @var $configurableAttribute \Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute */
                 $configurableAttribute = $this->_configurableAttributeFactory->create();
-                if (!empty($attributeData['id'])) {
-                    $configurableAttribute->load($attributeData['id']);
-                } else {
-                    $configurableAttribute->loadByProductAndAttribute(
-                        $product,
-                        $this->getAttributeById($attributeData['attribute_id'], $product)
-                    );
+                if (!$product->getIsDuplicate()) {
+                    if (!empty($attributeData['id'])) {
+                        $configurableAttribute->load($attributeData['id']);
+                    } else {
+                        $configurableAttribute->loadByProductAndAttribute(
+                            $product,
+                            $this->getAttributeById($attributeData['attribute_id'], $product)
+                        );
+                    }
                 }
                 unset($attributeData['id']);
                 $configurableAttribute->addData(
@@ -1159,6 +1161,10 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
 
         $postData['stock_data'] = $parentProduct->getStockData();
         $postData['stock_data']['manage_stock'] = $postData['quantity_and_stock_status']['qty'] === '' ? 0 : 1;
+        if (!isset($postData['stock_data']['is_in_stock'])) {
+            $stockStatus = $parentProduct->getQuantityAndStockStatus();
+            $postData['stock_data']['is_in_stock'] = $stockStatus['is_in_stock'];
+        }
         $configDefaultValue = $this->_scopeConfig->getValue(
             \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_MANAGE_STOCK,
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml
index 0d209003ba4fce55da6634d39d4ab0f72c91606f..4a0c3cb129201f0bde15743fd4b70be14fe51d23 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml
@@ -157,8 +157,12 @@ jQuery(function($) {
             $(this).html('');
         })
         .on('click', '[data-column=entity_id]', function() {
-            $(this).closest('tr').find('input[type!=checkbox],button')
-                .prop('disabled', !$(this).is(':checked'));
+            var entityCheckBox = $(this);
+            entityCheckBox.closest('tr').find('input[type!=checkbox],button').each(function () {
+                if (!isLocked($(this))) {
+                    $(this).prop('disabled', !entityCheckBox.is(':checked'));
+                }
+            });
         })
         .on('click', '[data-action=choose]', function(event) {
             event.preventDefault();
@@ -216,6 +220,7 @@ jQuery(function($) {
 
                     $matrixRow.find('[name=image]')
                         .attr('src', $gridRow.find('[data-role=image-url]').val())
+                        .attr('data-locked', '1')
                         .trigger('click')
                         .prop({disabled: true});
 
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml
index 31517d3f52aeaf86a196efb0c349a71abda435c1..249759260aef72f8203c5c3b9f4f62e52f9f78fb 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml
@@ -105,7 +105,7 @@ $productByUsedAttributes = $this->getAssociatedProducts();
                         <?php $image = $product->getImage(); if ($image == 'no_selection'): $image = ''; endif; ;?>
                         <div class="action-upload<?php if ($image): ?> no-display<?php endif;?>" data-action="upload-image">
                             <span><?php echo __('Upload Image'); ?></span>
-                            <input name="image" type="file" disabled="disabled"
+                            <input name="image" type="file" disabled="disabled" data-locked="1"
                                    data-url="<?php echo $this->escapeHtml($this->getImageUploadUrl()) ?>"
                                    title="<?php echo __('Upload Image'); ?>" />
                             <input id="product-<?php echo $product->getId()?>-variation-image"
diff --git a/app/code/Magento/Core/App/Router/Base.php b/app/code/Magento/Core/App/Router/Base.php
index 84f6bc74b3e1bfdc1b3d075ee20412ab9ecb1dee..54742020914e67524586a2734721636e5a836a08 100644
--- a/app/code/Magento/Core/App/Router/Base.php
+++ b/app/code/Magento/Core/App/Router/Base.php
@@ -246,7 +246,10 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
         }
 
         $controllerClassName = $this->getControllerClassName($currentModuleName, 'index');
-        if (!$controllerClassName || !method_exists($controllerClassName, 'norouteAction')) {
+        if (!$controllerClassName
+            || !method_exists($controllerClassName, 'norouteAction')
+            || !is_callable([$controllerClassName, 'norouteAction'])
+        ) {
             return null;
         }
 
@@ -294,7 +297,10 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
             $currentModuleName = $moduleName;
 
             $controllerClassName = $this->getControllerClassName($moduleName, $controller);
-            if (!$controllerClassName || false === method_exists($controllerClassName, $action . 'Action')) {
+            if (!$controllerClassName
+                || !method_exists($controllerClassName, $action . 'Action')
+                || !is_callable([$controllerClassName, $action . 'Action'])
+            ) {
                 continue;
             }
 
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Renderer/Attribute/Sendemail.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Renderer/Attribute/Sendemail.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ea74406b8f8a32971e5235295a1991cc08d10c6
--- /dev/null
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Renderer/Attribute/Sendemail.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\Block\Adminhtml\Edit\Renderer\Attribute;
+
+use Magento\Backend\Block\Widget\Form\Renderer\Fieldset\Element;
+
+/**
+ * Renderer for sendemail checkbox
+ */
+class Sendemail extends Element
+{
+    /**
+     * @var string
+     */
+    protected $_template = 'edit/tab/account/form/renderer/sendemail.phtml';
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|null
+     */
+    protected $_storeManager = null;
+
+    /**
+     * @param \Magento\Backend\Block\Template\Context $context
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Backend\Block\Template\Context $context,
+        array $data = array()
+    ) {
+        $this->_storeManager = $context->getStoreManager();
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * Check if Single Store Mode is enabled
+     *
+     * @return bool
+     */
+    public function isSingleStoreMode()
+    {
+        return $this->_storeManager->isSingleStoreMode();
+    }
+
+    /**
+     * Get form HTML ID
+     * @return string
+     */
+    public function getFormHtmlId()
+    {
+        return $this->getForm()->getHtmlIdPrefix();
+    }
+}
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Account.php b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Account.php
index af4db846c1266171c30e675cced56584c92b8944..f7ffe9e1333bd774c30b01e3259a7f6dc5e880bc 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Account.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit/Tab/Account.php
@@ -24,6 +24,7 @@
 namespace Magento\Customer\Block\Adminhtml\Edit\Tab;
 
 use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+use \Magento\Framework\Service\DataObjectConverter;
 
 /**
  * Customer account form block
@@ -73,6 +74,16 @@ class Account extends GenericMetadata
      */
     protected $_customerBuilder;
 
+    /**
+     * @var \Magento\Customer\Model\Metadata\Form
+     */
+    protected $_customerForm;
+
+    /**
+     * @var \Magento\Customer\Service\V1\Data\Customer
+     */
+    protected $_customerDataObject;
+
     /**
      * @param \Magento\Backend\Block\Template\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -126,84 +137,111 @@ class Account extends GenericMetadata
         $form->setHtmlIdPrefix('_account');
         $form->setFieldNameSuffix('account');
 
+        /** @var \Magento\Framework\Data\Form\Element\Fieldset $fieldset */
         $fieldset = $form->addFieldset('base_fieldset', array('legend' => __('Account Information')));
+        $accountData = $this->_customizeFieldset($fieldset);
 
-        $customerData = $this->_backendSession->getCustomerData();
-        $customerId = isset($customerData['customer_id']) ? $customerData['customer_id'] : false;
-        $accountData = isset($customerData['account']) ? $customerData['account'] : array();
-        $customerDataObject = $this->_customerBuilder->populateWithArray($accountData)->create();
+        $form->setValues($accountData);
+        $this->setForm($form);
+        return $this;
+    }
 
-        $customerForm = $this->_initCustomerForm($customerDataObject);
-        $attributes = $this->_initCustomerAttributes($customerForm);
+    /**
+     * Customize fieldset elements
+     *
+     * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset
+     * @return array
+     */
+    protected function _customizeFieldset($fieldset)
+    {
+        $attributes = $this->_initCustomerAttributes();
         $this->_setFieldset($attributes, $fieldset, array(self::DISABLE_ATTRIBUTE_NAME));
-
-        $form->getElement(
+        $form = $fieldset->getForm();
+        $groupElement = $form->getElement(
             'group_id'
-        )->setRenderer(
+        );
+        $groupElement->setRenderer(
             $this->getLayout()->createBlock(
                 'Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Group'
             )->setDisableAutoGroupChangeAttribute(
-                $customerForm->getAttribute(self::DISABLE_ATTRIBUTE_NAME)
+                $this->_getCustomerForm()->getAttribute(self::DISABLE_ATTRIBUTE_NAME)
             )->setDisableAutoGroupChangeAttributeValue(
-                $customerDataObject->getCustomAttribute(self::DISABLE_ATTRIBUTE_NAME) ?
-                $customerDataObject->getCustomAttribute(self::DISABLE_ATTRIBUTE_NAME)->getValue() : null
+                $this->_getCustomerDataObject()->getCustomAttribute(self::DISABLE_ATTRIBUTE_NAME) ?
+                $this->_getCustomerDataObject()->getCustomAttribute(self::DISABLE_ATTRIBUTE_NAME)->getValue() : null
             )
         );
 
-        $customerStoreId = $customerDataObject->getStoreId();
+        $this->_checkElementType('prefix', $fieldset);
+        $this->_checkElementType('suffix', $fieldset);
 
-        $prefixElement = $form->getElement('prefix');
-        if ($prefixElement) {
-            $prefixOptions = $this->_customerHelper->getNamePrefixOptions($customerStoreId);
-            if (!empty($prefixOptions)) {
-                $fieldset->removeField($prefixElement->getId());
-                $prefixField = $fieldset->addField(
-                    $prefixElement->getId(),
-                    'select',
-                    $prefixElement->getData(),
-                    $form->getElement('group_id')->getId()
-                );
-                $prefixField->setValues($prefixOptions);
-                if ($customerId) {
-                    $prefixField->addElementValues($customerDataObject->getPrefix());
-                }
-            }
+        $fieldset->getForm()->getElement('website_id')->addClass('validate-website-has-store');
+        $renderer = $this->getLayout()->createBlock(
+            'Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element'
+        );
+        $form->getElement('website_id')->setRenderer($renderer);
+
+        $accountData = DataObjectConverter::toFlatArray($this->_getCustomerDataObject());
+        if ($this->_getCustomerDataObject()->getId()) {
+            $customerFormFields = $this->_addEditCustomerFormFields($fieldset);
+        } else {
+            $customerFormFields = $this->_addNewCustomerFormFields($fieldset);
         }
 
-        $suffixElement = $form->getElement('suffix');
-        if ($suffixElement) {
-            $suffixOptions = $this->_customerHelper->getNameSuffixOptions($customerStoreId);
-            if (!empty($suffixOptions)) {
-                $fieldset->removeField($suffixElement->getId());
-                $suffixField = $fieldset->addField(
-                    $suffixElement->getId(),
+        $this->_handleReadOnlyCustomer($form, $this->_getCustomerDataObject()->getId(), $attributes);
+
+        return array_merge($customerFormFields, $accountData);
+    }
+
+    /**
+     * Check if type of Prefix and Suffix elements should be changed from text to select and change it if need.
+     *
+     * @param string $elementName
+     * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset
+     * @return null
+     */
+    protected function _checkElementType($elementName, $fieldset)
+    {
+        $possibleElements = ['prefix', 'suffix'];
+        if (!in_array($elementName, $possibleElements)) {
+            return;
+        }
+        $element = $fieldset->getForm()->getElement($elementName);
+        if ($element) {
+            if ($elementName == 'prefix') {
+                $options = $this->_customerHelper->getNamePrefixOptions($this->_getCustomerDataObject()->getStoreId());
+                $prevSibling = $fieldset->getForm()->getElement('group_id')->getId();
+            }
+            if ($elementName == 'suffix') {
+                $options = $this->_customerHelper->getNameSuffixOptions($this->_getCustomerDataObject()->getStoreId());
+                $prevSibling = $fieldset->getForm()->getElement('lastname')->getId();
+            }
+
+            if (!empty($options)) {
+                $fieldset->removeField($element->getId());
+                $elementField = $fieldset->addField(
+                    $element->getId(),
                     'select',
-                    $suffixElement->getData(),
-                    $form->getElement('lastname')->getId()
+                    $element->getData(),
+                    $prevSibling
                 );
-                $suffixField->setValues($suffixOptions);
-                if ($customerId) {
-                    $suffixField->addElementValues($customerDataObject->getSuffix());
-                }
+                $elementField->setValues($options);
             }
         }
+    }
 
-        if ($customerId) {
-            $accountData = array_merge(
-                $this->_addEditCustomerFormFields($form, $fieldset, $customerDataObject),
-                $accountData
-            );
-        } else {
-            $this->_addNewCustomerFormFields($form, $fieldset);
-            $accountData['sendemail'] = '1';
+    /**
+     * Obtain customer data from session and create customer object
+     *
+     * @return \Magento\Customer\Service\V1\Data\Customer
+     */
+    protected function _getCustomerDataObject()
+    {
+        if (is_null($this->_customerDataObject)) {
+            $customerData = $this->_backendSession->getCustomerData();
+            $accountData = isset($customerData['account']) ? $customerData['account'] : array();
+            $this->_customerDataObject = $this->_customerBuilder->populateWithArray($accountData)->create();
         }
-
-        $this->_disableSendEmailStoreForEmptyWebsite($form);
-        $this->_handleReadOnlyCustomer($form, $customerId, $attributes);
-
-        $form->setValues($accountData);
-        $this->setForm($form);
-        return $this;
+        return $this->_customerDataObject;
     }
 
     /**
@@ -223,13 +261,11 @@ class Account extends GenericMetadata
     /**
      * Initialize attribute set.
      *
-     * @param \Magento\Customer\Model\Metadata\Form $customerForm
      * @return \Magento\Customer\Service\V1\Data\Eav\AttributeMetadata[]
      */
-    protected function _initCustomerAttributes(\Magento\Customer\Model\Metadata\Form $customerForm)
+    protected function _initCustomerAttributes()
     {
-        $attributes = $customerForm->getAttributes();
-
+        $attributes = $this->_getCustomerForm()->getAttributes();
         foreach ($attributes as $key => $attribute) {
             if ($attribute->getAttributeCode() == 'created_at') {
                 unset($attributes[$key]);
@@ -241,16 +277,18 @@ class Account extends GenericMetadata
     /**
      * Initialize customer form
      *
-     * @param \Magento\Customer\Service\V1\Data\Customer $customer
      * @return \Magento\Customer\Model\Metadata\Form $customerForm
      */
-    protected function _initCustomerForm(\Magento\Customer\Service\V1\Data\Customer $customer)
+    protected function _getCustomerForm()
     {
-        return $this->_customerFormFactory->create(
-            'customer',
-            'adminhtml_customer',
-            \Magento\Framework\Service\EavDataObjectConverter::toFlatArray($customer)
-        );
+        if (is_null($this->_customerForm)) {
+            $this->_customerForm = $this->_customerFormFactory->create(
+                'customer',
+                'adminhtml_customer',
+                DataObjectConverter::toFlatArray($this->_getCustomerDataObject())
+            );
+        }
+        return $this->_customerForm;
     }
 
     /**
@@ -273,47 +311,13 @@ class Account extends GenericMetadata
         }
     }
 
-    /**
-     * Make sendemail or sendmail_store_id disabled if website_id has an empty value
-     *
-     * @param \Magento\Framework\Data\Form $form
-     * @return void
-     */
-    protected function _disableSendEmailStoreForEmptyWebsite(\Magento\Framework\Data\Form $form)
-    {
-        $sendEmailId = $this->_storeManager->isSingleStoreMode() ? 'sendemail' : 'sendemail_store_id';
-        $sendEmail = $form->getElement($sendEmailId);
-
-        $prefix = $form->getHtmlIdPrefix();
-        if ($sendEmail) {
-            $_disableStoreField = '';
-            if (!$this->_storeManager->isSingleStoreMode()) {
-                $_disableStoreField = "\$('{$prefix}sendemail_store_id').disabled=(''==this.value || '0'==this.value);";
-            }
-            $sendEmail->setAfterElementHtml(
-                '<script type="text/javascript">' .
-                "\n                document.observe('dom:loaded', function()" .
-                "{\n                    \$('{$prefix}website_id').disableSendemail = function() " .
-                "{\n                        \$('{$prefix}sendemail').disabled = ('' == this.value || " .
-                "'0' == this.value);" .
-                $_disableStoreField .
-                "\n}.bind(\$('{$prefix}website_id'));\n                    " .
-                "Event.observe('{$prefix}website_id', 'change', \$('{$prefix}website_id').disableSendemail);" .
-                "\n                    \$('{$prefix}website_id').disableSendemail();\n                });" .
-                "\n                " .
-                '</script>'
-            );
-        }
-    }
-
     /**
      * Create New Customer form fields
      *
-     * @param \Magento\Framework\Data\Form $form
      * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset
-     * @return void
+     * @return array
      */
-    protected function _addNewCustomerFormFields($form, $fieldset)
+    protected function _addNewCustomerFormFields($fieldset)
     {
         $fieldset->removeField('created_in');
 
@@ -323,39 +327,13 @@ class Account extends GenericMetadata
             'checkbox',
             array('label' => __('Send Welcome Email'), 'name' => 'sendemail', 'id' => 'sendemail')
         );
-        if (!$this->_storeManager->isSingleStoreMode()) {
-            $form->getElement('website_id')->addClass('validate-website-has-store');
-
-            $websites = array();
-            foreach ($this->_storeManager->getWebsites(true) as $website) {
-                $websites[$website->getId()] = !is_null($website->getDefaultStore());
-            }
-            $prefix = $form->getHtmlIdPrefix();
-
-            $note = __('Please select a website which contains store view');
-            $form->getElement(
-                'website_id'
-            )->setAfterElementJs(
-                '<script type="text/javascript">' .
-                "\n                var {$prefix}_websites = " .
-                $this->_jsonEncoder->encode(
-                    $websites
-                ) .
-                ";\n                jQuery.validator.addMethod('validate-website-has-store', function(v, elem)" .
-                "{\n                       return {$prefix}_websites[elem.value] == true;\n                    }," .
-                "\n                    '" .
-                $note .
-                "'\n                );\n                " .
-                "Element.observe('{$prefix}website_id', 'change', function()" .
-                "{\n                    jQuery.validator.validateElement('#{$prefix}website_id');" .
-                "\n                }.bind(\$('{$prefix}website_id')));\n                " .
-                '</script>'
-            );
-            $renderer = $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element'
-            );
-            $form->getElement('website_id')->setRenderer($renderer);
+        $renderer = $this->getLayout()->createBlock(
+            'Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Sendemail'
+        );
+        $renderer->setForm($fieldset->getForm());
+        $fieldset->getForm()->getElement('sendemail')->setRenderer($renderer);
 
+        if (!$this->_storeManager->isSingleStoreMode()) {
             $fieldset->addField(
                 'sendemail_store_id',
                 'select',
@@ -365,45 +343,36 @@ class Account extends GenericMetadata
                     'values' => $this->_systemStore->getStoreValuesForForm()
                 )
             );
-        } else {
-            $fieldset->removeField('website_id');
-            $fieldset->addField('website_id', 'hidden', array('name' => 'website_id'));
         }
+
+        return array('sendemail' => '1');
     }
 
     /**
      * Edit/View Existing Customer form fields
      *
-     * @param \Magento\Framework\Data\Form $form
      * @param \Magento\Framework\Data\Form\Element\Fieldset $fieldset
-     * @param \Magento\Customer\Service\V1\Data\Customer $customerDataObject
      * @return string[] Values to set on the form
      */
-    protected function _addEditCustomerFormFields($form, $fieldset, $customerDataObject)
+    protected function _addEditCustomerFormFields($fieldset)
     {
-        $form->getElement('created_in')->setDisabled('disabled');
-        if (!$this->_storeManager->isSingleStoreMode()) {
-            $form->getElement('website_id')->setDisabled('disabled');
-            $renderer = $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element'
-            );
-            $form->getElement('website_id')->setRenderer($renderer);
-        } else {
-            $fieldset->removeField('website_id');
-        }
-
-        if ($customerDataObject->getId() && !$this->_customerAccountService->canModify($customerDataObject->getId())) {
+        $fieldset->getForm()->getElement('created_in')->setDisabled('disabled');
+        $fieldset->getForm()->getElement('website_id')->setDisabled('disabled');
+        $customerData = $this->_getCustomerDataObject();
+        if ($customerData->getId() &&
+            !$this->_customerAccountService->canModify($customerData->getId())
+        ) {
             return array();
         }
 
 
         // Prepare customer confirmation control (only for existing customers)
-        $confirmationStatus = $this->_customerAccountService->getConfirmationStatus($customerDataObject->getId());
-        $confirmationKey = $customerDataObject->getConfirmation();
+        $confirmationStatus = $this->_customerAccountService->getConfirmationStatus($customerData->getId());
+        $confirmationKey = $customerData->getConfirmation();
         if ($confirmationStatus != CustomerAccountServiceInterface::ACCOUNT_CONFIRMED) {
             $confirmationAttr = $this->_customerMetadataService->getCustomerAttributeMetadata('confirmation');
             if (!$confirmationKey) {
-                $confirmationKey = $this->getRandomConfirmationKey();
+                $confirmationKey = $this->_getRandomConfirmationKey();
             }
 
             $element = $fieldset->addField(
@@ -416,7 +385,7 @@ class Account extends GenericMetadata
 
             // Prepare send welcome email checkbox if customer is not confirmed
             // no need to add it, if website ID is empty
-            if ($customerDataObject->getConfirmation() && $customerDataObject->getWebsiteId()) {
+            if ($customerData->getConfirmation() && $customerData->getWebsiteId()) {
                 $fieldset->addField(
                     'sendemail',
                     'checkbox',
diff --git a/app/code/Magento/Customer/Service/V1/Data/AddressBuilder.php b/app/code/Magento/Customer/Service/V1/Data/AddressBuilder.php
index e6258b1c96a8cac603bf39f58b4ccf081dec5a57..126fc2ec40caf071313e8926792f52312f08515a 100644
--- a/app/code/Magento/Customer/Service/V1/Data/AddressBuilder.php
+++ b/app/code/Magento/Customer/Service/V1/Data/AddressBuilder.php
@@ -48,18 +48,18 @@ class AddressBuilder extends AbstractObjectBuilder
     protected $_metadataService;
 
     /**
-     * Initialize dependencies.
-     *
+     * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory
      * @param AttributeValueBuilder $valueBuilder
      * @param RegionBuilder $regionBuilder
      * @param CustomerMetadataServiceInterface $metadataService
      */
     public function __construct(
+        \Magento\Framework\Service\Data\ObjectFactory $objectFactory,
         AttributeValueBuilder $valueBuilder,
         RegionBuilder $regionBuilder,
         CustomerMetadataServiceInterface $metadataService
     ) {
-        parent::__construct($valueBuilder);
+        parent::__construct($objectFactory, $valueBuilder);
         $this->_metadataService = $metadataService;
         $this->_regionBuilder = $regionBuilder;
         $this->_data[Address::KEY_REGION] = $regionBuilder->create();
diff --git a/app/code/Magento/Customer/Service/V1/Data/CustomerBuilder.php b/app/code/Magento/Customer/Service/V1/Data/CustomerBuilder.php
index 99e2edd8e71875610e9302e388b8a1a88116e20e..ffc2549adf8fc7e16e26299c3e979819f9a6336e 100644
--- a/app/code/Magento/Customer/Service/V1/Data/CustomerBuilder.php
+++ b/app/code/Magento/Customer/Service/V1/Data/CustomerBuilder.php
@@ -43,16 +43,16 @@ class CustomerBuilder extends AbstractObjectBuilder
     protected $_metadataService;
 
     /**
-     * Initialize dependencies.
-     *
+     * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory
      * @param AttributeValueBuilder $valueBuilder
      * @param CustomerMetadataServiceInterface $metadataService
      */
     public function __construct(
+        \Magento\Framework\Service\Data\ObjectFactory $objectFactory,
         AttributeValueBuilder $valueBuilder,
         CustomerMetadataServiceInterface $metadataService
     ) {
-        parent::__construct($valueBuilder);
+        parent::__construct($objectFactory, $valueBuilder);
         $this->_metadataService = $metadataService;
     }
 
diff --git a/app/code/Magento/Customer/Service/V1/Data/CustomerDetailsBuilder.php b/app/code/Magento/Customer/Service/V1/Data/CustomerDetailsBuilder.php
index 83125377c90ed4daf709fe7bae5b3c4588ffb2be..36db9eccb176335e9b8c6aeaa63e937ad5bb4efa 100644
--- a/app/code/Magento/Customer/Service/V1/Data/CustomerDetailsBuilder.php
+++ b/app/code/Magento/Customer/Service/V1/Data/CustomerDetailsBuilder.php
@@ -47,16 +47,16 @@ class CustomerDetailsBuilder extends AbstractObjectBuilder
     protected $_addressBuilder;
 
     /**
-     * Constructor
-     *
-     * @param \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder
-     * @param \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder
+     * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory
+     * @param CustomerBuilder $customerBuilder
+     * @param AddressBuilder $addressBuilder
      */
     public function __construct(
+        \Magento\Framework\Service\Data\ObjectFactory $objectFactory,
         \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder,
         \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder
     ) {
-        parent::__construct();
+        parent::__construct($objectFactory);
         $this->_customerBuilder = $customerBuilder;
         $this->_addressBuilder = $addressBuilder;
     }
diff --git a/app/code/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataBuilder.php b/app/code/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataBuilder.php
index 99581be76ee5f1221363c110fc57e73880c2e657..e45d018fad67e1472c3c6a095dbab85c0343f1a9 100644
--- a/app/code/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataBuilder.php
+++ b/app/code/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataBuilder.php
@@ -43,16 +43,16 @@ class AttributeMetadataBuilder extends \Magento\Framework\Service\Data\AbstractO
     protected $_validationRuleBuilder;
 
     /**
-     * Initializes builder.
-     *
-     * @param \Magento\Customer\Service\V1\Data\Eav\OptionBuilder $optionBuilder
-     * @param \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder $validationRuleBuilder
+     * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory
+     * @param OptionBuilder $optionBuilder
+     * @param ValidationRuleBuilder $validationRuleBuilder
      */
     public function __construct(
+        \Magento\Framework\Service\Data\ObjectFactory $objectFactory,
         \Magento\Customer\Service\V1\Data\Eav\OptionBuilder $optionBuilder,
         \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder $validationRuleBuilder
     ) {
-        parent::__construct();
+        parent::__construct($objectFactory);
         $this->_optionBuilder = $optionBuilder;
         $this->_validationRuleBuilder = $validationRuleBuilder;
         $this->_data[AttributeMetadata::OPTIONS] = array();
diff --git a/app/code/Magento/Customer/view/adminhtml/templates/edit/tab/account/form/renderer/sendemail.phtml b/app/code/Magento/Customer/view/adminhtml/templates/edit/tab/account/form/renderer/sendemail.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..c3982a964baf63667e3bd174bf93cdfa6d0ac0c8
--- /dev/null
+++ b/app/code/Magento/Customer/view/adminhtml/templates/edit/tab/account/form/renderer/sendemail.phtml
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+?>
+<?php
+/** @var \Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Sendemail $this */
+$element = $this->getElement();
+?>
+
+<div class="field field-<?php echo $element->getId() ?>">
+    <?php echo $element->getLabelHtml(); ?>
+    <div class="control">
+        <?php echo $element->getElementHtml(); ?>
+    </div>
+</div>
+
+<script type="text/javascript">
+    document.observe('dom:loaded', function() {
+        $('<?php echo $this->getFormHtmlId() ?>website_id').disableSendemail = function() {
+            $('<?php echo $this->getFormHtmlId() ?>sendemail').disabled = ('' == this.value || '0' == this.value);
+        <?php if(!$this->isSingleStoreMode()): ?>
+            $('<?php echo $this->getFormHtmlId() ?>sendemail_store_id').disabled=(''==this.value || '0'==this.value);
+        <?php endif; ?>
+        }.bind($('<?php echo $this->getFormHtmlId() ?>website_id'));
+        Event.observe(
+            '<?php echo $this->getFormHtmlId() ?>website_id',
+            'change',
+            $('<?php echo $this->getFormHtmlId() ?>website_id').disableSendemail
+        );
+        $('<?php echo $this->getFormHtmlId() ?>website_id').disableSendemail();
+    });
+</script>
diff --git a/app/code/Magento/DesignEditor/Model/Url/NavigationMode.php b/app/code/Magento/DesignEditor/Model/Url/NavigationMode.php
index 048f556e091547d3923cfab1531306e929ccbe8f..2555754fdfb84fd1e86ee46520913e7410d43aed 100644
--- a/app/code/Magento/DesignEditor/Model/Url/NavigationMode.php
+++ b/app/code/Magento/DesignEditor/Model/Url/NavigationMode.php
@@ -58,9 +58,9 @@ class NavigationMode extends \Magento\Framework\Url
      * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
      * @param \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver
      * @param \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver
-     * @param \Magento\DesignEditor\Helper\Data $helper
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param string $scopeType
+     * @param \Magento\DesignEditor\Helper\Data $helper
      * @param array $data
      */
     public function __construct(
@@ -72,9 +72,9 @@ class NavigationMode extends \Magento\Framework\Url
         \Magento\Framework\Session\SidResolverInterface $sidResolver,
         \Magento\Framework\Url\RouteParamsResolverFactory $routeParamsResolver,
         \Magento\Framework\Url\QueryParamsResolverInterface $queryParamsResolver,
-        \Magento\DesignEditor\Helper\Data $helper,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         $scopeType,
+        \Magento\DesignEditor\Helper\Data $helper,
         array $data = array()
     ) {
         $this->_helper = $helper;
diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
index f3337ae5bf533f4be6469e42e976be7ef6a7c218..11ea1a7832db51028504ad60d2c5c77f477c2d29 100644
--- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
+++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php
@@ -781,7 +781,7 @@ abstract class AbstractEntity extends \Magento\Framework\Model\Resource\Abstract
      */
     protected function _isCallableAttributeInstance($instance, $method, $args)
     {
-        if (!is_object($instance) || !method_exists($instance, $method)) {
+        if (!is_object($instance) || !method_exists($instance, $method) || !is_callable([$instance, $method])) {
             return false;
         }
 
diff --git a/app/code/Magento/Eav/Model/Validator/Attribute/Backend.php b/app/code/Magento/Eav/Model/Validator/Attribute/Backend.php
index 065fbcf673ccf6a7011361b1130f2a07635bd9a5..8a15b7f0b42fc04daf978770237f53c306485b64 100644
--- a/app/code/Magento/Eav/Model/Validator/Attribute/Backend.php
+++ b/app/code/Magento/Eav/Model/Validator/Attribute/Backend.php
@@ -55,7 +55,7 @@ class Backend extends \Magento\Framework\Validator\AbstractValidator
         /** @var \Magento\Eav\Model\Entity\Attribute $attribute */
         foreach ($attributes as $attribute) {
             $backend = $attribute->getBackend();
-            if (!method_exists($backend, 'validate')) {
+            if (!method_exists($backend, 'validate') || !is_callable([$backend, 'validate'])) {
                 continue;
             }
             try {
diff --git a/app/code/Magento/Email/Model/Template/Filter.php b/app/code/Magento/Email/Model/Template/Filter.php
index 9a183ff687bed88506ff46b69eabc143702ab894..f9ad16c0141e3a8003de44e87c5a4bc2ad991c9d 100644
--- a/app/code/Magento/Email/Model/Template/Filter.php
+++ b/app/code/Magento/Email/Model/Template/Filter.php
@@ -273,7 +273,11 @@ class Filter extends \Magento\Framework\Filter\Template
         if (isset($blockParameters['output'])) {
             $method = $blockParameters['output'];
         }
-        if (!isset($method) || !is_string($method) || !method_exists($block, $method)) {
+        if (!isset($method)
+            || !is_string($method)
+            || !method_exists($block, $method)
+            || !is_callable([$block, $method])
+        ) {
             $method = 'toHtml';
         }
         return $block->{$method}();
diff --git a/app/code/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php b/app/code/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php
new file mode 100644
index 0000000000000000000000000000000000000000..3baa7a795bb8c51520bc2cdea0e78362a13ed9ae
--- /dev/null
+++ b/app/code/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.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\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin;
+
+class Grouped
+{
+    /**
+     * Initialize grouped product links
+     *
+     * @param \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $subject
+     * @param \Magento\Catalog\Model\Product $product
+     * @param array $links
+     *
+     * @return \Magento\Catalog\Model\Product
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function beforeInitializeLinks(
+        \Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $subject,
+        \Magento\Catalog\Model\Product $product,
+        array $links
+    ) {
+        if (isset($links['associated']) && !$product->getGroupedReadonly()) {
+            $product->setGroupedLinkData((array)$links['associated']);
+        }
+    }
+}
diff --git a/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Grouped.php b/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Grouped.php
new file mode 100644
index 0000000000000000000000000000000000000000..4979b68474b14232a55d67e61a88410ebb674c8f
--- /dev/null
+++ b/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/Grouped.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\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\CollectionProvider;
+
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProviderInterface;
+
+class Grouped implements CollectionProviderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getLinkedProducts(\Magento\Catalog\Model\Product $product)
+    {
+        return $product->getTypeInstance()->getAssociatedProducts($product);
+    }
+}
diff --git a/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/DataMapper/GroupedProduct.php b/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/DataMapper/GroupedProduct.php
new file mode 100644
index 0000000000000000000000000000000000000000..9417a61c230f7232ba7c754016c62b7a9ce26599
--- /dev/null
+++ b/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/DataMapper/GroupedProduct.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\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\DataMapper;
+
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapperInterface;
+
+class GroupedProduct implements DataMapperInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function map(array $data)
+    {
+        foreach ($data as &$item) {
+            if (isset($item['custom_attributes']['qty']['value'])) {
+                $item['qty'] = $item['custom_attributes']['qty']['value'];
+            }
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/ProductEntity/Converter.php b/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/ProductEntity/Converter.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a5e22e7a2414fe1e708dee22862a1d7ef1b81ed
--- /dev/null
+++ b/app/code/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/ProductEntity/Converter.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\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\ProductEntity;
+
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+use \Magento\Framework\Service\Data\Eav\AttributeValue;
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterInterface;
+
+class Converter implements ConverterInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function convert(\Magento\Catalog\Model\Product $product)
+    {
+        return [
+            ProductLink::TYPE => $product->getTypeId(),
+            ProductLink::SKU => $product->getSku(),
+            ProductLink::POSITION => $product->getPosition(),
+            ProductLink::CUSTOM_ATTRIBUTES_KEY => [
+                [AttributeValue::ATTRIBUTE_CODE => 'qty', AttributeValue::VALUE => $product->getQty()],
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/GroupedProduct/etc/adminhtml/di.xml b/app/code/Magento/GroupedProduct/etc/adminhtml/di.xml
index dbc58b6bf1e901659b28e745506904bad8288e0c..0c7439cae967a5db24dcda2248bc09f5df875bbc 100644
--- a/app/code/Magento/GroupedProduct/etc/adminhtml/di.xml
+++ b/app/code/Magento/GroupedProduct/etc/adminhtml/di.xml
@@ -25,9 +25,6 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
     <preference for="Magento\GroupedProduct\Model\Product\Type\Grouped" type="Magento\GroupedProduct\Model\Product\Type\Grouped\Backend" />
-    <type name="Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks">
-        <plugin name="GroupedProduct" type="Magento\GroupedProduct\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks\Plugin\Grouped" />
-    </type>
     <type name="Magento\Sales\Block\Adminhtml\Order\Create\Sidebar\AbstractSidebar">
         <plugin name="GroupedProduct" type="Magento\GroupedProduct\Block\Adminhtml\Order\Create\Sidebar" sortOrder="100"/>
     </type>
diff --git a/app/code/Magento/GroupedProduct/etc/di.xml b/app/code/Magento/GroupedProduct/etc/di.xml
index f708f1943bfaae9454b530be97c87f1b90ba5d0c..a10ad5a509daa7183894077e7ed14141e0537b37 100644
--- a/app/code/Magento/GroupedProduct/etc/di.xml
+++ b/app/code/Magento/GroupedProduct/etc/di.xml
@@ -91,4 +91,35 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider">
+        <arguments>
+            <argument name="providers" xsi:type="array">
+                <item name="associated" xsi:type="object">Magento\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\CollectionProvider\Grouped</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks">
+        <plugin name="GroupedProduct" type="Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin\Grouped" />
+    </type>
+    <type name="Magento\Catalog\Service\V1\Product\Link\Data\ProductLinkBuilder">
+        <arguments>
+            <argument name="customAttributesCodes" xsi:type="array">
+                <item name="grouped" xsi:type="string">qty</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapper\Composite">
+        <arguments>
+            <argument name="mappers" xsi:type="array">
+                <item name="grouped" xsi:type="object">\Magento\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\DataMapper\GroupedProduct</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterPool">
+        <arguments>
+            <argument name="converters" xsi:type="array">
+                <item name="associated" xsi:type="object">\Magento\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\ProductEntity\Converter</item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/templates/product/grouped/list.phtml b/app/code/Magento/GroupedProduct/view/adminhtml/templates/product/grouped/list.phtml
index dd55b34c8552cae1327d6f0017bb676133f7fcd2..dd402007256ea786f3a3c080df2e5fbc4009effd 100644
--- a/app/code/Magento/GroupedProduct/view/adminhtml/templates/product/grouped/list.phtml
+++ b/app/code/Magento/GroupedProduct/view/adminhtml/templates/product/grouped/list.phtml
@@ -27,8 +27,8 @@
 <tr title="#" class="pointer" data-role="row">
     <td data-column="info" class="col-draggable col-info">
         <span class="draggable-handle"></span>
-        <input type="hidden" name="links[grouped][${id}][id]" value="${id}" data-role="id" />
-        <input type="hidden" name="links[grouped][${id}][position]" value="${position}" data-role="position" />
+        <input type="hidden" name="links[associated][${id}][id]" value="${id}" data-role="id" />
+        <input type="hidden" name="links[associated][${id}][position]" value="${position}" data-role="position" />
     </td>
     <td data-column="name" class="editable col-name">
         ${name}
@@ -40,7 +40,7 @@
         ${price}
     </td>
     <td data-column="qty" class="editable col-qty col-number">
-        <input type="text" class="input-text " name="links[grouped][${id}][qty]" value="${qty}">
+        <input type="text" class="input-text " name="links[associated][${id}][qty]" value="${qty}">
     </td>
     <td data-column="actions" class="col-actions">
         <button type="button" class="action- delete" data-role="delete"></button>
diff --git a/app/code/Magento/ImportExport/Model/Export/Entity/Product.php b/app/code/Magento/ImportExport/Model/Export/Entity/Product.php
index dfe75b41ffd01e94a5c82fe9ca2f8eeab276d64a..e42ee802051ee100ddf1c3bdcf69a41d9bda7605 100644
--- a/app/code/Magento/ImportExport/Model/Export/Entity/Product.php
+++ b/app/code/Magento/ImportExport/Model/Export/Entity/Product.php
@@ -651,12 +651,12 @@ class Product extends \Magento\ImportExport\Model\Export\Entity\AbstractEntity
                 reset($stockItemRows) ? array_keys(end($stockItemRows)) : array(),
                 array(),
                 array(
-                    '_links_related_sku',
-                    '_links_related_position',
-                    '_links_crosssell_sku',
-                    '_links_crosssell_position',
-                    '_links_upsell_sku',
-                    '_links_upsell_position',
+                    '_related_sku',
+                    '_related_position',
+                    '_crosssell_sku',
+                    '_crosssell_position',
+                    '_upsell_sku',
+                    '_upsell_position',
                     '_associated_sku',
                     '_associated_default_qty',
                     '_associated_position'
diff --git a/app/code/Magento/ImportExport/Model/Import.php b/app/code/Magento/ImportExport/Model/Import.php
index 0d9c373b440294e34c40fc0f9f9922164de9ded9..9e2c52e67602170a3d86f9fda01a615f8314979b 100644
--- a/app/code/Magento/ImportExport/Model/Import.php
+++ b/app/code/Magento/ImportExport/Model/Import.php
@@ -489,9 +489,9 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
             'meta_title' => 'last',
             'meta_keyword' => 'last',
             'meta_description' => 'last',
-            '_links_related_sku' => 'last',
-            '_links_crosssell_sku' => 'last',
-            '_links_upsell_sku' => 'last',
+            '_related_sku' => 'last',
+            '_crosssell_sku' => 'last',
+            '_upsell_sku' => 'last',
             '_custom_option_sku' => 'middle',
             '_custom_option_row_sku' => 'middle',
             '_super_products_sku' => 'last',
diff --git a/app/code/Magento/ImportExport/Model/Import/Entity/Product.php b/app/code/Magento/ImportExport/Model/Import/Entity/Product.php
index 06e176661e99e5cf0e29700cf6b37a194e20037b..41d7fb2ba0129c13f855c65903a903dd91c52b49 100644
--- a/app/code/Magento/ImportExport/Model/Import/Entity/Product.php
+++ b/app/code/Magento/ImportExport/Model/Import/Entity/Product.php
@@ -178,9 +178,9 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
      * @var array
      */
     protected $_linkNameToId = array(
-        '_links_related_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_RELATED,
-        '_links_crosssell_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL,
-        '_links_upsell_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL
+        '_related_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_RELATED,
+        '_crosssell_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_CROSSSELL,
+        '_upsell_' => \Magento\Catalog\Model\Product\Link::LINK_TYPE_UPSELL
     );
 
     /**
@@ -258,15 +258,15 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         '_tier_price_customer_group',
         '_tier_price_qty',
         '_tier_price_price',
-        '_links_related_sku',
+        '_related_sku',
         '_group_price_website',
         '_group_price_customer_group',
         '_group_price_price',
-        '_links_related_position',
-        '_links_crosssell_sku',
-        '_links_crosssell_position',
-        '_links_upsell_sku',
-        '_links_upsell_position',
+        '_related_position',
+        '_crosssell_sku',
+        '_crosssell_position',
+        '_upsell_sku',
+        '_upsell_position',
         '_custom_option_store',
         '_custom_option_type',
         '_custom_option_title',
diff --git a/app/code/Magento/ImportExport/Model/Import/Uploader.php b/app/code/Magento/ImportExport/Model/Import/Uploader.php
index 6b5eca673a1e081bb46358b49a67aaea9c05361b..e7ce134a3cd965fec267a71cf04fe8394cacf031 100644
--- a/app/code/Magento/ImportExport/Model/Import/Uploader.php
+++ b/app/code/Magento/ImportExport/Model/Import/Uploader.php
@@ -175,7 +175,10 @@ class Uploader extends \Magento\Core\Model\File\Uploader
         }
         //run validate callbacks
         foreach ($this->_validateCallbacks as $params) {
-            if (is_object($params['object']) && method_exists($params['object'], $params['method'])) {
+            if (is_object($params['object'])
+                && method_exists($params['object'], $params['method'])
+                && is_callable([$params['object'], $params['method']])
+            ) {
                 $params['object']->{$params['method']}($filePath);
             }
         }
diff --git a/app/code/Magento/Index/Model/Indexer/AbstractIndexer.php b/app/code/Magento/Index/Model/Indexer/AbstractIndexer.php
index 9011de56e6ce4fb4ce55fa7850e0ca663bf0e816..e3156dca525b70fa293f624ec6d760d63471f0ad 100644
--- a/app/code/Magento/Index/Model/Indexer/AbstractIndexer.php
+++ b/app/code/Magento/Index/Model/Indexer/AbstractIndexer.php
@@ -147,7 +147,7 @@ abstract class AbstractIndexer extends \Magento\Framework\Model\AbstractModel im
     }
 
     /**
-     * Try dynamicly detect and call event hanler from resource model.
+     * Try dynamicly detect and call event handler from resource model.
      * Handler name will be generated from event entity and type code
      *
      * @param   Event $event
diff --git a/app/code/Magento/Index/Model/Resource/Setup.php b/app/code/Magento/Index/Model/Resource/Setup.php
index 0c858883b69d85077ebb29f4ffeb209a7d493b99..f752418b17e7648954142beb689543cb08cf1b26 100644
--- a/app/code/Magento/Index/Model/Resource/Setup.php
+++ b/app/code/Magento/Index/Model/Resource/Setup.php
@@ -98,7 +98,7 @@ class Setup extends \Magento\Framework\Module\Setup
                     'status' => \Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX
                 );
             }
-            if (method_exists($connection, 'insertArray')) {
+            if (method_exists($connection, 'insertArray') && is_callable([$connection, 'insertArray'])) {
                 $connection->insertArray($table, array('indexer_code', 'status'), $insertData);
             }
         }
diff --git a/app/code/Magento/OfflinePayments/Block/Info/Ccsave.php b/app/code/Magento/OfflinePayments/Block/Info/Ccsave.php
deleted file mode 100644
index 2247bddf5301b8f335cf4d9f72a3a16479a63e22..0000000000000000000000000000000000000000
--- a/app/code/Magento/OfflinePayments/Block/Info/Ccsave.php
+++ /dev/null
@@ -1,59 +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\OfflinePayments\Block\Info;
-
-class Ccsave extends \Magento\Payment\Block\Info\Cc
-{
-    /**
-     * Show name on card, expiration date and full cc number
-     *
-     * Expiration date and full number will show up only in secure mode (only for admin, not in emails or pdfs)
-     *
-     * @param \Magento\Framework\Object|array $transport
-     * @return \Magento\Framework\Object
-     */
-    protected function _prepareSpecificInformation($transport = null)
-    {
-        if (null !== $this->_paymentSpecificInformation) {
-            return $this->_paymentSpecificInformation;
-        }
-        $info = $this->getInfo();
-        $transport = new \Magento\Framework\Object(array((string)__('Name on the Card') => $info->getCcOwner()));
-        $transport = parent::_prepareSpecificInformation($transport);
-        if (!$this->getIsSecureMode()) {
-            $transport->addData(
-                array(
-                    (string)__(
-                        'Expiration Date'
-                    ) => $this->_formatCardDate(
-                        $info->getCcExpYear(),
-                        $this->getCcExpMonth()
-                    ),
-                    (string)__('Credit Card Number') => $info->getCcNumber()
-                )
-            );
-        }
-        return $transport;
-    }
-}
diff --git a/app/code/Magento/OfflinePayments/etc/adminhtml/system.xml b/app/code/Magento/OfflinePayments/etc/adminhtml/system.xml
index f377052c10897c42c6c03e8594ef1389816776ec..8c8b26642800b1da9b0c232294878dcfba3f6408 100644
--- a/app/code/Magento/OfflinePayments/etc/adminhtml/system.xml
+++ b/app/code/Magento/OfflinePayments/etc/adminhtml/system.xml
@@ -26,70 +26,6 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Backend/etc/system_file.xsd">
     <system>
         <section id="payment" translate="label" type="text" sortOrder="400" showInDefault="1" showInWebsite="1" showInStore="1">
-            <group id="ccsave" translate="label" type="text" sortOrder="27" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>Saved CC</label>
-                <field id="active" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Enabled</label>
-                    <comment>Enabling this method will store credit card information in the database, which may increase your security or compliance requirements.</comment>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                </field>
-                <field id="cctypes" translate="label" type="multiselect" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Credit Card Types</label>
-                    <source_model>Magento\Payment\Model\Config\Source\Cctype</source_model>
-                    <can_be_empty>1</can_be_empty>
-                </field>
-                <field id="order_status" translate="label" type="select" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>New Order Status</label>
-                    <source_model>Magento\Sales\Model\Config\Source\Order\Status\NewStatus</source_model>
-                </field>
-                <field id="sort_order" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Sort Order</label>
-                    <frontend_class>validate-number</frontend_class>
-                </field>
-                <field id="title" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
-                    <label>Title</label>
-                </field>
-                <field id="useccv" translate="label" type="select" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Request Card Security Code</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                </field>
-                <field id="centinel" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>3D Secure Card Validation</label>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                </field>
-                <field id="centinel_is_mode_strict" translate="label comment" type="select" sortOrder="25" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Severe 3D Secure Card Validation</label>
-                    <comment>Severe validation removes chargeback liability on merchant.</comment>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                    <depends>
-                        <field id="centinel">1</field>
-                    </depends>
-                </field>
-                <field id="centinel_api_url" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Centinel API URL</label>
-                    <comment>A value is required for live mode. Refer to your CardinalCommerce agreement.</comment>
-                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                    <depends>
-                        <field id="centinel">1</field>
-                    </depends>
-                </field>
-                <field id="allowspecific" translate="label" type="allowspecific" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Payment from Applicable Countries</label>
-                    <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
-                </field>
-                <field id="specificcountry" translate="label" type="multiselect" sortOrder="51" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Payment from Specific Countries</label>
-                    <source_model>Magento\Directory\Model\Config\Source\Country</source_model>
-                    <can_be_empty>1</can_be_empty>
-                </field>
-                <field id="min_order_total" translate="label" type="text" sortOrder="98" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Minimum Order Total</label>
-                </field>
-                <field id="max_order_total" translate="label" type="text" sortOrder="99" showInDefault="1" showInWebsite="1" showInStore="0">
-                    <label>Maximum Order Total</label>
-                </field>
-                <field id="model"></field>
-            </group>
             <group id="checkmo" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
                 <label>Check / Money Order</label>
                 <field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="0">
diff --git a/app/code/Magento/OfflinePayments/etc/config.xml b/app/code/Magento/OfflinePayments/etc/config.xml
index 4bddc0ad7c37042bb3df56e8b6775bf77036352d..1075acf376dde64728f354bdf351d7c92715a9ab 100644
--- a/app/code/Magento/OfflinePayments/etc/config.xml
+++ b/app/code/Magento/OfflinePayments/etc/config.xml
@@ -26,15 +26,6 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Core/etc/config.xsd">
     <default>
         <payment>
-            <ccsave>
-                <active>0</active>
-                <cctypes>AE,VI,MC,DI</cctypes>
-                <model>Magento\OfflinePayments\Model\Ccsave</model>
-                <order_status>pending</order_status>
-                <title>Credit Card (saved)</title>
-                <allowspecific>0</allowspecific>
-                <group>offline</group>
-            </ccsave>
             <checkmo>
                 <active>1</active>
                 <model>Magento\OfflinePayments\Model\Checkmo</model>
diff --git a/app/code/Magento/OfflinePayments/etc/module.xml b/app/code/Magento/OfflinePayments/etc/module.xml
index 6e1c51754de2cbb6d93e1e1c5bd2730878c005d9..cecfda746ac1be710087a32d88de7b1f3a585e99 100644
--- a/app/code/Magento/OfflinePayments/etc/module.xml
+++ b/app/code/Magento/OfflinePayments/etc/module.xml
@@ -32,7 +32,6 @@
         </sequence>
         <depends>
             <module name="Magento_Payment"/>
-            <module name="Magento_Checkout"/>
         </depends>
     </module>
 </config>
diff --git a/app/code/Magento/OfflinePayments/etc/payment.xml b/app/code/Magento/OfflinePayments/etc/payment.xml
index 642e8e8f9637fa0807d51a5f928333f7fc8b175b..cbd2c76df8928f32e0dfb5ed380e97c0446bc600 100644
--- a/app/code/Magento/OfflinePayments/etc/payment.xml
+++ b/app/code/Magento/OfflinePayments/etc/payment.xml
@@ -39,10 +39,6 @@
             <allow_multiple_address>1</allow_multiple_address>
             <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure>
         </method>
-        <method name="ccsave">
-            <allow_multiple_address>1</allow_multiple_address>
-            <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure>
-        </method>
         <method name="checkmo">
             <allow_multiple_address>1</allow_multiple_address>
             <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure>
diff --git a/app/code/Magento/OfflinePayments/view/adminhtml/templates/form/ccsave.phtml b/app/code/Magento/OfflinePayments/view/adminhtml/templates/form/ccsave.phtml
deleted file mode 100644
index ad7b26916558a159f8521cb01eca95c2363e1156..0000000000000000000000000000000000000000
--- a/app/code/Magento/OfflinePayments/view/adminhtml/templates/form/ccsave.phtml
+++ /dev/null
@@ -1,128 +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 $_code=$this->getMethodCode() ?>
-<fieldset class="fieldset payment method" id="payment_form_<?php echo $_code ?>" style="display:none">
-    <div class="field field-name required">
-        <label class="label" for="<?php echo $_code ?>_cc_owner"><span><?php echo __('Name on Card') ?></span></label>
-        <div class="control">
-            <input type="text" title="<?php echo __('Name on Card') ?>" class="required-entry input-text" id="<?php echo $_code ?>_cc_owner" name="payment[cc_owner]" value="<?php echo $this->getInfoData('cc_owner') ?>"/>
-        </div>
-    </div>
-
-    <div class="field field-type required">
-        <label class="label" for="<?php echo $_code ?>_cc_type"><span><?php echo __('Credit Card Type') ?></span></label>
-        <div class="control">
-            <select id="<?php echo $_code ?>_cc_type" name="payment[cc_type]" class="required-entry validate-cc-type-select">
-                <?php $_ccType = $this->getInfoData('cc_type') ?>
-                <option value=""></option>
-                <?php foreach ($this->getCcAvailableTypes() as $_typeCode => $_typeName): ?>
-                    <option value="<?php echo $_typeCode ?>" <?php if($_typeCode==$_ccType): ?>selected="selected"<?php endif ?>><?php echo $_typeName ?></option>
-                <?php endforeach ?>
-            </select>
-        </div>
-    </div>
-
-    <div class="field field-number required">
-        <label class="label" for="<?php echo $_code ?>_cc_number"><span><?php echo __('Credit Card Number') ?></span></label>
-        <div class="control">
-            <input type="text" id="<?php echo $_code ?>_cc_number" name="payment[cc_number]" title="<?php echo __('Credit Card Number') ?>" class="input-text validate-cc-number" value="<?php echo $this->getInfoData('cc_number')?>"/>
-        </div>
-    </div>
-
-    <div class="field field-date required">
-        <label class="label" for="<?php echo $_code ?>_expiration"><span><?php echo __('Expiration Date') ?></span></label>
-        <div class="control">
-            <select id="<?php echo $_code ?>_expiration" style="width:140px;" name="payment[cc_exp_month]" class="validate-cc-exp required-entry">
-                <?php $_ccExpMonth = $this->getInfoData('cc_exp_month') ?>
-                <?php foreach ($this->getCcMonths() as $k=>$v): ?>
-                    <option value="<?php echo $k ?>" <?php if($k==$_ccExpMonth): ?>selected="selected"<?php endif ?>><?php echo $v ?></option>
-                <?php endforeach ?>
-            </select>
-            <?php $_ccExpYear = $this->getInfoData('cc_exp_year') ?>
-            <select id="<?php echo $_code ?>_expiration_yr" style="width:103px;" name="payment[cc_exp_year]" class="required-entry">
-                <?php foreach ($this->getCcYears() as $k=>$v): ?>
-                    <option value="<?php echo $k ? $k : '' ?>" <?php if($k==$_ccExpYear): ?>selected="selected"<?php endif ?>><?php echo $v ?></option>
-                <?php endforeach ?>
-            </select>
-        </div>
-    </div>
-
-    <?php if($this->hasVerification()): ?>
-        <div class="field field-number required">
-            <label class="label" for="<?php echo $_code ?>_cc_cid"><span><?php echo __('Card Verification Number') ?></span></label>
-            <div class="control">
-                <input type="text" title="<?php echo __('Card Verification Number') ?>" class="required-entry input-text validate-cc-cvn" id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]" style="width:3em;" value="<?php echo $this->getInfoData('cc_cid')?>"/>
-            </div>
-        </div>
-    <?php endif; ?>
-
-    <?php if ($this->hasSsCardType()): ?>
-        <div id="<?php echo $_code ?>_cc_type_ss_div">
-            <div class="field field-type required">
-                <label for="<?php echo $_code ?>_cc_issue"><span><?php echo __('Switch/Solo/Maestro Only') ?></span></label>
-            </div>
-
-            <div class="field field-issue">
-                <label class="label" for="<?php echo $_code ?>_cc_issue"><span><?php echo __('Issue Number') ?>:</span></label>
-                <div class="control">
-                    <input type="text" title="<?php echo __('Issue Number') ?>" class="input-text validate-cc-ukss cvv" id="<?php echo $_code ?>_cc_issue" name="payment[cc_ss_issue]" value="" />
-                </div>
-            </div>
-
-            <div class="field field-date">
-                <label class="label" for="<?php echo $_code ?>_start_month"><span><?php echo __('Start Date') ?>:</span></label>
-                <div class="control">
-                    <select id="<?php echo $_code ?>_start_month" name="payment[cc_ss_start_month]" class="validate-cc-ukss month">
-                        <?php foreach ($this->getCcMonths() as $k=>$v): ?>
-                            <option value="<?php echo $k?$k:'' ?>"<?php if($k==$this->getInfoData('cc_ss_start_month')): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
-                        <?php endforeach ?>
-                    </select>
-                    <select id="<?php echo $_code ?>_start_year" name="payment[cc_ss_start_year]" class="validate-cc-ukss year">
-                        <?php foreach ($this->getSsStartYears() as $k=>$v): ?>
-                            <option value="<?php echo $k?$k:'' ?>"<?php if($k==$this->getInfoData('cc_ss_start_year')): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
-                        <?php endforeach ?>
-                    </select>
-                </div>
-            </div>
-
-            <div class="adv-container">&nbsp;</div>
-
-            <script type="text/javascript">
-                //<![CDATA[
-                var SSChecked<?php echo $_code ?> = function() {
-                    var elm = $('<?php echo $_code ?>_cc_type');
-                    if (['SS','SM','SO'].indexOf(elm.value) != -1) {
-                        jQuery('#' + '<?php echo $_code ?>_cc_type_ss_div').show().removeClass('ignore-validate');
-                    } else {
-                        jQuery('#' + '<?php echo $_code ?>_cc_type_ss_div').hide().addClass('ignore-validate');
-                    }
-                };
-                Event.observe($('<?php echo $_code ?>_cc_type'), 'change', SSChecked<?php echo $_code ?>);
-                SSChecked<?php echo $_code ?>();
-                //]]>
-            </script>
-        </div>
-    <?php endif; ?>
-</fieldset>
diff --git a/app/code/Magento/OfflinePayments/view/frontend/templates/form/ccsave.phtml b/app/code/Magento/OfflinePayments/view/frontend/templates/form/ccsave.phtml
deleted file mode 100644
index a2270efa5676ea21d1feca33f2833dab8ac7593c..0000000000000000000000000000000000000000
--- a/app/code/Magento/OfflinePayments/view/frontend/templates/form/ccsave.phtml
+++ /dev/null
@@ -1,137 +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 $_code=$this->getMethodCode() ?>
-<fieldset class="fieldset payment items ccard <?php echo $_code ?>" id="payment_form_<?php echo $_code ?>" style="display:none;">
-    <div class="field name required">
-        <label for="<?php echo $_code ?>_cc_owner" class="label"><span><?php echo __('Name on Card') ?></span></label>
-        <div class="control">
-            <input type="text" title="<?php echo __('Name on Card') ?>" class="input-text" id="<?php echo $_code ?>_cc_owner" name="payment[cc_owner]" value="<?php echo $this->escapeHtml($this->getInfoData('cc_owner')) ?>" data-validate='{required:true}'/>
-        </div>
-    </div>
-    <div class="field type required">
-        <label for="<?php echo $_code ?>_cc_type" class="label"><span><?php echo __('Credit Card Type') ?></span></label>
-        <div class="control">
-            <select id="<?php echo $_code ?>_cc_type"
-                    data-mage-init='{"creditCardType":{"creditCardTypeContainer":"#<?php echo $_code ?>_cc_type_ss_div"}}'
-                    name="payment[cc_type]" title="<?php echo __('Credit Card Type') ?>" data-validate='{required:true, "validate-cc-type-select":"#<?php echo $_code ?>_cc_number"}' class="select">
-                <option value=""><?php echo __('--Please Select--') ?></option>
-            <?php $_ccType = $this->getInfoData('cc_type') ?>
-            <?php foreach ($this->getCcAvailableTypes() as $_typeCode => $_typeName): ?>
-                <option value="<?php echo $_typeCode ?>"<?php if($_typeCode==$_ccType): ?> selected="selected"<?php endif ?>><?php echo $_typeName ?></option>
-            <?php endforeach ?>
-            </select>
-        </div>
-    </div>
-    <div class="field number required">
-        <label for="<?php echo $_code ?>_cc_number" class="label"><span><?php echo __('Credit Card Number') ?></span></label>
-        <div class="control">
-            <input type="number" id="<?php echo $_code ?>_cc_number" name="payment[cc_number]" title="<?php echo __('Credit Card Number') ?>" class="input-text" value="" data-validate='{required:true, "validate-cc-number":"#<?php echo $_code ?>_cc_type", "validate-cc-type":"#<?php echo $_code ?>_cc_type"}'/>
-        </div>
-    </div>
-    <div class="field date required">
-        <label for="<?php echo $_code ?>_expiration" class="label"><span><?php echo __('Expiration Date') ?></span></label>
-        <div class="control">
-            <div class="fields group group-2">
-                <div class="field no-label month">
-                    <div class="control">
-                        <select id="<?php echo $_code ?>_expiration" name="payment[cc_exp_month]" class="month" data-validate='{required:true, "validate-cc-exp":"#<?php echo $_code ?>_expiration_yr"}'>
-                        <?php $_ccExpMonth = $this->getInfoData('cc_exp_month') ?>
-                        <?php foreach ($this->getCcMonths() as $k=>$v): ?>
-                            <option value="<?php echo $k?$k:'' ?>"<?php if($k==$_ccExpMonth): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
-                        <?php endforeach ?>
-                        </select>
-                    </div>
-                </div>
-                <div class="field no-label year">
-                    <div class="control">
-                        <?php $_ccExpYear = $this->getInfoData('cc_exp_year') ?>
-                        <select id="<?php echo $_code ?>_expiration_yr" name="payment[cc_exp_year]" class="year" data-validate='{required:true}'>
-                        <?php foreach ($this->getCcYears() as $k=>$v): ?>
-                            <option value="<?php echo $k?$k:'' ?>"<?php if($k==$_ccExpYear): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
-                        <?php endforeach ?>
-                        </select>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <?php if($this->hasVerification()): ?>
-    <div class="field cvv required">
-        <label for="<?php echo $_code ?>_cc_cid" class="label"><span><?php echo __('Card Verification Number') ?></span></label>
-        <div class="control">
-            <input type="number" title="<?php echo __('Card Verification Number') ?>" class="input-text cvv" id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]" value="" data-validate='{required:true, "validate-cc-cvn":"#<?php echo $_code ?>_cc_type"}'/>
-            <?php $_content = '<img src=\"'.$this->getViewFileUrl('Magento_Checkout::cvv.gif').'\" alt=\"'.__('Card Verification Number Visual Reference').'\" title=\"'.__('Card Verification Number Visual Reference').'\" />'; ?>
-            <div class="note">
-                <a href="#" class="action cvv" title="" data-mage-init='{"tooltip": {"content": "<?php echo $_content ?>"}}'><span><?php echo __('What is this?') ?></span></a>
-            </div>
-        </div>
-    </div>
-    <?php endif; ?>
-
-    <?php if ($this->hasSsCardType()): ?>
-    <div class="field switch solo required" id="<?php echo $_code ?>_cc_type_ss_div">
-        <div class="nested">
-            <div class="field switch solo required">
-                <label for="<?php echo $_code ?>_cc_issue" class="label"><span><?php echo __('Switch/Solo/Maestro Only') ?></span></label>
-            </div>
-            <div class="field number required">
-                <label for="<?php echo $_code ?>_cc_issue" class="label"><span><?php echo __('Issue Number') ?></span></label>
-                <div class="control">
-                    <input type="text" title="<?php echo __('Issue Number') ?>" class="input-text cvv" id="<?php echo $_code ?>_cc_issue" name="payment[cc_ss_issue]" value="" data-validate='{"validate-cc-ukss":true}'/>
-                </div>
-            </div>
-
-            <div class="field date required">
-                <label for="<?php echo $_code ?>_start_month" class="label"><span><?php echo __('Start Date') ?></span></label>
-
-                <div class="control">
-                    <div class="fields group group-2">
-                        <div class="field no-label">
-                            <div class="control">
-                                <select id="<?php echo $_code ?>_start_month" name="payment[cc_ss_start_month]" class="month" data-validate='{"validate-cc-ukss":true}'>
-                                <?php foreach ($this->getCcMonths() as $k=>$v): ?>
-                                    <option value="<?php echo $k?$k:'' ?>"<?php if($k==$this->getInfoData('cc_ss_start_month')): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
-                                <?php endforeach ?>
-                                </select>
-                            </div>
-                        </div>
-                        <div class="field no-label">
-                            <div class="control">
-                                <select id="<?php echo $_code ?>_start_year" name="payment[cc_ss_start_year]" class="year" data-validate='{"validate-cc-ukss":true}'>
-                                <?php foreach ($this->getSsStartYears() as $k=>$v): ?>
-                                    <option value="<?php echo $k?$k:'' ?>"<?php if($k==$this->getInfoData('cc_ss_start_year')): ?> selected="selected"<?php endif ?>><?php echo $v ?></option>
-                                <?php endforeach ?>
-                                </select>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-            <div class="adv container" data-validation-msg="validate-cc-ukss">&nbsp;</div>
-        </div>
-    </div>
-    <?php endif; ?>
-    <?php echo $this->getChildHtml() ?>
-</fieldset>
diff --git a/app/code/Magento/Ogone/Model/Config.php b/app/code/Magento/Ogone/Model/Config.php
index 3454c8269656e5b32c693c944453a2179101e215..1da9203599023067a0e6415a425c2953cb18e4c2 100644
--- a/app/code/Magento/Ogone/Model/Config.php
+++ b/app/code/Magento/Ogone/Model/Config.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\Ogone\Model;
 
+use Magento\Store\Model\ScopeInterface;
+
 /**
  * Config model
  */
@@ -45,6 +47,7 @@ class Config extends \Magento\Payment\Model\Config
      * @param \Magento\Payment\Model\Method\Factory $paymentMethodFactory
      * @param \Magento\Framework\Locale\ListsInterface $localeLists
      * @param \Magento\Framework\Config\DataInterface $dataStorage
+     * @param \Magento\Framework\Stdlib\DateTime\DateTime $date
      * @param \Magento\Framework\UrlInterface $urlBuilder
      * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
      */
@@ -53,10 +56,11 @@ class Config extends \Magento\Payment\Model\Config
         \Magento\Payment\Model\Method\Factory $paymentMethodFactory,
         \Magento\Framework\Locale\ListsInterface $localeLists,
         \Magento\Framework\Config\DataInterface $dataStorage,
+        \Magento\Framework\Stdlib\DateTime\DateTime $date,
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Framework\Encryption\EncryptorInterface $encryptor
     ) {
-        parent::__construct($scopeConfig, $paymentMethodFactory, $localeLists, $dataStorage);
+        parent::__construct($scopeConfig, $paymentMethodFactory, $localeLists, $dataStorage, $date);
         $this->_urlBuilder = $urlBuilder;
         $this->_encryptor = $encryptor;
     }
@@ -73,7 +77,7 @@ class Config extends \Magento\Payment\Model\Config
         if (!empty($path)) {
             return $this->_scopeConfig->getValue(
                 self::OGONE_PAYMENT_PATH . $path,
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+                ScopeInterface::SCOPE_STORE,
                 $storeId
             );
         }
diff --git a/app/code/Magento/Payment/Block/Info.php b/app/code/Magento/Payment/Block/Info.php
index a62eb2f72564af7771d64f759174e8d07b114d65..bab83b56527bf7548cae42f6edf22d9a53471398 100644
--- a/app/code/Magento/Payment/Block/Info.php
+++ b/app/code/Magento/Payment/Block/Info.php
@@ -86,7 +86,7 @@ class Info extends \Magento\Framework\View\Element\Template
     {
         $result = array();
         foreach ($this->getLayout()->getChildBlocks($this->getNameInLayout()) as $child) {
-            if (method_exists($child, 'toPdf')) {
+            if (method_exists($child, 'toPdf') && is_callable([$child, 'toPdf'])) {
                 $result[] = $child->toPdf();
             }
         }
diff --git a/app/code/Magento/Payment/Model/Checks/CanUseCheckout.php b/app/code/Magento/Payment/Model/Checks/CanUseCheckout.php
index 11f29a4935deb162663d0b0ce4a14e494654d4d0..08f4ab261d9bf5130a0aada110e92c3c974575f5 100644
--- a/app/code/Magento/Payment/Model/Checks/CanUseCheckout.php
+++ b/app/code/Magento/Payment/Model/Checks/CanUseCheckout.php
@@ -31,7 +31,7 @@ class CanUseCheckout implements SpecificationInterface
      * Check whether payment method is applicable to quote
      *
      * @param PaymentMethodChecksInterface $paymentMethod
-     * @param \Magento\Sales\Model\Quote $quote
+     * @param Quote $quote
      * @return bool
      */
     public function isApplicable(PaymentMethodChecksInterface $paymentMethod, Quote $quote)
diff --git a/app/code/Magento/Payment/Model/Checks/CanUseForCountry.php b/app/code/Magento/Payment/Model/Checks/CanUseForCountry.php
index debf20993b1e045e013cd91d8faf55b30eb43e51..7310e289b8b362d84c74f5402c77d07cac8cfbcb 100644
--- a/app/code/Magento/Payment/Model/Checks/CanUseForCountry.php
+++ b/app/code/Magento/Payment/Model/Checks/CanUseForCountry.php
@@ -30,7 +30,7 @@ class CanUseForCountry implements SpecificationInterface
     /**
      * Check whether payment method is applicable to quote
      * @param PaymentMethodChecksInterface $paymentMethod
-     * @param \Magento\Sales\Model\Quote $quote
+     * @param Quote $quote
      * @return bool
      */
     public function isApplicable(PaymentMethodChecksInterface $paymentMethod, Quote $quote)
diff --git a/app/code/Magento/Payment/Model/Checks/SpecificationFactory.php b/app/code/Magento/Payment/Model/Checks/SpecificationFactory.php
index 26295db8efe85a774b1344fffe6ddd806985cfc5..a04ef799205a015f9ec921841846631dd9035a28 100644
--- a/app/code/Magento/Payment/Model/Checks/SpecificationFactory.php
+++ b/app/code/Magento/Payment/Model/Checks/SpecificationFactory.php
@@ -29,11 +29,11 @@ namespace Magento\Payment\Model\Checks;
 class SpecificationFactory
 {
     /**
-     * Object manager
+     * Composite Factory
      *
-     * @var \Magento\Framework\ObjectManager
+     * @var \Magento\Payment\Model\Checks\CompositeFactory
      */
-    protected $objectManager;
+    protected $compositeFactory;
 
     /** @var  array mapping */
     protected $mapping;
@@ -41,12 +41,12 @@ class SpecificationFactory
     /**
      * Construct
      *
-     * @param \Magento\Framework\ObjectManager $objectManager
+     * @param \Magento\Payment\Model\Checks\CompositeFactory $compositeFactory
      * @param array $mapping
      */
-    public function __construct(\Magento\Framework\ObjectManager $objectManager, array $mapping)
+    public function __construct(\Magento\Payment\Model\Checks\CompositeFactory $compositeFactory, array $mapping)
     {
-        $this->objectManager = $objectManager;
+        $this->compositeFactory = $compositeFactory;
         $this->mapping = $mapping;
     }
 
@@ -54,15 +54,12 @@ class SpecificationFactory
      * Creates new instances of payment method models
      *
      * @param array $data
-     * @return SpecificationInterface
+     * @return Composite
      * @throws \Magento\Framework\Model\Exception
      */
     public function create($data)
     {
         $specifications = array_intersect_key($this->mapping, array_flip((array)$data));
-        return $this->objectManager->create(
-            'Magento\Payment\Model\Checks\Composite',
-            array('list' => $specifications)
-        );
+        return $this->compositeFactory->create(array('list' => $specifications));
     }
 }
diff --git a/app/code/Magento/Payment/Model/Checks/TotalMinMax.php b/app/code/Magento/Payment/Model/Checks/TotalMinMax.php
index 3a0f6427dd4b39815cdfd313a8b9ef8d20ac45ea..d58afce684461ea0a53da852815ff0e94c273338 100644
--- a/app/code/Magento/Payment/Model/Checks/TotalMinMax.php
+++ b/app/code/Magento/Payment/Model/Checks/TotalMinMax.php
@@ -27,6 +27,16 @@ use Magento\Sales\Model\Quote;
 
 class TotalMinMax implements SpecificationInterface
 {
+    /**
+     * Config value key for min order total
+     */
+    const MIN_ORDER_TOTAL = 'min_order_total';
+
+    /**
+     * Config value key for max order total
+     */
+    const MAX_ORDER_TOTAL = 'max_order_total';
+
     /**
      * Check whether payment method is applicable to quote
      *
@@ -37,8 +47,8 @@ class TotalMinMax implements SpecificationInterface
     public function isApplicable(PaymentMethodChecksInterface $paymentMethod, Quote $quote)
     {
         $total = $quote->getBaseGrandTotal();
-        $minTotal = $paymentMethod->getConfigData('min_order_total');
-        $maxTotal = $paymentMethod->getConfigData('max_order_total');
+        $minTotal = $paymentMethod->getConfigData(self::MIN_ORDER_TOTAL);
+        $maxTotal = $paymentMethod->getConfigData(self::MAX_ORDER_TOTAL);
         if (!empty($minTotal) && $total < $minTotal || !empty($maxTotal) && $total > $maxTotal) {
             return false;
         }
diff --git a/app/code/Magento/Payment/Model/Config.php b/app/code/Magento/Payment/Model/Config.php
index d1fe2bda8defb6bb840c16c3234faab132ddebf3..ad399c1448b6e01b2c071b6ce3faac9f0b4e0b80 100644
--- a/app/code/Magento/Payment/Model/Config.php
+++ b/app/code/Magento/Payment/Model/Config.php
@@ -23,7 +23,7 @@
  */
 namespace Magento\Payment\Model;
 
-use Magento\Store\Model\Store;
+use Magento\Store\Model\ScopeInterface;
 use Magento\Payment\Model\Method\AbstractMethod;
 
 /**
@@ -33,6 +33,11 @@ use Magento\Payment\Model\Method\AbstractMethod;
  */
 class Config
 {
+    /**
+     * Years range
+     */
+    const YEARS_RANGE = 10;
+
     /**
      * @var array
      */
@@ -62,7 +67,14 @@ class Config
      *
      * @var \Magento\Payment\Model\Method\Factory
      */
-    protected $_methodFactory;
+    protected $_paymentMethodFactory;
+
+    /**
+     * DateTime
+     *
+     * @var \Magento\Framework\Stdlib\DateTime\DateTime
+     */
+    protected $_date;
 
     /**
      * Construct
@@ -71,41 +83,37 @@ class Config
      * @param \Magento\Payment\Model\Method\Factory $paymentMethodFactory
      * @param \Magento\Framework\Locale\ListsInterface $localeLists
      * @param \Magento\Framework\Config\DataInterface $dataStorage
+     * @param \Magento\Framework\Stdlib\DateTime\DateTime $date
      */
     public function __construct(
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Payment\Model\Method\Factory $paymentMethodFactory,
         \Magento\Framework\Locale\ListsInterface $localeLists,
-        \Magento\Framework\Config\DataInterface $dataStorage
+        \Magento\Framework\Config\DataInterface $dataStorage,
+        \Magento\Framework\Stdlib\DateTime\DateTime $date
     ) {
         $this->_scopeConfig = $scopeConfig;
         $this->_dataStorage = $dataStorage;
-        $this->_methodFactory = $paymentMethodFactory;
+        $this->_paymentMethodFactory = $paymentMethodFactory;
         $this->_localeLists = $localeLists;
+        $this->_date = $date;
     }
 
     /**
      * Retrieve active system payments
      *
-     * @param null|string|bool|int|Store $store
      * @return array
      */
-    public function getActiveMethods($store = null)
+    public function getActiveMethods()
     {
-        $methods = array();
-        $config = $this->_scopeConfig->getValue('payment', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
-        foreach ($config as $code => $methodConfig) {
-            if ($this->_scopeConfig->isSetFlag(
-                'payment/' . $code . '/active',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-                $store
-            )
-            ) {
-                if (array_key_exists('model', $methodConfig)) {
-                    $methodModel = $this->_methodFactory->create($methodConfig['model']);
-                    if ($methodModel && $methodModel->getConfigData('active', $store)) {
-                        $methods[$code] = $this->_getMethod($code, $methodConfig);
-                    }
+        $methods = [];
+        foreach ($this->_scopeConfig->getValue('payment', ScopeInterface::SCOPE_STORE, null) as $code => $data) {
+            if (isset($data['active']) && (bool)$data['active'] && isset($data['model'])) {
+                /** @var AbstractMethod|null $methodModel Actually it's wrong interface */
+                $methodModel = $this->_paymentMethodFactory->create($data['model']);
+                $methodModel->setId($code)->setStore(null);
+                if ($methodModel->getConfigData('active', null)) {
+                    $methods[$code] = $methodModel;
                 }
             }
         }
@@ -113,53 +121,7 @@ class Config
     }
 
     /**
-     * Retrieve all system payments
-     *
-     * @param null|string|bool|int|Store $store
-     * @return array
-     */
-    public function getAllMethods($store = null)
-    {
-        $methods = array();
-        $config = $this->_scopeConfig->getValue('payment', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $store);
-        foreach ($config as $code => $methodConfig) {
-            $data = $this->_getMethod($code, $methodConfig);
-            if (false !== $data) {
-                $methods[$code] = $data;
-            }
-        }
-        return $methods;
-    }
-
-    /**
-     * @param string $code
-     * @param string $config
-     * @param null|string|bool|int|Store $store
-     * @return \Magento\Payment\Model\MethodInterface
-     */
-    protected function _getMethod($code, $config, $store = null)
-    {
-        if (isset($this->_methods[$code])) {
-            return $this->_methods[$code];
-        }
-        if (empty($config['model'])) {
-            return false;
-        }
-        $modelName = $config['model'];
-
-        if (!class_exists($modelName)) {
-            return false;
-        }
-
-        /** @var AbstractMethod $method */
-        $method = $this->_methodFactory->create($modelName);
-        $method->setId($code)->setStore($store);
-        $this->_methods[$code] = $method;
-        return $this->_methods[$code];
-    }
-
-    /**
-     * Retrieve array of credit card types
+     * Get list of credit card types
      *
      * @return array
      */
@@ -185,12 +147,7 @@ class Config
      */
     public function getGroups()
     {
-        $groups = $this->_dataStorage->get('groups');
-        $result = array();
-        foreach ($groups as $code => $title) {
-            $result[$code] = $title;
-        }
-        return $result;
+        return $this->_dataStorage->get('groups');
     }
 
     /**
@@ -216,9 +173,8 @@ class Config
     public function getYears()
     {
         $years = array();
-        $first = date("Y");
-
-        for ($index = 0; $index <= 10; $index++) {
+        $first = (int)$this->_date->date('Y');
+        for ($index = 0; $index <= self::YEARS_RANGE; $index++) {
             $year = $first + $index;
             $years[$year] = $year;
         }
diff --git a/app/code/Magento/Payment/Model/Config/SchemaLocator.php b/app/code/Magento/Payment/Model/Config/SchemaLocator.php
index a86cffd42e00ef008b1ddf46517ca1d0bd71fa8b..42e63e7f4223ebe229272796fc0442b312627a5b 100644
--- a/app/code/Magento/Payment/Model/Config/SchemaLocator.php
+++ b/app/code/Magento/Payment/Model/Config/SchemaLocator.php
@@ -27,6 +27,16 @@ namespace Magento\Payment\Model\Config;
 
 class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
 {
+    /**
+     * Merged config schema file name
+     */
+    const MERGED_CONFIG_SCHEMA = 'payment.xsd';
+
+    /**
+     * Per file validation schema file name
+     */
+    const PER_FILE_VALIDATION_SCHEMA = 'payment_file.xsd';
+
     /**
      * Path to corresponding XSD file with validation rules for merged config
      *
@@ -46,8 +56,9 @@ class SchemaLocator implements \Magento\Framework\Config\SchemaLocatorInterface
      */
     public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader)
     {
-        $this->_schema = $moduleReader->getModuleDir('etc', 'Magento_Payment') . '/payment.xsd';
-        $this->_perFileSchema = $moduleReader->getModuleDir('etc', 'Magento_Payment') . '/payment_file.xsd';
+        $this->_schema = $moduleReader->getModuleDir('etc', 'Magento_Payment') . '/' . self::MERGED_CONFIG_SCHEMA;
+        $this->_perFileSchema = $moduleReader->getModuleDir('etc', 'Magento_Payment')
+            . '/' . self::PER_FILE_VALIDATION_SCHEMA;
     }
 
     /**
diff --git a/app/code/Magento/Payment/Model/Config/Source/Allmethods.php b/app/code/Magento/Payment/Model/Config/Source/Allmethods.php
index bdd8a1dbdfe8abe38fbfb64ec2ec7aced6034e43..fb4df03b0f2502b6e72a6b651099e0bd4834fe13 100644
--- a/app/code/Magento/Payment/Model/Config/Source/Allmethods.php
+++ b/app/code/Magento/Payment/Model/Config/Source/Allmethods.php
@@ -30,7 +30,7 @@ class Allmethods implements \Magento\Framework\Option\ArrayInterface
      *
      * @var \Magento\Payment\Helper\Data
      */
-    protected $_paymentData = null;
+    protected $_paymentData;
 
     /**
      * @param \Magento\Payment\Helper\Data $paymentData
diff --git a/app/code/Magento/Payment/Model/Info.php b/app/code/Magento/Payment/Model/Info.php
index 12a02e71eacc0cd061c92cf5f584c8b8919eea61..b2989c643e4739b524e753c5fba85dd84457a596 100644
--- a/app/code/Magento/Payment/Model/Info.php
+++ b/app/code/Magento/Payment/Model/Info.php
@@ -33,14 +33,14 @@ class Info extends \Magento\Framework\Model\AbstractModel
      *
      * @var array
      */
-    protected $_additionalInformation = -1;
+    protected $_additionalInformation = array();
 
     /**
      * Payment data
      *
      * @var \Magento\Payment\Helper\Data
      */
-    protected $_paymentData = null;
+    protected $_paymentData;
 
     /**
      * @var \Magento\Framework\Encryption\EncryptorInterface
@@ -95,7 +95,7 @@ class Info extends \Magento\Framework\Model\AbstractModel
     /**
      * Retrieve payment method model object
      *
-     * @return \Magento\Payment\Model\MethodInterface
+     * @return MethodInterface
      * @throws \Magento\Framework\Model\Exception
      */
     public function getMethodInstance()
@@ -105,7 +105,7 @@ class Info extends \Magento\Framework\Model\AbstractModel
                 $instance = $this->_paymentData->getMethodInstance($this->getMethod());
                 if (!$instance) {
                     $instance = $this->_paymentData->getMethodInstance(
-                        \Magento\Payment\Model\Method\Substitution::CODE
+                        Method\Substitution::CODE
                     );
                 }
                 $instance->setInfoInstance($this);
@@ -126,10 +126,7 @@ class Info extends \Magento\Framework\Model\AbstractModel
      */
     public function encrypt($data)
     {
-        if ($data) {
-            return $this->_encryptor->encrypt($data);
-        }
-        return $data;
+        return $this->_encryptor->encrypt($data);
     }
 
     /**
@@ -140,10 +137,7 @@ class Info extends \Magento\Framework\Model\AbstractModel
      */
     public function decrypt($data)
     {
-        if ($data) {
-            return $this->_encryptor->decrypt($data);
-        }
-        return $data;
+        return $this->_encryptor->decrypt($data);
     }
 
     /**
@@ -197,7 +191,7 @@ class Info extends \Magento\Framework\Model\AbstractModel
             unset($this->_additionalInformation[$key]);
             return $this->setData('additional_information', $this->_additionalInformation);
         }
-        $this->_additionalInformation = -1;
+        $this->_additionalInformation = array();
         return $this->unsetData('additional_information');
     }
 
@@ -217,17 +211,14 @@ class Info extends \Magento\Framework\Model\AbstractModel
     }
 
     /**
-     * Make sure _additionalInformation is an array
+     * Initialize _additionalInformation with $this->_data['additional_information'] if empty
      *
      * @return void
      */
     protected function _initAdditionalInformation()
     {
-        if (-1 === $this->_additionalInformation) {
+        if (empty($this->_additionalInformation) && $this->_getData('additional_information')) {
             $this->_additionalInformation = $this->_getData('additional_information');
         }
-        if (null === $this->_additionalInformation) {
-            $this->_additionalInformation = array();
-        }
     }
 }
diff --git a/app/code/Magento/Payment/Model/Method/AbstractMethod.php b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
index e775c0846bb6f3bdcd1a529c5fa7d08cca545c19..720776229f0fe6fdc6f0df7cf0e9d072a74111d0 100644
--- a/app/code/Magento/Payment/Model/Method/AbstractMethod.php
+++ b/app/code/Magento/Payment/Model/Method/AbstractMethod.php
@@ -30,6 +30,7 @@ use Magento\Payment\Model\Checks\PaymentMethodChecksInterface;
 
 /**
  * Payment method abstract model
+ * @method AbstractMethod setStore()
  */
 abstract class AbstractMethod extends \Magento\Framework\Object implements MethodInterface, PaymentMethodChecksInterface
 {
diff --git a/app/code/Magento/Payment/Model/Observer.php b/app/code/Magento/Payment/Model/Observer.php
index 0bec83e0d782e0b409df0f9d205117467a783805..f734264e322833da28965e95cae5b42362af3409 100644
--- a/app/code/Magento/Payment/Model/Observer.php
+++ b/app/code/Magento/Payment/Model/Observer.php
@@ -68,6 +68,7 @@ class Observer
      */
     public function salesOrderBeforeSave($observer)
     {
+        /** @var \Magento\Sales\Model\Order $order */
         $order = $observer->getEvent()->getOrder();
 
         if ($order->getPayment()->getMethodInstance()->getCode() != 'free') {
@@ -78,7 +79,7 @@ class Observer
             return $this;
         }
 
-        if ($order->isCanceled() || $order->getState() === \Magento\Sales\Model\Order::STATE_CLOSED) {
+        if ($order->isCanceled() || $order->getState() == \Magento\Sales\Model\Order::STATE_CLOSED) {
             return $this;
         }
         /**
@@ -96,7 +97,7 @@ class Observer
      */
     public function updateOrderStatusForPaymentMethods(\Magento\Framework\Event\Observer $observer)
     {
-        if ($observer->getEvent()->getState() !== \Magento\Sales\Model\Order::STATE_NEW) {
+        if ($observer->getEvent()->getState() != \Magento\Sales\Model\Order::STATE_NEW) {
             return;
         }
         $status = $observer->getEvent()->getStatus();
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php b/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..67ee9b9dc5347c58d6f8db36240686ac5d9e1d80
--- /dev/null
+++ b/app/code/Magento/Paypal/Block/Adminhtml/Store/SwitcherPlugin.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Block\Adminhtml\Store;
+
+class SwitcherPlugin
+{
+    /**
+     * Remove country request param from url
+     *
+     * @param \Magento\Backend\Block\Store\Switcher $subject
+     * @param \Closure $proceed
+     * @param string $route
+     * @param array $params
+     * @return string
+     */
+    public function aroundGetUrl(
+        \Magento\Backend\Block\Store\Switcher $subject,
+        \Closure $proceed,
+        $route = '',
+        $params = array()
+    ) {
+        if ($subject->getRequest()->getParam(\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY)) {
+            $params[\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY] = null;
+        }
+        return $proceed($route, $params);
+    }
+}
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Field/Country.php b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Field/Country.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6759b378742b6df4b26d13f49da335f6deb9236
--- /dev/null
+++ b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Field/Country.php
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Field renderer for PayPal merchant country selector
+ */
+namespace Magento\Paypal\Block\Adminhtml\System\Config\Field;
+
+use Magento\Paypal\Model\Config\StructurePlugin;
+
+class Country extends \Magento\Backend\Block\System\Config\Form\Field
+{
+    /**
+     * Config path for merchant country selector
+     */
+    const FIELD_CONFIG_PATH = 'paypal/general/merchant_country';
+
+    /**
+     * Request parameter name for default country
+     */
+    const REQUEST_PARAM_DEFAULT_COUNTRY = 'paypal_default_country';
+
+    /**
+     * Country of default scope
+     *
+     * @var string
+     */
+    protected $_defaultCountry;
+
+    /**
+     * @var \Magento\Backend\Model\Url
+     */
+    protected $_url;
+
+    /**
+     * @var \Magento\Framework\View\Helper\Js
+     */
+    protected $_jsHelper;
+
+    /**
+     * @var \Magento\Core\Helper\Data
+     */
+    protected $_coreHelper;
+
+    /**
+     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Model\Url $url
+     * @param \Magento\Framework\View\Helper\Js $jsHelper
+     * @param \Magento\Core\Helper\Data $coreHelper
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Model\Url $url,
+        \Magento\Framework\View\Helper\Js $jsHelper,
+        \Magento\Core\Helper\Data $coreHelper,
+        array $data = array()
+    ) {
+        parent::__construct($context, $data);
+        $this->_url = $url;
+        $this->_jsHelper = $jsHelper;
+        $this->_coreHelper = $coreHelper;
+    }
+
+    /**
+     * Render country field considering request parameter
+     *
+     * @param \Magento\Framework\Data\Form\Element\AbstractElement $element
+     * @return string
+     */
+    public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
+    {
+        $country = $this->getRequest()->getParam(StructurePlugin::REQUEST_PARAM_COUNTRY);
+        if ($country) {
+            $element->setValue($country);
+        }
+
+        if ($element->getCanUseDefaultValue()) {
+            $this->_defaultCountry = $this->_scopeConfig->getValue(self::FIELD_CONFIG_PATH);
+            if (!$this->_defaultCountry) {
+                $this->_defaultCountry = $this->_coreHelper->getDefaultCountry();
+            }
+            if ($country) {
+                $shouldInherit = $country == $this->_defaultCountry
+                    && $this->getRequest()->getParam(self::REQUEST_PARAM_DEFAULT_COUNTRY);
+                $element->setInherit($shouldInherit);
+            }
+            if ($element->getInherit()) {
+                $this->_defaultCountry = null;
+            }
+        }
+
+        return parent::render($element);
+    }
+
+    /**
+     * Get country selector html
+     *
+     * @param \Magento\Framework\Data\Form\Element\AbstractElement $element
+     * @return string
+     */
+    protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
+    {
+        $urlParams = [
+            'section' => $this->getRequest()->getParam('section'),
+            'website' => $this->getRequest()->getParam('website'),
+            'store' => $this->getRequest()->getParam('store'),
+            StructurePlugin::REQUEST_PARAM_COUNTRY => '__country__'
+        ];
+        $urlString = $this->_escaper->escapeJsQuote($this->_url->getUrl('*/*/*', $urlParams));
+        $jsString = '
+            $("' . $element->getHtmlId() . '").observe("change", function () {
+                location.href = \'' . $urlString . '\'.replace("__country__", this.value);
+            });
+        ';
+
+        if ($this->_defaultCountry) {
+            $urlParams[self::REQUEST_PARAM_DEFAULT_COUNTRY] = '__default__';
+            $urlString = $this->_escaper->escapeJsQuote($this->_url->getUrl('*/*/*', $urlParams));
+            $jsParentCountry = $this->_escaper->escapeJsQuote($this->_defaultCountry);
+            $jsString .= '
+                $("' . $element->getHtmlId() . '_inherit").observe("click", function () {
+                    if (this.checked) {
+                        location.href = \'' . $urlString . '\'.replace("__country__", \'' . $jsParentCountry . '\')
+                            .replace("__default__", "1");
+                    }
+                });
+            ';
+        }
+
+        return parent::_getElementHtml($element) . $this->_jsHelper->getScript(
+            'document.observe("dom:loaded", function() {' . $jsString . '});'
+        );
+    }
+}
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Group.php b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Group.php
index 4c0f1a5a55d7f9e138dae5161c7510edeeefd693..d943cb66b96ec247f0ab84efca3a3bd546d233d4 100644
--- a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Group.php
+++ b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Group.php
@@ -83,7 +83,8 @@ class Group extends \Magento\Backend\Block\System\Config\Form\Fieldset
             return $extra['configState'][$element->getId()];
         }
 
-        if ($element->getExpanded() !== null) {
+        $groupConfig = $element->getGroup();
+        if (!empty($groupConfig['expanded'])) {
             return true;
         }
 
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Location.php b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Location.php
index 2b47358433f81dc2db9687350018ff2ade20854d..03f52d5de07e89b7ef99718d7e4db2bd4f6a5a8f 100644
--- a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Location.php
+++ b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Location.php
@@ -29,7 +29,7 @@
  */
 namespace Magento\Paypal\Block\Adminhtml\System\Config\Fieldset;
 
-class Location extends \Magento\Backend\Block\System\Config\Form\Fieldset
+class Location extends \Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded
 {
     /**
      * Render fieldset html
@@ -373,6 +373,6 @@ class Location extends \Magento\Backend\Block\System\Config\Form\Fieldset
                 });
             });
         ';
-        return $this->toHtml() . $this->_jsHelper->getScript($js);
+        return parent::render($element) . $this->_jsHelper->getScript($js);
     }
 }
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Payment.php b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Payment.php
index b09e265347ebaad2569cd873591991719514a6a8..2d983add86fdeeed767119d480c51ff76a11dae4 100644
--- a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Payment.php
+++ b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Payment.php
@@ -72,15 +72,19 @@ class Payment extends \Magento\Backend\Block\System\Config\Form\Fieldset
     protected function _isPaymentEnabled($element)
     {
         $groupConfig = $element->getGroup();
-        $activityPath = isset($groupConfig['activity_path']) ? $groupConfig['activity_path'] : '';
+        $activityPaths = isset($groupConfig['activity_path']) ? $groupConfig['activity_path'] : [];
 
-        if (empty($activityPath)) {
-            return false;
+        if (!is_array($activityPaths)) {
+            $activityPaths = [$activityPaths];
         }
 
-        $isPaymentEnabled = (string)$this->_backendConfig->getConfigDataValue($activityPath);
+        $isPaymentEnabled = false;
+        foreach ($activityPaths as $activityPath) {
+            $isPaymentEnabled = $isPaymentEnabled
+                || (bool)(string)$this->_backendConfig->getConfigDataValue($activityPath);
+        }
 
-        return (bool)$isPaymentEnabled;
+        return $isPaymentEnabled;
     }
 
     /**
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Store.php b/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Store.php
deleted file mode 100644
index 21dfd95a60f7c9f0bdb4908e57a1c70ccd3e3ae2..0000000000000000000000000000000000000000
--- a/app/code/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/Store.php
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Paypal\Block\Adminhtml\System\Config\Fieldset;
-
-/**
- * Renderer for service JavaScript code that disables corresponding paypal methods on page load
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Store extends \Magento\Backend\Block\Template implements \Magento\Framework\Data\Form\Element\Renderer\RendererInterface
-{
-    /**
-     * Path to template file
-     *
-     * @var string
-     */
-    protected $_template = 'Magento_Paypal::system/config/fieldset/store.phtml';
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        array $data = array()
-    ) {
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * Render service JavaScript code
-     *
-     * @param \Magento\Framework\Data\Form\Element\AbstractElement $element
-     * @return string
-     */
-    public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
-    {
-        $html = $this->_storeManager->isSingleStoreMode() ? '' : $this->toHtml();
-        return $html;
-    }
-
-    /**
-     * Returns list of disabled (in the Default or the Website Scope) paypal methods
-     *
-     * @return array
-     */
-    protected function getPaypalDisabledMethods()
-    {
-        // Assoc array that contains info about paypal methods (their IDs and corresponding Config Paths)
-        $methods = array(
-            'express' => 'payment/paypal_express/active',
-            'wps' => 'payment/paypal_standard/active',
-            'wpp' => 'payment/paypal_direct/active',
-            'wpppe' => 'payment/payflow_direct/active',
-            'payflowpro' => 'payment/payflowpro/active',
-            'expresspe' => 'payment/payflow_express/active'
-        );
-        // Retrieve a code of the current website
-        $website = $this->getRequest()->getParam('website');
-        $disabledMethods = array();
-        foreach ($methods as $methodId => $methodPath) {
-            $isEnabled = (int)$this->_scopeConfig->getValue($methodPath, 'website', $website);
-            if ($isEnabled === 0) {
-                $disabledMethods[$methodId] = $isEnabled;
-            }
-        }
-        return $disabledMethods;
-    }
-}
diff --git a/app/code/Magento/Paypal/Block/Express/Shortcut.php b/app/code/Magento/Paypal/Block/Express/Shortcut.php
index 8f014d3bbee076c205f0b676a66aa7b4ebb30399..8f508fad6dea14cb37cc1611b9902c0da402f967 100644
--- a/app/code/Magento/Paypal/Block/Express/Shortcut.php
+++ b/app/code/Magento/Paypal/Block/Express/Shortcut.php
@@ -177,7 +177,7 @@ class Shortcut extends \Magento\Framework\View\Element\Template implements Catal
 
         // check visibility on cart or product page
         $context = $isInCatalog ? 'visible_on_product' : 'visible_on_cart';
-        if (!$config->{$context}) {
+        if (!$config->getConfigValue($context)) {
             $this->_shouldRender = false;
             return $result;
         }
diff --git a/app/code/Magento/Paypal/Helper/Backend.php b/app/code/Magento/Paypal/Helper/Backend.php
new file mode 100644
index 0000000000000000000000000000000000000000..10ba896db84f05e5b56ffb6989c372c2a6a493db
--- /dev/null
+++ b/app/code/Magento/Paypal/Helper/Backend.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Helper;
+
+/**
+ * Paypal Backend helper
+ */
+class Backend extends \Magento\Framework\App\Helper\AbstractHelper
+{
+    /**
+     * @var \Magento\Core\Helper\Data
+     */
+    protected $_coreHelper;
+
+    /**
+     * @var \Magento\Backend\Model\Config
+     */
+    protected $_backendConfig;
+
+    /**
+     * @param \Magento\Framework\App\Helper\Context $context
+     * @param \Magento\Core\Helper\Data $coreHelper
+     * @param \Magento\Backend\Model\Config $backendConfig
+     */
+    public function __construct(
+        \Magento\Framework\App\Helper\Context $context,
+        \Magento\Core\Helper\Data $coreHelper,
+        \Magento\Backend\Model\Config $backendConfig
+    ) {
+        parent::__construct($context);
+        $this->_coreHelper = $coreHelper;
+        $this->_backendConfig = $backendConfig;
+    }
+
+    /**
+     * Get selected merchant country code in system configuration
+     *
+     * @return string
+     */
+    public function getConfigurationCountryCode()
+    {
+        $countryCode  = $this->_request->getParam(\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY);
+        if (is_null($countryCode) || preg_match('/^[a-zA-Z]{2}$/', $countryCode) == 0) {
+            $countryCode = $this->_backendConfig->getConfigDataValue(
+                \Magento\Paypal\Block\Adminhtml\System\Config\Field\Country::FIELD_CONFIG_PATH
+            );
+        }
+        if (empty($countryCode)) {
+            $countryCode = $this->_coreHelper->getDefaultCountry();
+        }
+        return $countryCode;
+    }
+}
diff --git a/app/code/Magento/Paypal/Model/AbstractIpn.php b/app/code/Magento/Paypal/Model/AbstractIpn.php
index 891581276d25e39fc2aeb58beab48606b6b5684b..03fee1cce9f37913e089fd665e43229136dcd189 100644
--- a/app/code/Magento/Paypal/Model/AbstractIpn.php
+++ b/app/code/Magento/Paypal/Model/AbstractIpn.php
@@ -104,7 +104,7 @@ class AbstractIpn
         $postbackUrl = $this->_config->getPaypalUrl();
         $this->_addDebugData('postback_to', $postbackUrl);
 
-        $httpAdapter->setConfig(array('verifypeer' => $this->_config->verifyPeer));
+        $httpAdapter->setConfig(array('verifypeer' => $this->_config->getConfigValue('verifyPeer')));
         $httpAdapter->write(\Zend_Http_Client::POST, $postbackUrl, '1.1', array('Connection: close'), $postbackQuery);
         try {
             $postbackResult = $httpAdapter->read();
@@ -169,7 +169,7 @@ class AbstractIpn
      */
     protected function _debug()
     {
-        if ($this->_config && $this->_config->debug) {
+        if ($this->_config && $this->_config->getConfigValue('debug')) {
             $file = $this->_config
                 ->getMethodCode() ? "payment_{$this
                 ->_config
diff --git a/app/code/Magento/Paypal/Model/Api/AbstractApi.php b/app/code/Magento/Paypal/Model/Api/AbstractApi.php
index 12a59392568a3ac9bf1fce8555013161144f3889..5f7c6e3f777422612a612136430d6fde7fd80595 100644
--- a/app/code/Magento/Paypal/Model/Api/AbstractApi.php
+++ b/app/code/Magento/Paypal/Model/Api/AbstractApi.php
@@ -156,7 +156,7 @@ abstract class AbstractApi extends \Magento\Framework\Object
      */
     public function getApiUsername()
     {
-        return $this->_config->apiUsername;
+        return $this->_config->getConfigValue('apiUsername');
     }
 
     /**
@@ -166,7 +166,7 @@ abstract class AbstractApi extends \Magento\Framework\Object
      */
     public function getApiPassword()
     {
-        return $this->_config->apiPassword;
+        return $this->_config->getConfigValue('apiPassword');
     }
 
     /**
@@ -176,7 +176,7 @@ abstract class AbstractApi extends \Magento\Framework\Object
      */
     public function getApiSignature()
     {
-        return $this->_config->apiSignature;
+        return $this->_config->getConfigValue('apiSignature');
     }
 
     /**
@@ -542,7 +542,7 @@ abstract class AbstractApi extends \Magento\Framework\Object
         if ($this->hasData($key)) {
             return $this->getData($key);
         }
-        return $this->_config->{$key} ? $this->_config->{$key} : $default;
+        return $this->_config->getConfigValue($key) ? $this->_config->getConfigValue($key) : $default;
     }
 
     /**
@@ -639,7 +639,7 @@ abstract class AbstractApi extends \Magento\Framework\Object
      */
     public function getDebugFlag()
     {
-        return $this->_config->debug;
+        return $this->_config->getConfigValue('debug');
     }
 
     /**
@@ -649,6 +649,6 @@ abstract class AbstractApi extends \Magento\Framework\Object
      */
     public function getUseCertAuthentication()
     {
-        return (bool)$this->_config->apiAuthentication;
+        return (bool)$this->_config->getConfigValue('apiAuthentication');
     }
 }
diff --git a/app/code/Magento/Paypal/Model/Api/Nvp.php b/app/code/Magento/Paypal/Model/Api/Nvp.php
index e100aa87b2688d7d23f6530c216ec3b8019054f4..585541edfaeac962d28fe396a2736c5207cfc447 100644
--- a/app/code/Magento/Paypal/Model/Api/Nvp.php
+++ b/app/code/Magento/Paypal/Model/Api/Nvp.php
@@ -783,7 +783,7 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
     public function getApiEndpoint()
     {
         $url = $this->getUseCertAuthentication() ? 'https://api%s.paypal.com/nvp' : 'https://api-3t%s.paypal.com/nvp';
-        return sprintf($url, $this->_config->sandboxFlag ? '.sandbox' : '');
+        return sprintf($url, $this->_config->getConfigValue('sandboxFlag') ? '.sandbox' : '');
     }
 
     /**
@@ -1174,7 +1174,7 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
 
         try {
             $http = new \Magento\Framework\HTTP\Adapter\Curl();
-            $config = array('timeout' => 60, 'verifypeer' => $this->_config->verifyPeer);
+            $config = array('timeout' => 60, 'verifypeer' => $this->_config->getConfigValue('verifyPeer'));
             if ($this->getUseProxy()) {
                 $config['proxy'] = $this->getProxyHost() . ':' . $this->getProxyPort();
             }
diff --git a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
index d4933ed247bafc065c9a3a71362da0f96d66c05d..6450d5b29f4918b2e5dac9f74442e56e44469594 100644
--- a/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
+++ b/app/code/Magento/Paypal/Model/Api/PayflowNvp.php
@@ -480,7 +480,10 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
      */
     public function getApiEndpoint()
     {
-        return sprintf('https://%spayflowpro.paypal.com/transaction', $this->_config->sandboxFlag ? 'pilot-' : '');
+        return sprintf(
+            'https://%spayflowpro.paypal.com/transaction',
+            $this->_config->getConfigValue('sandboxFlag') ? 'pilot-' : ''
+        );
     }
 
     /**
@@ -597,7 +600,7 @@ class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
             case \Magento\Paypal\Model\Api\Nvp::GET_EXPRESS_CHECKOUT_DETAILS:
             case \Magento\Paypal\Model\Api\Nvp::SET_EXPRESS_CHECKOUT:
             case \Magento\Paypal\Model\Api\Nvp::DO_DIRECT_PAYMENT:
-                return $this->_config->payment_action ==
+                return $this->_config->getConfigValue('payment_action') ==
                     \Magento\Paypal\Model\Config::PAYMENT_ACTION_AUTH ? self::TRXTYPE_AUTH_ONLY : self::TRXTYPE_SALE;
             case \Magento\Paypal\Model\Api\Nvp::DO_CAPTURE:
                 return self::TRXTYPE_DELAYED_CAPTURE;
diff --git a/app/code/Magento/Paypal/Model/Config.php b/app/code/Magento/Paypal/Model/Config.php
index 81aa7428da980928730bc4ba232351b1a0ef09c0..9d62ad04439e79aa0eac48060a875336f1fd6fbe 100644
--- a/app/code/Magento/Paypal/Model/Config.php
+++ b/app/code/Magento/Paypal/Model/Config.php
@@ -44,11 +44,6 @@ class Config
      */
     const METHOD_WPP_DIRECT = 'paypal_direct';
 
-    /**
-     * Direct Payments (Payflow Edition)
-     */
-    const METHOD_WPP_PE_DIRECT = 'payflow_direct';
-
     /**
      * Express Checkout (Payflow Edition)
      */
@@ -203,8 +198,7 @@ class Config
         'paypal_standard' => 'WPS',
         'paypal_express' => 'EC',
         'paypal_direct' => 'DP',
-        'payflow_express' => 'EC',
-        'payflow_direct' => 'DP'
+        'payflow_express' => 'EC'
     );
 
     /**
@@ -732,41 +726,26 @@ class Config
 
         switch ($methodCode) {
             case self::METHOD_WPS:
-                if (!$this->businessAccount) {
+                if (!$this->getConfigValue('businessAccount')) {
                     $result = false;
                     break;
                 }
                 // check for direct payments dependence
-                if ($this->isMethodActive(self::METHOD_WPP_DIRECT) || $this->isMethodActive(self::METHOD_WPP_PE_DIRECT)
-                ) {
+                if ($this->isMethodActive(self::METHOD_WPP_DIRECT)) {
                     $result = false;
                 }
                 break;
             case self::METHOD_WPP_EXPRESS:
-                // check for direct payments dependence
-                if ($this->isMethodActive(self::METHOD_WPP_PE_DIRECT)) {
-                    $result = false;
-                } elseif ($this->isMethodActive(self::METHOD_WPP_DIRECT)) {
+                if ($this->isMethodActive(self::METHOD_WPP_DIRECT)) {
                     $result = true;
                 }
                 break;
             case self::METHOD_WPP_PE_EXPRESS:
                 // check for direct payments dependence
-                if ($this->isMethodActive(
-                    self::METHOD_WPP_PE_DIRECT
-                ) || $this->isMethodActive(
-                    self::METHOD_PAYFLOWLINK
-                ) || $this->isMethodActive(
-                    self::METHOD_PAYFLOWADVANCED
-                )
-                ) {
+                if ($this->isMethodActive(self::METHOD_PAYFLOWLINK)
+                    || $this->isMethodActive(self::METHOD_PAYFLOWADVANCED)) {
                     $result = true;
-                } elseif (!$this->isMethodActive(
-                    self::METHOD_WPP_PE_DIRECT
-                ) && !$this->isMethodActive(
-                    self::METHOD_PAYFLOWPRO
-                )
-                ) {
+                } elseif (!$this->isMethodActive(self::METHOD_PAYFLOWPRO)) {
                     $result = false;
                 }
                 break;
@@ -774,7 +753,6 @@ class Config
                 $result = $this->isWppApiAvailabe();
                 break;
             case self::METHOD_WPP_DIRECT:
-            case self::METHOD_WPP_PE_DIRECT:
                 break;
         }
         return $result;
@@ -789,7 +767,7 @@ class Config
      * @param string $key
      * @return string|null
      */
-    public function __get($key)
+    public function getConfigValue($key)
     {
         $underscored = strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $key));
         $path = $this->_getSpecificConfigPath($underscored);
@@ -894,9 +872,9 @@ class Config
      */
     public function getCountryMethods($countryCode = null)
     {
-        $countryMethods = array(
-            'other' => array(self::METHOD_WPS, self::METHOD_WPP_EXPRESS, self::METHOD_BILLING_AGREEMENT),
-            'US' => array(
+        $countryMethods = [
+            'other' => [self::METHOD_WPS, self::METHOD_WPP_EXPRESS, self::METHOD_BILLING_AGREEMENT],
+            'US' => [
                 self::METHOD_PAYFLOWADVANCED,
                 self::METHOD_WPP_DIRECT,
                 self::METHOD_WPS,
@@ -905,68 +883,71 @@ class Config
                 self::METHOD_WPP_EXPRESS,
                 self::METHOD_BILLING_AGREEMENT,
                 self::METHOD_WPP_PE_EXPRESS
-            ),
-            'CA' => array(
+            ],
+            'CA' => [
                 self::METHOD_WPP_DIRECT,
                 self::METHOD_WPS,
                 self::METHOD_PAYFLOWPRO,
                 self::METHOD_PAYFLOWLINK,
                 self::METHOD_WPP_EXPRESS,
-                self::METHOD_BILLING_AGREEMENT
-            ),
-            'GB' => array(
+                self::METHOD_BILLING_AGREEMENT,
+                self::METHOD_WPP_PE_EXPRESS
+            ],
+            'GB' => [
                 self::METHOD_WPP_DIRECT,
                 self::METHOD_WPS,
-                self::METHOD_WPP_PE_DIRECT,
                 self::METHOD_HOSTEDPRO,
                 self::METHOD_WPP_EXPRESS,
-                self::METHOD_BILLING_AGREEMENT,
-                self::METHOD_WPP_PE_EXPRESS
-            ),
-            'AU' => array(
+                self::METHOD_BILLING_AGREEMENT
+            ],
+            'AU' => [
                 self::METHOD_WPS,
                 self::METHOD_PAYFLOWPRO,
                 self::METHOD_HOSTEDPRO,
                 self::METHOD_WPP_EXPRESS,
                 self::METHOD_BILLING_AGREEMENT
-            ),
-            'NZ' => array(
+            ],
+            'NZ' => [
                 self::METHOD_WPS,
                 self::METHOD_PAYFLOWPRO,
                 self::METHOD_WPP_EXPRESS,
                 self::METHOD_BILLING_AGREEMENT
-            ),
-            'JP' => array(
+            ],
+            'JP' => [
                 self::METHOD_WPS,
                 self::METHOD_HOSTEDPRO,
                 self::METHOD_WPP_EXPRESS,
                 self::METHOD_BILLING_AGREEMENT
-            ),
-            'FR' => array(
+            ],
+            'FR' => [
                 self::METHOD_WPS,
                 self::METHOD_HOSTEDPRO,
                 self::METHOD_WPP_EXPRESS,
                 self::METHOD_BILLING_AGREEMENT
-            ),
-            'IT' => array(
+            ],
+            'IT' => [
                 self::METHOD_WPS,
                 self::METHOD_HOSTEDPRO,
                 self::METHOD_WPP_EXPRESS,
                 self::METHOD_BILLING_AGREEMENT
-            ),
-            'ES' => array(
+            ],
+            'ES' => [
                 self::METHOD_WPS,
                 self::METHOD_HOSTEDPRO,
                 self::METHOD_WPP_EXPRESS,
                 self::METHOD_BILLING_AGREEMENT
-            ),
-            'HK' => array(
+            ],
+            'HK' => [
                 self::METHOD_WPS,
                 self::METHOD_HOSTEDPRO,
                 self::METHOD_WPP_EXPRESS,
                 self::METHOD_BILLING_AGREEMENT
-            )
-        );
+            ],
+            'DE' => [
+                self::METHOD_WPP_EXPRESS,
+                self::METHOD_BILLING_AGREEMENT
+            ]
+        ];
         if ($countryCode === null) {
             return $countryMethods;
         }
@@ -1028,7 +1009,7 @@ class Config
     {
         return sprintf(
             'https://www.%spaypal.com/cgi-bin/webscr%s',
-            $this->sandboxFlag ? 'sandbox.' : '',
+            $this->getConfigValue('sandboxFlag') ? 'sandbox.' : '',
             $params ? '?' . http_build_query($params) : ''
         );
     }
@@ -1040,7 +1021,7 @@ class Config
      */
     public function areButtonsDynamic()
     {
-        return $this->buttonFlavor === self::EC_FLAVOR_DYNAMIC;
+        return $this->getConfigValue('buttonFlavor') === self::EC_FLAVOR_DYNAMIC;
     }
 
     /**
@@ -1058,7 +1039,7 @@ class Config
         if ($this->areButtonsDynamic()) {
             return $this->_getDynamicImageUrl(self::EC_BUTTON_TYPE_SHORTCUT, $localeCode, $orderTotal, $pal);
         }
-        if ($this->buttonType === self::EC_BUTTON_TYPE_MARK) {
+        if ($this->getConfigValue('buttonType') === self::EC_BUTTON_TYPE_MARK) {
             return $this->getPaymentMarkImageUrl($localeCode);
         }
         return sprintf(
@@ -1085,7 +1066,7 @@ class Config
         }
 
         if (null === $staticSize) {
-            $staticSize = $this->paymentMarkSize;
+            $staticSize = $this->getConfigValue('paymentMarkSize');
         }
         switch ($staticSize) {
             case self::PAYMENT_MARK_37X23:
@@ -1317,7 +1298,7 @@ class Config
      */
     public function getPaymentAction()
     {
-        switch ($this->paymentAction) {
+        switch ($this->getConfigValue('paymentAction')) {
             case self::PAYMENT_ACTION_AUTH:
                 return \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE;
             case self::PAYMENT_ACTION_SALE:
@@ -1372,7 +1353,8 @@ class Config
      */
     public function shouldAskToCreateBillingAgreement()
     {
-        return $this->allow_ba_signup === self::EC_BA_SIGNUP_ASK && !$this->shouldUseUnilateralPayments();
+        return $this->getConfigValue('allow_ba_signup') === self::EC_BA_SIGNUP_ASK
+            && !$this->shouldUseUnilateralPayments();
     }
 
     /**
@@ -1382,7 +1364,7 @@ class Config
      */
     public function shouldUseUnilateralPayments()
     {
-        return $this->business_account && !$this->isWppApiAvailabe();
+        return $this->getConfigValue('business_account') && !$this->isWppApiAvailabe();
     }
 
     /**
@@ -1392,7 +1374,10 @@ class Config
      */
     public function isWppApiAvailabe()
     {
-        return $this->api_username && $this->api_password && ($this->api_signature || $this->api_cert);
+        return $this->getConfigValue('api_username')
+            && $this->getConfigValue('api_password')
+            && ($this->getConfigValue('api_signature')
+            || $this->getConfigValue('api_cert'));
     }
 
     /**
@@ -1449,7 +1434,6 @@ class Config
     {
         switch ($code) {
             case self::METHOD_WPP_DIRECT:
-            case self::METHOD_WPP_PE_DIRECT:
             case self::METHOD_PAYFLOWPRO:
             case self::METHOD_PAYFLOWLINK:
             case self::METHOD_PAYFLOWADVANCED:
@@ -1491,8 +1475,9 @@ class Config
     public function exportExpressCheckoutStyleSettings(\Magento\Framework\Object $to)
     {
         foreach ($this->_ecStyleConfigMap as $key => $exportKey) {
-            if ($this->{$key}) {
-                $to->setData($exportKey, $this->{$key});
+            $configValue = $this->getConfigValue($key);
+            if ($configValue) {
+                $to->setData($exportKey, $configValue);
             }
         }
     }
@@ -1522,7 +1507,7 @@ class Config
         }
         return sprintf(
             'https://fpdbs%s.paypal.com/dynamicimageweb?%s',
-            $this->sandboxFlag ? '.sandbox' : '',
+            $this->getConfigValue('sandboxFlag') ? '.sandbox' : '',
             http_build_query($params)
         );
     }
@@ -1559,7 +1544,6 @@ class Config
                 $path = $this->_mapExpressFieldset($fieldName);
                 break;
             case self::METHOD_WPP_DIRECT:
-            case self::METHOD_WPP_PE_DIRECT:
                 $path = $this->_mapDirectFieldset($fieldName);
                 break;
             case self::METHOD_BILLING_AGREEMENT:
@@ -1577,7 +1561,6 @@ class Config
                     $path = $this->_mapWppFieldset($fieldName);
                     break;
                 case self::METHOD_WPP_PE_EXPRESS:
-                case self::METHOD_WPP_PE_DIRECT:
                 case self::METHOD_PAYFLOWADVANCED:
                 case self::METHOD_PAYFLOWLINK:
                     $path = $this->_mapWpukFieldset($fieldName);
@@ -1731,10 +1714,7 @@ class Config
         )
         ) {
             $pathPrefix = 'payment/payflow_advanced';
-        } elseif ($this->_methodCode == self::METHOD_WPP_PE_EXPRESS && !$this->isMethodAvailable(
-            self::METHOD_WPP_PE_DIRECT
-        )
-        ) {
+        } elseif ($this->_methodCode == self::METHOD_WPP_PE_EXPRESS) {
             $pathPrefix = 'payment/payflowpro';
         } elseif ($this->_methodCode == self::METHOD_PAYFLOWADVANCED || $this->_methodCode == self::METHOD_PAYFLOWLINK
         ) {
diff --git a/app/code/Magento/GroupedProduct/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php b/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php
similarity index 57%
rename from app/code/Magento/GroupedProduct/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php
rename to app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php
index fb2995df05543ae472ad28cbf8abdb34c4226800..015deadeae4c21581c866ac6b75cec2ff4e59ef4 100644
--- a/app/code/Magento/GroupedProduct/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks/Plugin/Grouped.php
+++ b/app/code/Magento/Paypal/Model/Config/Structure/Element/FieldPlugin.php
@@ -21,42 +21,41 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\GroupedProduct\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks\Plugin;
+namespace Magento\Paypal\Model\Config\Structure\Element;
 
-class Grouped
+class FieldPlugin
 {
     /**
      * @var \Magento\Framework\App\RequestInterface
      */
-    protected $request;
+    protected $_request;
 
     /**
      * @param \Magento\Framework\App\RequestInterface $request
      */
     public function __construct(\Magento\Framework\App\RequestInterface $request)
     {
-        $this->request = $request;
+        $this->_request = $request;
     }
 
     /**
-     * Initialize grouped product links
+     * Get original configPath (not changed by PayPal configuration inheritance)
      *
-     * @param \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks $subject
-     * @param \Magento\Catalog\Model\Product $product
-     *
-     * @return \Magento\Catalog\Model\Product
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     * @param \Magento\Backend\Model\Config\Structure\Element\Field $subject
+     * @param \Closure $proceed
+     * @return string|null
      */
-    public function afterInitializeLinks(
-        \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks $subject,
-        \Magento\Catalog\Model\Product $product
+    public function aroundGetConfigPath(
+        \Magento\Backend\Model\Config\Structure\Element\Field $subject,
+        \Closure $proceed
     ) {
-        $links = $this->request->getPost('links');
-
-        if (isset($links['grouped']) && !$product->getGroupedReadonly()) {
-            $product->setGroupedLinkData((array)$links['grouped']);
+        $configPath = $proceed();
+        if (!isset($configPath) && $this->_request->getParam('section') == 'payment') {
+            $configPath = preg_replace('@^(' . implode(
+                '|',
+                \Magento\Paypal\Model\Config\StructurePlugin::getPaypalConfigCountries(true)
+            ) . ')/@', 'payment/', $subject->getPath());
         }
-
-        return $product;
+        return $configPath;
     }
 }
diff --git a/app/code/Magento/Paypal/Model/Config/StructurePlugin.php b/app/code/Magento/Paypal/Model/Config/StructurePlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..b69557e61914e6089201edae727c9589581a561a
--- /dev/null
+++ b/app/code/Magento/Paypal/Model/Config/StructurePlugin.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Model\Config;
+
+class StructurePlugin
+{
+    /**
+     * Request parameter name
+     */
+    const REQUEST_PARAM_COUNTRY = 'paypal_country';
+
+    /**
+     * @var \Magento\Paypal\Helper\Backend
+     */
+    protected $_helper;
+
+    /**
+     * @var \Magento\Backend\Model\Config\ScopeDefiner
+     */
+    protected $_scopeDefiner;
+
+    /**
+     * @var string[]
+     */
+    private static $_paypalConfigCountries = [
+        'payment_us',
+        'payment_ca',
+        'payment_au',
+        'payment_gb',
+        'payment_jp',
+        'payment_fr',
+        'payment_it',
+        'payment_es',
+        'payment_hk',
+        'payment_nz',
+        'payment_de'
+    ];
+
+    /**
+     * @param \Magento\Backend\Model\Config\ScopeDefiner $scopeDefiner
+     * @param \Magento\Paypal\Helper\Backend $helper
+     */
+    public function __construct(
+        \Magento\Backend\Model\Config\ScopeDefiner $scopeDefiner,
+        \Magento\Paypal\Helper\Backend $helper
+    ) {
+        $this->_scopeDefiner = $scopeDefiner;
+        $this->_helper = $helper;
+    }
+
+    /**
+     * Get paypal configuration countries
+     *
+     * @param bool $addOther
+     * @return string[]
+     */
+    public static function getPaypalConfigCountries($addOther = false)
+    {
+        $countries = self::$_paypalConfigCountries;
+        if ($addOther) {
+            $countries[] = 'payment_other';
+        }
+        return $countries;
+    }
+
+    /**
+     * Substitute payment section with PayPal configs
+     *
+     * @param \Magento\Backend\Model\Config\Structure $subject
+     * @param \Closure $proceed
+     * @param array $pathParts
+     * @return \Magento\Backend\Model\Config\Structure\ElementInterface
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundGetElementByPathParts(
+        \Magento\Backend\Model\Config\Structure $subject,
+        \Closure $proceed,
+        array $pathParts
+    ) {
+        $isSectionChanged = $pathParts[0] == 'payment';
+        if ($isSectionChanged) {
+            $requestedCountrySection = 'payment_' . strtolower($this->_helper->getConfigurationCountryCode());
+            if (in_array($requestedCountrySection, self::getPaypalConfigCountries())) {
+                $pathParts[0] = $requestedCountrySection;
+            } else {
+                $pathParts[0] = 'payment_other';
+            }
+        }
+        /** @var \Magento\Backend\Model\Config\Structure\ElementInterface $result */
+        $result = $proceed($pathParts);
+        if ($isSectionChanged && isset($result)) {
+            if ($result instanceof \Magento\Backend\Model\Config\Structure\Element\Section) {
+                $result->setData(array_merge(
+                    $result->getData(),
+                    ['showInDefault' => true, 'showInWebsite' => true, 'showInStore' => true]
+                ), $this->_scopeDefiner->getScope());
+            }
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Paypal/Model/Direct.php b/app/code/Magento/Paypal/Model/Direct.php
index f16a3aee13a94d1541999e1e0f314b8d30e807c5..392c2b8eb9213962f402b33b430c069f1d6b9943 100644
--- a/app/code/Magento/Paypal/Model/Direct.php
+++ b/app/code/Magento/Paypal/Model/Direct.php
@@ -129,18 +129,6 @@ class Direct extends \Magento\Payment\Model\Method\Cc
      */
     protected $_pro;
 
-    /**
-     * Website Payments Pro instance type
-     *
-     * @var $_proType string
-     */
-    protected $_proType = 'Magento\Paypal\Model\Pro';
-
-    /**
-     * @var \Magento\Paypal\Model\Method\ProTypeFactory
-     */
-    protected $_proTypeFactory;
-
     /**
      * @var \Magento\Store\Model\StoreManagerInterface
      */
@@ -170,7 +158,7 @@ class Direct extends \Magento\Payment\Model\Method\Cc
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
-     * @param \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory
+     * @param \Magento\Paypal\Model\ProFactory $proFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $urlBuilder
      * @param \Magento\Framework\App\RequestInterface $requestHttp
@@ -188,7 +176,7 @@ class Direct extends \Magento\Payment\Model\Method\Cc
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
-        \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory,
+        \Magento\Paypal\Model\ProFactory $proFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Framework\App\RequestInterface $requestHttp,
@@ -206,7 +194,6 @@ class Direct extends \Magento\Payment\Model\Method\Cc
             $centinelService,
             $data
         );
-        $this->_proTypeFactory = $proTypeFactory;
         $this->_storeManager = $storeManager;
         $this->_urlBuilder = $urlBuilder;
         $this->_requestHttp = $requestHttp;
@@ -216,7 +203,7 @@ class Direct extends \Magento\Payment\Model\Method\Cc
         if ($proInstance && $proInstance instanceof \Magento\Paypal\Model\Pro) {
             $this->_pro = $proInstance;
         } else {
-            $this->_pro = $this->_proTypeFactory->create($this->_proType);
+            $this->_pro = $proFactory->create();
         }
         $this->_pro->setMethod($this->_code);
     }
@@ -267,7 +254,7 @@ class Direct extends \Magento\Payment\Model\Method\Cc
      */
     public function getAllowedCcTypes()
     {
-        $ccTypes = explode(',', $this->_pro->getConfig()->cctypes);
+        $ccTypes = explode(',', $this->_pro->getConfig()->getConfigValue('cctypes'));
         $country = $this->_pro->getConfig()->getMerchantCountry();
 
         if ($country == 'GB') {
@@ -307,7 +294,7 @@ class Direct extends \Magento\Payment\Model\Method\Cc
                 $value = $this->getAllowedCcTypes();
                 break;
             default:
-                $value = $this->_pro->getConfig()->{$field};
+                $value = $this->_pro->getConfig()->getConfigValue($field);
         }
         return $value;
     }
@@ -421,7 +408,7 @@ class Direct extends \Magento\Payment\Model\Method\Cc
     {
         $validator = parent::getCentinelValidator();
         if (!$validator->getCustomApiEndpointUrl()) {
-            $validator->setCustomApiEndpointUrl($this->_pro->getConfig()->centinelDefaultApiUrl);
+            $validator->setCustomApiEndpointUrl($this->_pro->getConfig()->getConfigValue('centinelDefaultApiUrl'));
         }
         return $validator;
     }
@@ -449,7 +436,7 @@ class Direct extends \Magento\Payment\Model\Method\Cc
     {
         $order = $payment->getOrder();
         $api = $this->_pro->getApi()->setPaymentAction(
-            $this->_pro->getConfig()->paymentAction
+            $this->_pro->getConfig()->getConfigValue('paymentAction')
         )->setIpAddress(
             $this->_requestHttp->getClientIp(false)
         )->setAmount(
@@ -493,7 +480,7 @@ class Direct extends \Magento\Payment\Model\Method\Cc
         // add line items
         $cart = $this->_cartFactory->create(array('salesModel' => $order));
 
-        $api->setPaypalCart($cart)->setIsLineItemsEnabled($this->_pro->getConfig()->lineItemsEnabled);
+        $api->setPaypalCart($cart)->setIsLineItemsEnabled($this->_pro->getConfig()->getConfigValue('lineItemsEnabled'));
 
         // call api and import transaction and other payment information
         $api->callDoDirectPayment();
diff --git a/app/code/Magento/Paypal/Model/Express.php b/app/code/Magento/Paypal/Model/Express.php
index c954207a604c25adc70aae5f35a54fb17ca7427f..6a48cd19f66ba1e98b080fa64efa58fb54f718dd 100644
--- a/app/code/Magento/Paypal/Model/Express.php
+++ b/app/code/Magento/Paypal/Model/Express.php
@@ -49,13 +49,6 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
      */
     protected $_infoBlockType = 'Magento\Paypal\Block\Payment\Info';
 
-    /**
-     * Website Payments Pro instance type
-     *
-     * @var $_proType string
-     */
-    protected $_proType = 'Magento\Paypal\Model\Pro';
-
     /**
      * Availability option
      *
@@ -161,11 +154,6 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
      */
     protected $_authorizationCountKey = 'authorization_count';
 
-    /**
-     * @var \Magento\Paypal\Model\Method\ProTypeFactory
-     */
-    protected $_proTypeFactory;
-
     /**
      * @var \Magento\Store\Model\StoreManagerInterface
      */
@@ -186,7 +174,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory
+     * @param ProFactory $proFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $urlBuilder
      * @param \Magento\Paypal\Model\CartFactory $cartFactory
@@ -197,14 +185,13 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory,
+        ProFactory $proFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Paypal\Model\CartFactory $cartFactory,
         array $data = array()
     ) {
         parent::__construct($eventManager, $paymentData, $scopeConfig, $logAdapterFactory, $data);
-        $this->_proTypeFactory = $proTypeFactory;
         $this->_storeManager = $storeManager;
         $this->_urlBuilder = $urlBuilder;
         $this->_cartFactory = $cartFactory;
@@ -213,7 +200,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
         if ($proInstance && $proInstance instanceof \Magento\Paypal\Model\Pro) {
             $this->_pro = $proInstance;
         } else {
-            $this->_pro = $this->_proTypeFactory->create($this->_proType);
+            $this->_pro = $proFactory->create();
         }
         $this->_pro->setMethod($this->_code);
     }
@@ -299,7 +286,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
      */
     public function getConfigData($field, $storeId = null)
     {
-        return $this->_pro->getConfig()->{$field};
+        return $this->_pro->getConfig()->getConfigValue($field);
     }
 
     /**
@@ -622,7 +609,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
         )->setAmount(
             $amount
         )->setPaymentAction(
-            $this->_pro->getConfig()->paymentAction
+            $this->_pro->getConfig()->getConfigValue('paymentAction')
         )->setNotifyUrl(
             $this->_urlBuilder->getUrl('paypal/ipn/')
         )->setInvNum(
@@ -632,7 +619,7 @@ class Express extends \Magento\Payment\Model\Method\AbstractMethod
         )->setPaypalCart(
             $cart
         )->setIsLineItemsEnabled(
-            $this->_pro->getConfig()->lineItemsEnabled
+            $this->_pro->getConfig()->getConfigValue('lineItemsEnabled')
         );
         if ($order->getIsVirtual()) {
             $api->setAddress($order->getBillingAddress())->setSuppressShipping(true);
diff --git a/app/code/Magento/Paypal/Model/Express/Checkout.php b/app/code/Magento/Paypal/Model/Express/Checkout.php
index 926dce9ac386511f75e37e51f64179c4aa645fb9..e014d89c4d517567aa81c883420312f90d537176 100644
--- a/app/code/Magento/Paypal/Model/Express/Checkout.php
+++ b/app/code/Magento/Paypal/Model/Express/Checkout.php
@@ -483,8 +483,8 @@ class Checkout
             ->setInvNum($this->_quote->getReservedOrderId())
             ->setReturnUrl($returnUrl)
             ->setCancelUrl($cancelUrl)
-            ->setSolutionType($this->_config->solutionType)
-            ->setPaymentAction($this->_config->paymentAction)
+            ->setSolutionType($this->_config->getConfigValue('solutionType'))
+            ->setPaymentAction($this->_config->getConfigValue('paymentAction'))
         ;
         if ($this->_giropayUrls) {
             list($successUrl, $cancelUrl, $pendingUrl) = $this->_giropayUrls;
@@ -499,13 +499,13 @@ class Checkout
 
         $this->_setBillingAgreementRequest();
 
-        if ($this->_config->requireBillingAddress == PaypalConfig::REQUIRE_BILLING_ADDRESS_ALL) {
+        if ($this->_config->getConfigValue('requireBillingAddress') == PaypalConfig::REQUIRE_BILLING_ADDRESS_ALL) {
             $this->_api->setRequireBillingAddress(1);
         }
 
         // suppress or export shipping address
         if ($this->_quote->getIsVirtual()) {
-            if ($this->_config->requireBillingAddress == PaypalConfig::REQUIRE_BILLING_ADDRESS_VIRTUAL) {
+            if ($this->_config->getConfigValue('requireBillingAddress') == PaypalConfig::REQUIRE_BILLING_ADDRESS_VIRTUAL) {
                 $this->_api->setRequireBillingAddress(1);
             }
             $this->_api->setSuppressShipping(true);
@@ -527,11 +527,14 @@ class Checkout
         /** @var $cart \Magento\Payment\Model\Cart */
         $cart = $this->_cartFactory->create(array('salesModel' => $this->_quote));
         $this->_api->setPaypalCart($cart)
-            ->setIsLineItemsEnabled($this->_config->lineItemsEnabled);
+            ->setIsLineItemsEnabled($this->_config->getConfigValue('lineItemsEnabled'));
 
         // add shipping options if needed and line items are available
         $cartItems = $cart->getAllItems();
-        if ($this->_config->lineItemsEnabled && $this->_config->transferShippingOptions && !empty($cartItems)) {
+        if ($this->_config->getConfigValue('lineItemsEnabled')
+            && $this->_config->getConfigValue('transferShippingOptions')
+            && !empty($cartItems)
+        ) {
             if (!$this->_quote->getIsVirtual() && !$this->_quote->hasNominalItems()) {
                 $options = $this->_prepareShippingOptions($address, true);
                 if ($options) {
@@ -816,7 +819,9 @@ class Checkout
         $this->_quote->getBillingAddress()->setShouldIgnoreValidation(true);
         if (!$this->_quote->getIsVirtual()) {
             $this->_quote->getShippingAddress()->setShouldIgnoreValidation(true);
-            if (!$this->_config->requireBillingAddress && !$this->_quote->getBillingAddress()->getEmail()) {
+            if (!$this->_config->getConfigValue('requireBillingAddress')
+                && !$this->_quote->getBillingAddress()->getEmail()
+            ) {
                 $this->_quote->getBillingAddress()->setSameAsBilling(1);
             }
         }
@@ -913,7 +918,7 @@ class Checkout
         $isRequested = $this->_isBARequested || $this->_quote->getPayment()
             ->getAdditionalInformation(self::PAYMENT_INFO_TRANSPORT_BILLING_AGREEMENT);
 
-        if (!($this->_config->allow_ba_signup == PaypalConfig::EC_BA_SIGNUP_AUTO
+        if (!($this->_config->getConfigValue('allow_ba_signup') == PaypalConfig::EC_BA_SIGNUP_AUTO
             || $isRequested && $this->_config->shouldAskToCreateBillingAgreement())
         ) {
             return $this;
diff --git a/app/code/Magento/Paypal/Model/Hostedpro.php b/app/code/Magento/Paypal/Model/Hostedpro.php
index afcd305a69a87282684a92d4995391be9ba26d19..c887fde91d128163c9b4706f3ef10c8f9a657a91 100644
--- a/app/code/Magento/Paypal/Model/Hostedpro.php
+++ b/app/code/Magento/Paypal/Model/Hostedpro.php
@@ -95,7 +95,7 @@ class Hostedpro extends \Magento\Paypal\Model\Direct
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Centinel\Model\Service $centinelService
-     * @param \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory
+     * @param \Magento\Paypal\Model\ProFactory $proFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $urlBuilder
      * @param \Magento\Framework\App\RequestInterface $requestHttp
@@ -114,7 +114,7 @@ class Hostedpro extends \Magento\Paypal\Model\Direct
         \Magento\Framework\Module\ModuleListInterface $moduleList,
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Centinel\Model\Service $centinelService,
-        \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory,
+        \Magento\Paypal\Model\ProFactory $proFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Framework\App\RequestInterface $requestHttp,
@@ -132,7 +132,7 @@ class Hostedpro extends \Magento\Paypal\Model\Direct
             $moduleList,
             $localeDate,
             $centinelService,
-            $proTypeFactory,
+            $proFactory,
             $storeManager,
             $urlBuilder,
             $requestHttp,
diff --git a/app/code/Magento/Paypal/Model/Info.php b/app/code/Magento/Paypal/Model/Info.php
index 2d1b90150b9addd1883ac5e409f0746f7b61f05c..2b6874fca2d1ef885d4a342f83e2f546157b0a2d 100644
--- a/app/code/Magento/Paypal/Model/Info.php
+++ b/app/code/Magento/Paypal/Model/Info.php
@@ -91,16 +91,16 @@ class Info
      * @var array
      */
     protected $_paymentMap = array(
-        self::PAYER_ID => 'paypal_payer_id',
-        self::PAYER_EMAIL => 'paypal_payer_email',
-        self::PAYER_STATUS => 'paypal_payer_status',
-        self::ADDRESS_ID => 'paypal_address_id',
-        self::ADDRESS_STATUS => 'paypal_address_status',
-        self::PROTECTION_EL => 'paypal_protection_eligibility',
-        self::FRAUD_FILTERS => 'paypal_fraud_filters',
-        self::CORRELATION_ID => 'paypal_correlation_id',
-        self::AVS_CODE => 'paypal_avs_code',
-        self::CVV2_MATCH => 'paypal_cvv2_match',
+        self::PAYER_ID => self::PAYPAL_PAYER_ID,
+        self::PAYER_EMAIL => self::PAYPAL_PAYER_EMAIL,
+        self::PAYER_STATUS => self::PAYPAL_PAYER_STATUS,
+        self::ADDRESS_ID => self::PAYPAL_ADDRESS_ID,
+        self::ADDRESS_STATUS => self::PAYPAL_ADDRESS_STATUS,
+        self::PROTECTION_EL => self::PAYPAL_PROTECTION_ELIGIBILITY,
+        self::FRAUD_FILTERS => self::PAYPAL_FRAUD_FILTERS,
+        self::CORRELATION_ID => self::PAYPAL_CORRELATION_ID,
+        self::AVS_CODE => self::PAYPAL_AVS_CODE,
+        self::CVV2_MATCH => self::PAYPAL_CVV2_MATCH,
         self::CENTINEL_VPAS => self::CENTINEL_VPAS,
         self::CENTINEL_ECI => self::CENTINEL_ECI,
         self::BUYER_TAX_ID => self::BUYER_TAX_ID,
@@ -187,6 +187,68 @@ class Info
      */
     protected $_paymentMapFull = array();
 
+    /**
+     * Cache for storing label translations
+     *
+     * @var array
+     */
+    protected $_labelCodesCache = [];
+
+    /**
+     * Paypal payer id code key
+     */
+    const PAYPAL_PAYER_ID = 'paypal_payer_id';
+
+    /**
+     * Paypal payer email code key
+     */
+    const PAYPAL_PAYER_EMAIL = 'paypal_payer_email';
+
+    /**
+     * Paypal payer status code key
+     */
+    const PAYPAL_PAYER_STATUS = 'paypal_payer_status';
+
+    /**
+     * Paypal address id code key
+     */
+    const PAYPAL_ADDRESS_ID = 'paypal_address_id';
+
+    /**
+     * Paypal address status code key
+     */
+    const PAYPAL_ADDRESS_STATUS = 'paypal_address_status';
+
+    /**
+     * Paypal protection eligibility code key
+     */
+    const PAYPAL_PROTECTION_ELIGIBILITY = 'paypal_protection_eligibility';
+
+    /**
+     * Paypal fraud filters code key
+     */
+    const PAYPAL_FRAUD_FILTERS = 'paypal_fraud_filters';
+
+    /**
+     * Paypal correlation id code key
+     */
+    const PAYPAL_CORRELATION_ID = 'paypal_correlation_id';
+
+    /**
+     * Paypal avs code key
+     */
+    const PAYPAL_AVS_CODE = 'paypal_avs_code';
+
+    /**
+     * Paypal cvv2 code key
+     */
+    const PAYPAL_CVV2_MATCH = 'paypal_cvv2_match';
+
+    /**
+     * Item labels key for label codes cache
+     */
+    const ITEM_LABELS = 'item labels';
+
     /**
      * All available payment info getter
      *
@@ -409,7 +471,7 @@ class Info
      */
     public static function explainReasonCode($code)
     {
-        $comments = array(
+        $comments = [
             'chargeback' => __('A reversal has occurred on this transaction due to a chargeback by your customer.'),
             'guarantee' => __(
                 'A reversal has occurred on this transaction due to your customer triggering a money-back guarantee.'
@@ -439,14 +501,10 @@ class Info
             'adjustment_reimburse' => __('A case that has been resolved and close requires a reimbursement.'),
             'duplicate' => __('Buyer claims that a possible duplicate payment was made to the merchant.'),
             'merchandise' => __('Buyer claims that the received merchandise is unsatisfactory, defective, or damaged.')
-        );
-        $value = array_key_exists(
-            $code,
-            $comments
-        ) && !empty($comments[$code]) ? $comments[$code] : __(
-            'Unknown reason. Please contact PayPal customer service.'
-        );
-        return $value;
+        ];
+        return isset($comments[$code])
+            ? $comments[$code]
+            : __('Unknown reason. Please contact PayPal customer service.');
     }
 
     /**
@@ -457,21 +515,18 @@ class Info
      */
     public static function isReversalDisputable($code)
     {
-        switch ($code) {
-            case 'none':
-            case 'other':
-            case 'chargeback':
-            case 'buyer-complaint':
-            case 'buyer_complaint':
-            case 'adjustment_reversal':
-                return true;
-            case 'guarantee':
-            case 'refund':
-            case 'chargeback_reimbursement':
-            case 'chargeback_settlement':
-            default:
-                return false;
-        }
+        $listOfDisputeCodes = [
+            'none' => true,
+            'other' => true,
+            'chargeback' => true,
+            'buyer-complaint' => true,
+            'adjustment_reversal' => true,
+            'guarantee' => false,
+            'refund' => false,
+            'chargeback_reimbursement' => false,
+            'chargeback_settlement' => false,
+        ];
+        return isset($listOfDisputeCodes[$code]) ? $listOfDisputeCodes[$code] : false;
     }
 
     /**
@@ -518,37 +573,27 @@ class Info
      */
     protected function _getLabel($key)
     {
-        switch ($key) {
-            case 'paypal_payer_id':
-                return __('Payer ID');
-            case 'paypal_payer_email':
-                return __('Payer Email');
-            case 'paypal_payer_status':
-                return __('Payer Status');
-            case 'paypal_address_id':
-                return __('Payer Address ID');
-            case 'paypal_address_status':
-                return __('Payer Address Status');
-            case 'paypal_protection_eligibility':
-                return __('Merchant Protection Eligibility');
-            case 'paypal_fraud_filters':
-                return __('Triggered Fraud Filters');
-            case 'paypal_correlation_id':
-                return __('Last Correlation ID');
-            case 'paypal_avs_code':
-                return __('Address Verification System Response');
-            case 'paypal_cvv2_match':
-                return __('CVV2 Check Result by PayPal');
-            case self::BUYER_TAX_ID:
-                return __('Buyer\'s Tax ID');
-            case self::BUYER_TAX_ID_TYPE:
-                return __('Buyer\'s Tax ID Type');
-            case self::CENTINEL_VPAS:
-                return __('PayPal/Centinel Visa Payer Authentication Service Result');
-            case self::CENTINEL_ECI:
-                return __('PayPal/Centinel Electronic Commerce Indicator');
+        if (!isset($this->_labelCodesCache[self::ITEM_LABELS])) {
+            $this->_labelCodesCache[self::ITEM_LABELS] = [
+                self::PAYPAL_PAYER_ID => __('Payer ID'),
+                self::PAYPAL_PAYER_EMAIL=> __('Payer Email'),
+                self::PAYPAL_PAYER_STATUS => __('Payer Status'),
+                self::PAYPAL_ADDRESS_ID => __('Payer Address ID'),
+                self::PAYPAL_ADDRESS_STATUS => __('Payer Address Status'),
+                self::PAYPAL_PROTECTION_ELIGIBILITY=> __('Merchant Protection Eligibility'),
+                self::PAYPAL_FRAUD_FILTERS => __('Triggered Fraud Filters'),
+                self::PAYPAL_CORRELATION_ID => __('Last Correlation ID'),
+                self::PAYPAL_AVS_CODE => __('Address Verification System Response'),
+                self::PAYPAL_CVV2_MATCH => __('CVV2 Check Result by PayPal'),
+                self::BUYER_TAX_ID => __('Buyer\'s Tax ID'),
+                self::BUYER_TAX_ID_TYPE => __('Buyer\'s Tax ID Type'),
+                self::CENTINEL_VPAS => __('PayPal/Centinel Visa Payer Authentication Service Result'),
+                self::CENTINEL_ECI => __('PayPal/Centinel Electronic Commerce Indicator')
+            ];
         }
-        return '';
+        return isset($this->_labelCodesCache[self::ITEM_LABELS][$key])
+            ? $this->_labelCodesCache[self::ITEM_LABELS][$key]
+            : '';
     }
 
     /**
@@ -559,8 +604,12 @@ class Info
      */
     public static function getCaseTypeLabel($key)
     {
-        $labels = array('chargeback' => __('Chargeback'), 'complaint' => __('Complaint'), 'dispute' => __('Dispute'));
-        $value = array_key_exists($key, $labels) && !empty($labels[$key]) ? $labels[$key] : '';
+        $labels = [
+            'chargeback' => __('Chargeback'),
+            'complaint' => __('Complaint'),
+            'dispute' => __('Dispute')
+        ];
+        $value = isset($labels[$key]) ? $labels[$key] : '';
         return $value;
     }
 
@@ -575,10 +624,10 @@ class Info
     {
         $label = '';
         switch ($key) {
-            case 'paypal_avs_code':
+            case self::PAYPAL_AVS_CODE:
                 $label = $this->_getAvsLabel($value);
                 break;
-            case 'paypal_cvv2_match':
+            case self::PAYPAL_CVV2_MATCH:
                 $label = $this->_getCvv2Label($value);
                 break;
             case self::CENTINEL_VPAS:
@@ -605,64 +654,42 @@ class Info
      */
     protected function _getAvsLabel($value)
     {
-        switch ($value) {
-            // Visa, MasterCard, Discover and American Express
-            case 'A':
-            case 'YN':
-                return __('Matched Address only (no ZIP)');
-            case 'B':
+        if (!isset($this->_labelCodesCache[self::PAYPAL_AVS_CODE])) {
+            $this->_labelCodesCache[self::PAYPAL_AVS_CODE] = [
+                // Visa, MasterCard, Discover and American Express
+                'A' => __('Matched Address only (no ZIP)'),
                 // international "A"
-                return __('Matched Address only (no ZIP) International');
-            case 'N':
-                return __('No Details matched');
-            case 'C':
+                'B' => __('Matched Address only (no ZIP) International'),
+                'N' => __('No Details matched'),
                 // international "N"
-                return __('No Details matched. International');
-            case 'X':
-                return __('Exact Match. Address and nine-digit ZIP code');
-            case 'D':
+                'C' => __('No Details matched. International'),
+                'X' => __('Exact Match. Address and nine-digit ZIP code'),
                 // international "X"
-                return __('Exact Match. Address and Postal Code. International');
-            case 'F':
+                'D' => __('Exact Match. Address and Postal Code. International'),
                 // UK-specific "X"
-                return __('Exact Match. Address and Postal Code. UK-specific');
-            case 'E':
-                return __('N/A. Not allowed for MOTO (Internet/Phone) transactions');
-            case 'G':
-                return __('N/A. Global Unavailable');
-            case 'I':
-                return __('N/A. International Unavailable');
-            case 'Z':
-            case 'NY':
-                return __('Matched five-digit ZIP only (no Address)');
-            case 'P':
+                'F' => __('Exact Match. Address and Postal Code. UK-specific'),
+                'E' => __('N/A. Not allowed for MOTO (Internet/Phone) transactions'),
+                'G' => __('N/A. Global Unavailable'),
+                'I' => __('N/A. International Unavailable'),
+                'Z' => __('Matched five-digit ZIP only (no Address)'),
                 // international "Z"
-            case 'NY':
-                return __('Matched Postal Code only (no Address)');
-            case 'R':
-                return __('N/A. Retry');
-            case 'S':
-                return __('N/A. Service not Supported');
-            case 'U':
-                return __('N/A. Unavailable');
-            case 'W':
-                return __('Matched whole nine-didgit ZIP (no Address)');
-            case 'Y':
-                return __('Yes. Matched Address and five-didgit ZIP');
+                'P' => __('Matched Postal Code only (no Address)'),
+                'R' => __('N/A. Retry'),
+                'S' => __('N/A. Service not Supported'),
+                'U' => __('N/A. Unavailable'),
+                'W' => __('Matched whole nine-didgit ZIP (no Address)'),
+                'Y' => __('Yes. Matched Address and five-didgit ZIP'),
                 // Maestro and Solo
-            case '0':
-                return __('All the address information matched');
-            case '1':
-                return __('None of the address information matched');
-            case '2':
-                return __('Part of the address information matched');
-            case '3':
-                return __('N/A. The merchant did not provide AVS information');
-            case '4':
-                return __('N/A. Address not checked, or acquirer had no response. Service not available');
-            default:
-                return $value;
+                '0' => __('All the address information matched'),
+                '1' => __('None of the address information matched'),
+                '2' => __('Part of the address information matched'),
+                '3' => __('N/A. The merchant did not provide AVS information'),
+                '4' => __('N/A. Address not checked, or acquirer had no response. Service not available')
+            ];
         }
+        return isset($this->_labelCodesCache[self::PAYPAL_AVS_CODE][$value])
+            ? $this->_labelCodesCache[self::PAYPAL_AVS_CODE][$value]
+            : $value;
     }
 
     /**
@@ -674,34 +701,26 @@ class Info
      */
     protected function _getCvv2Label($value)
     {
-        switch ($value) {
-            // Visa, MasterCard, Discover and American Express
-            case 'M':
-                return __('Matched (CVV2CSC)');
-            case 'N':
-                return __('No match');
-            case 'P':
-                return __('N/A. Not processed');
-            case 'S':
-                return __('N/A. Service not supported');
-            case 'U':
-                return __('N/A. Service not available');
-            case 'X':
-                return __('N/A. No response');
+        if (!isset($this->_labelCodesCache[self::PAYPAL_CVV2_MATCH])) {
+            $this->_labelCodesCache[self::PAYPAL_CVV2_MATCH] = [
+                // Visa, MasterCard, Discover and American Express
+                'M' => __('Matched (CVV2CSC)'),
+                'N' => __('No match'),
+                'P' => __('N/A. Not processed'),
+                'S' => __('N/A. Service not supported'),
+                'U' => __('N/A. Service not available'),
+                'X' => __('N/A. No response'),
                 // Maestro and Solo
-            case '0':
-                return __('Matched (CVV2)');
-            case '1':
-                return __('No match');
-            case '2':
-                return __('N/A. The merchant has not implemented CVV2 code handling');
-            case '3':
-                return __('N/A. Merchant has indicated that CVV2 is not present on card');
-            case '4':
-                return __('N/A. Service not available');
-            default:
-                return $value;
+                '0' => __('Matched (CVV2)'),
+                '1' => __('No match'),
+                '2' => __('N/A. The merchant has not implemented CVV2 code handling'),
+                '3' => __('N/A. Merchant has indicated that CVV2 is not present on card'),
+                '4' => __('N/A. Service not available')
+            ];
         }
+        return isset($this->_labelCodesCache[self::PAYPAL_CVV2_MATCH][$value])
+            ? $this->_labelCodesCache[self::PAYPAL_CVV2_MATCH][$value]
+            : $value;
     }
 
     /**
@@ -713,29 +732,27 @@ class Info
      */
     private function _getCentinelVpasLabel($value)
     {
-        switch ($value) {
-            case '2':
-            case 'D':
-                return __('Authenticated, Good Result');
-            case '1':
-                return __('Authenticated, Bad Result');
-            case '3':
-            case '6':
-            case '8':
-            case 'A':
-            case 'C':
-                return __('Attempted Authentication, Good Result');
-            case '4':
-            case '7':
-            case '9':
-                return __('Attempted Authentication, Bad Result');
-            case '':
-            case '0':
-            case 'B':
-                return __('No Liability Shift');
-            default:
-                return $value;
+        if (!isset($this->_labelCodesCache[self::CENTINEL_VPAS])) {
+            $this->_labelCodesCache[self::CENTINEL_VPAS] = [
+                '2' => __('Authenticated, Good Result'),
+                'D' => __('Authenticated, Good Result'),
+                '1' => __('Authenticated, Bad Result'),
+                '3' => __('Attempted Authentication, Good Result'),
+                '6' => __('Attempted Authentication, Good Result'),
+                '8' => __('Attempted Authentication, Good Result'),
+                'A' => __('Attempted Authentication, Good Result'),
+                'C' => __('Attempted Authentication, Good Result'),
+                '4' => __('Attempted Authentication, Bad Result'),
+                '7' => __('Attempted Authentication, Bad Result'),
+                '9' => __('Attempted Authentication, Bad Result'),
+                '' => __('No Liability Shift'),
+                '0' => __('No Liability Shift'),
+                'B' => __('No Liability Shift')
+            ];
         }
+        return isset($this->_labelCodesCache[self::CENTINEL_VPAS][$value])
+            ? $this->_labelCodesCache[self::CENTINEL_VPAS][$value]
+            : $value;
     }
 
     /**
@@ -747,17 +764,18 @@ class Info
      */
     private function _getCentinelEciLabel($value)
     {
-        switch ($value) {
-            case '01':
-            case '07':
-                return __('Merchant Liability');
-            case '02':
-            case '05':
-            case '06':
-                return __('Issuer Liability');
-            default:
-                return $value;
+        if (!isset($this->_labelCodesCache[self::CENTINEL_ECI])) {
+            $this->_labelCodesCache[self::CENTINEL_ECI] = [
+                '01' => __('Merchant Liability'),
+                '07' => __('Merchant Liability'),
+                '02' => __('Issuer Liability'),
+                '05' => __('Issuer Liability'),
+                '06' => __('Issuer Liability')
+            ];
         }
+        return isset($this->_labelCodesCache[self::CENTINEL_ECI][$value])
+            ? $this->_labelCodesCache[self::CENTINEL_ECI][$value]
+            : $value;
     }
 
     /**
@@ -768,15 +786,14 @@ class Info
      */
     protected function _getBuyerIdTypeValue($code)
     {
-        $value = '';
-        switch ($code) {
-            case self::BUYER_TAX_ID_TYPE_CNPJ:
-                $value = __('CNPJ');
-                break;
-            case self::BUYER_TAX_ID_TYPE_CPF:
-                $value = __('CPF');
-                break;
+        if (!isset($this->_labelCodesCache[self::BUYER_TAX_ID_TYPE])) {
+            $this->_labelCodesCache[self::BUYER_TAX_ID_TYPE] = [
+                self::BUYER_TAX_ID_TYPE_CNPJ => __('CNPJ'),
+                self::BUYER_TAX_ID_TYPE_CPF => __('CPF')
+            ];
         }
-        return $value;
+        return isset($this->_labelCodesCache[self::BUYER_TAX_ID_TYPE][$code])
+            ? $this->_labelCodesCache[self::BUYER_TAX_ID_TYPE][$code]
+            : '';
     }
 }
diff --git a/app/code/Magento/Paypal/Model/Ipn.php b/app/code/Magento/Paypal/Model/Ipn.php
index a1fe5bf3b1a8822ee1300bbc3d6018130b8e2ed8..493bd9bdee3d3ee827f3fb010c316f313345a001 100644
--- a/app/code/Magento/Paypal/Model/Ipn.php
+++ b/app/code/Magento/Paypal/Model/Ipn.php
@@ -107,7 +107,7 @@ class Ipn extends \Magento\Paypal\Model\AbstractIpn implements IpnInterface
         }
         /** @link https://cms.paypal.com/cgi-bin/marketingweb?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro */
         // verify merchant email intended to receive notification
-        $merchantEmail = $this->_config->businessAccount;
+        $merchantEmail = $this->_config->getConfigValue('businessAccount');
         if (!$merchantEmail) {
             return $this->_config;
         }
diff --git a/app/code/Magento/Paypal/Model/Method/Agreement.php b/app/code/Magento/Paypal/Model/Method/Agreement.php
index 843421a934579aacc7478cfd3cb4cc62666c40eb..2aa41c4c3ce140058fac69ccea19318e4863c1e8 100644
--- a/app/code/Magento/Paypal/Model/Method/Agreement.php
+++ b/app/code/Magento/Paypal/Model/Method/Agreement.php
@@ -139,7 +139,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
      * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
      * @param \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory
+     * @param \Magento\Paypal\Model\ProFactory $proFactory
      * @param \Magento\Framework\UrlInterface $urlBuilder
      * @param \Magento\Paypal\Model\CartFactory $cartFactory
      * @param array $data
@@ -153,7 +153,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
         \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
         \Magento\Paypal\Model\Billing\AgreementFactory $agreementFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
-        \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory,
+        \Magento\Paypal\Model\ProFactory $proFactory,
         \Magento\Framework\UrlInterface $urlBuilder,
         \Magento\Paypal\Model\CartFactory $cartFactory,
         array $data = array()
@@ -173,7 +173,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
         if ($proInstance && $proInstance instanceof \Magento\Paypal\Model\Pro) {
             $this->_pro = $proInstance;
         } else {
-            $this->_pro = $proTypeFactory->create('Magento\Paypal\Model\Pro');
+            $this->_pro = $proFactory->create();
         }
         $this->_pro->setMethod($this->_code);
     }
@@ -412,7 +412,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
         $api = $this->_pro->getApi()->setReferenceId(
             $billingAgreement->getReferenceId()
         )->setPaymentAction(
-            $proConfig->paymentAction
+            $proConfig->getConfigValue('paymentAction')
         )->setAmount(
             $amount
         )->setCurrencyCode(
@@ -422,7 +422,7 @@ class Agreement extends \Magento\Paypal\Model\Payment\Method\Billing\AbstractAgr
         )->setPaypalCart(
             $cart
         )->setIsLineItemsEnabled(
-            $proConfig->lineItemsEnabled
+            $proConfig->getConfigValue('lineItemsEnabled')
         )->setInvNum(
             $order->getIncrementId()
         );
diff --git a/app/code/Magento/Paypal/Model/PayflowDirect.php b/app/code/Magento/Paypal/Model/PayflowDirect.php
deleted file mode 100644
index 998f2bd5c0f26c34078cb669faa48a3c410ee290..0000000000000000000000000000000000000000
--- a/app/code/Magento/Paypal/Model/PayflowDirect.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Paypal\Model;
-
-class PayflowDirect extends \Magento\Paypal\Model\Direct
-{
-    /**
-     * @var string
-     */
-    protected $_code = \Magento\Paypal\Model\Config::METHOD_WPP_PE_DIRECT;
-
-    /**
-     * Website Payments Pro instance type
-     *
-     * @var string
-     */
-    protected $_proType = 'Magento\Paypal\Model\Payflow\Pro';
-
-    /**
-     * Return available CC types for gateway based on merchant country
-     *
-     * @return string
-     */
-    public function getAllowedCcTypes()
-    {
-        return $this->_pro->getConfig()->cctypes;
-    }
-
-    /**
-     * Merchant country limitation for 3d secure feature, rewrite for parent implementation
-     *
-     * @return bool
-     */
-    public function getIsCentinelValidationEnabled()
-    {
-        if (!parent::getIsCentinelValidationEnabled()) {
-            return false;
-        }
-        // available only for US and UK merchants
-        if (in_array($this->_pro->getConfig()->getMerchantCountry(), array('US', 'GB'))) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Import direct payment results to payment
-     *
-     * @param \Magento\Paypal\Model\Api\Nvp $api
-     * @param \Magento\Sales\Model\Order\Payment $payment
-     * @return void
-     */
-    protected function _importResultToPayment($api, $payment)
-    {
-        $payment->setTransactionId(
-            $api->getPaypalTransactionId()
-        )->setIsTransactionClosed(
-            0
-        )->setIsTransactionPending(
-            $api->getIsPaymentPending()
-        )->setTransactionAdditionalInfo(
-            \Magento\Paypal\Model\Payflow\Pro::TRANSPORT_PAYFLOW_TXN_ID,
-            $api->getTransactionId()
-        );
-        $payment->setPreparedMessage(__('Payflow PNREF: #%1.', $api->getTransactionId()));
-        $this->_pro->importPaymentInfo($api, $payment);
-    }
-
-    /**
-     * Format credit card expiration date based on month and year values
-     * Format: mmyy
-     *
-     * @param string|int $month
-     * @param string|int $year
-     * @return string
-     */
-    protected function _getFormattedCcExpirationDate($month, $year)
-    {
-        return sprintf('%02d', $month) . sprintf('%02d', substr($year, -2, 2));
-    }
-}
diff --git a/app/code/Magento/Paypal/Model/PayflowExpress.php b/app/code/Magento/Paypal/Model/PayflowExpress.php
index 911897733bd4dc3d3017d68f01ffd70d4d7e4c23..50d0c2081fbd61db6116389fdb628de956e9fffd 100644
--- a/app/code/Magento/Paypal/Model/PayflowExpress.php
+++ b/app/code/Magento/Paypal/Model/PayflowExpress.php
@@ -21,36 +21,32 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Paypal\Model;
 
+use Magento\Sales\Model\Order\Payment\Transaction;
+
 class PayflowExpress extends \Magento\Paypal\Model\Express
 {
     /**
      * @var string
      */
-    protected $_code = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+    protected $_code = Config::METHOD_WPP_PE_EXPRESS;
 
     /**
      * @var string
      */
     protected $_formBlockType = 'Magento\Paypal\Block\PayflowExpress\Form';
 
-    /**
-     * Website Payments Pro instance type
-     *
-     * @var $_proType string
-     */
-    protected $_proType = 'Magento\Paypal\Model\Payflow\Pro';
-
     /**
      * Express Checkout payment method instance
      *
-     * @var \Magento\Paypal\Model\Express
+     * @var Express
      */
     protected $_ecInstance = null;
 
     /**
-     * @var \Magento\Paypal\Model\InfoFactory
+     * @var InfoFactory
      */
     protected $_paypalInfoFactory;
 
@@ -59,11 +55,11 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
      * @param \Magento\Payment\Helper\Data $paymentData
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param \Magento\Framework\Logger\AdapterFactory $logAdapterFactory
-     * @param \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory
+     * @param ProFactory $proFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\UrlInterface $urlBuilder
-     * @param \Magento\Paypal\Model\CartFactory $cartFactory
-     * @param \Magento\Paypal\Model\InfoFactory $paypalInfoFactory
+     * @param CartFactory $cartFactory
+     * @param InfoFactory $paypalInfoFactory
      * @param array $data
      */
     public function __construct(
@@ -71,11 +67,11 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
         \Magento\Payment\Helper\Data $paymentData,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         \Magento\Framework\Logger\AdapterFactory $logAdapterFactory,
-        \Magento\Paypal\Model\Method\ProTypeFactory $proTypeFactory,
+        ProFactory $proFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\UrlInterface $urlBuilder,
-        \Magento\Paypal\Model\CartFactory $cartFactory,
-        \Magento\Paypal\Model\InfoFactory $paypalInfoFactory,
+        CartFactory $cartFactory,
+        InfoFactory $paypalInfoFactory,
         array $data = array()
     ) {
         parent::__construct(
@@ -83,7 +79,7 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
             $paymentData,
             $scopeConfig,
             $logAdapterFactory,
-            $proTypeFactory,
+            $proFactory,
             $storeManager,
             $urlBuilder,
             $cartFactory,
@@ -105,7 +101,7 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
         }
         if (!$this->_ecInstance) {
             $this->_ecInstance = $this->_paymentData->getMethodInstance(
-                \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS
+                Config::METHOD_WPP_EXPRESS
             );
         }
         if ($quote && $this->_ecInstance) {
@@ -117,7 +113,7 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
     /**
      * Import payment info to payment
      *
-     * @param \Magento\Paypal\Model\Api\Nvp $api
+     * @param Api\Nvp $api
      * @param \Magento\Sales\Model\Order\Payment $payment
      * @return void
      */
@@ -128,12 +124,12 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
         )->setIsTransactionClosed(
             0
         )->setAdditionalInformation(
-            \Magento\Paypal\Model\Express\Checkout::PAYMENT_INFO_TRANSPORT_REDIRECT,
+            Express\Checkout::PAYMENT_INFO_TRANSPORT_REDIRECT,
             $api->getRedirectRequired() || $api->getRedirectRequested()
         )->setIsTransactionPending(
             $api->getIsPaymentPending()
         )->setTransactionAdditionalInfo(
-            \Magento\Paypal\Model\Payflow\Pro::TRANSPORT_PAYFLOW_TXN_ID,
+            Payflow\Pro::TRANSPORT_PAYFLOW_TXN_ID,
             $api->getTransactionId()
         );
         $payment->setPreparedMessage(__('Payflow PNREF: #%1.', $api->getTransactionId()));
@@ -151,4 +147,22 @@ class PayflowExpress extends \Magento\Paypal\Model\Express
     {
         return $this->_urlBuilder->getUrl('paypal/payflowexpress/start');
     }
+
+    /**
+     * Check refund availability.
+     * The main factor is that the last capture transaction exists and has an Payflow\Pro::TRANSPORT_PAYFLOW_TXN_ID in
+     * additional information(needed to perform online refund. Requirement of the Payflow gateway)
+     *
+     * @return bool
+     */
+    public function canRefund()
+    {
+        /** @var \Magento\Sales\Model\Order\Payment $payment */
+        $payment = $this->getInfoInstance();
+        // we need the last capture transaction was made
+        $captureTransaction = $payment->lookupTransaction('', Transaction::TYPE_CAPTURE);
+        return $captureTransaction && $captureTransaction->getAdditionalInformation(
+            Payflow\Pro::TRANSPORT_PAYFLOW_TXN_ID
+        ) && $this->_canRefund;
+    }
 }
diff --git a/app/code/Magento/Paypal/Model/Standard.php b/app/code/Magento/Paypal/Model/Standard.php
index a4e0c231f7704ce756d7f615196fe546d5aecd52..db3685289c1ce3508759f0d8b17fe9357e8398ae 100644
--- a/app/code/Magento/Paypal/Model/Standard.php
+++ b/app/code/Magento/Paypal/Model/Standard.php
@@ -252,7 +252,7 @@ class Standard extends \Magento\Payment\Model\Method\AbstractMethod
 
         // add cart totals and line items
         $cart = $this->_cartFactory->create(array('salesModel' => $order));
-        $api->setPaypalCart($cart)->setIsLineItemsEnabled($this->_config->lineItemsEnabled);
+        $api->setPaypalCart($cart)->setIsLineItemsEnabled($this->_config->getConfigValue('lineItemsEnabled'));
         $api->setCartSummary($this->_getAggregatedCartSummary());
         $api->setLocale($api->getLocaleCode());
         $result = $api->getStandardCheckoutRequest();
@@ -313,7 +313,7 @@ class Standard extends \Magento\Payment\Model\Method\AbstractMethod
      */
     public function getConfigData($field, $storeId = null)
     {
-        return $this->getConfig()->{$field};
+        return $this->getConfig()->getConfigValue($field);
     }
 
     /**
@@ -323,8 +323,8 @@ class Standard extends \Magento\Payment\Model\Method\AbstractMethod
      */
     private function _getAggregatedCartSummary()
     {
-        if ($this->_config->lineItemsSummary) {
-            return $this->_config->lineItemsSummary;
+        if ($this->_config->getConfigValue('lineItemsSummary')) {
+            return $this->_config->getConfigValue('lineItemsSummary');
         }
         return $this->_storeManager->getStore($this->getStore())->getFrontendName();
     }
diff --git a/app/code/Magento/Paypal/etc/adminhtml/di.xml b/app/code/Magento/Paypal/etc/adminhtml/di.xml
index 7a9dcd1d84cccdb869484905a53e140fd23f8616..34037115d3b55e2cb5e1071b146d3a21d4e6efa7 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/di.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/di.xml
@@ -51,4 +51,13 @@
             <argument name="sessionName" xsi:type="string">adminhtml</argument>
         </arguments>
     </type>
+    <type name="Magento\Backend\Model\Config\Structure">
+        <plugin name="paypal_system_configuration" type="Magento\Paypal\Model\Config\StructurePlugin"/>
+    </type>
+    <type name="Magento\Backend\Model\Config\Structure\Element\Field">
+        <plugin name="paypal_system_configuration_field" type="Magento\Paypal\Model\Config\Structure\Element\FieldPlugin"/>
+    </type>
+    <type name="Magento\Backend\Block\Store\Switcher">
+        <plugin name="paypal_store_switcher" type="Magento\Paypal\Block\Adminhtml\Store\SwitcherPlugin"/>
+    </type>
 </config>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/system.xml b/app/code/Magento/Paypal/etc/adminhtml/system.xml
index 1953c4fc7cad5f6d2b102325a5bc80baec4ade56..82bf0a09bf352a0b9c38bc8c4604bd0cc71e0df0 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/system.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/system.xml
@@ -30,997 +30,1420 @@
                 <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Hint</frontend_model>
                 <help_url>https://www.paypal-marketing.com/emarketing/partner/na/merchantlineup/home.page#mainTab=checkoutlineup</help_url>
             </group>
-            <group id="account" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
+            <group id="account" translate="label" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="0">
+                <label>Merchant Location</label>
                 <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Location</frontend_model>
+                <field id="merchant_country" type="select" translate="label comment" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Merchant Country</label>
+                    <comment>If not specified, Default Country from General Config will be used</comment>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Field\Country</frontend_model>
+                    <source_model>Magento\Paypal\Model\System\Config\Source\MerchantCountry</source_model>
+                    <backend_model>Magento\Paypal\Model\System\Config\Backend\MerchantCountry</backend_model>
+                    <config_path>paypal/general/merchant_country</config_path>
+                </field>
             </group>
-            <group id="paypal_group_all_in_one" translate="label comment paypal_title" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>
-                    <![CDATA[PayPal All-in-One Payment Solutions&nbsp;&nbsp;<i>Accept and process credit cards and PayPal payments.</i>]]>
-                </label>
-                <expanded>1</expanded>
-                <fieldset_css>complex</fieldset_css>
-                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
-                <comment>Choose a secure bundled payment solution for your business.</comment>
-                <help_url>https://www.paypal-marketing.com/emarketing/partner/na/merchantlineup/home.page#mainTab=checkoutlineup</help_url>
-                <group id="payflow_advanced_us" extends="*/paypal_payments/payflow_advanced" />
-                <group id="wpp_us" translate="label" extends="*/paypal_payments/wpp">
-                    <label>Payments Pro (Includes Express Checkout)</label>
-                    <group id="wpp_required_settings">
-                        <group id="wpp_and_express_checkout" translate="label">
-                            <label>Payments Pro and Express Checkout</label>
-                        </group>
+        </section>
+        <section id="payment_all_paypal" showInDefault="0" showInWebsite="0" showInStore="0">
+            <group id="wpp" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="40">
+                <label>Website Payments Pro (Includes Express Checkout)</label>
+                <fieldset_css>pp-method-general</fieldset_css>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
+                <comment>Accept payments with a completely customizable checkout.</comment>
+                <attribute type="activity_path">payment/paypal_direct/active</attribute>
+                <more_url>https://www.paypal.com/webapps/mpp/referral/website-payments-pro?partner_id=NB9WWHYEMVUMS</more_url>
+                <group id="wpp_required_settings" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                    <label>Required PayPal Settings</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <group id="wpp_and_express_checkout" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                        <label>Website Payments Pro and Express Checkout</label>
+                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                        <field id="business_account" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account"/>
+                        <field id="api_authentication" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_authentication"/>
+                        <field id="api_username" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_username"/>
+                        <field id="api_password" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_password"/>
+                        <field id="api_signature" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_signature"/>
+                        <field id="api_cert" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_cert"/>
+                        <field id="api_wizard" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_wizard"/>
+                        <field id="sandbox_flag" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/sandbox_flag"/>
+                        <field id="use_proxy" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/use_proxy"/>
+                        <field id="proxy_host" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/proxy_host"/>
+                        <field id="proxy_port" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/proxy_port"/>
                     </group>
-                    <group id="wpp_settings" translate="label">
-                        <label>Basic Settings - PayPal Payments Pro</label>
+                    <field id="enable_wpp" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
+                        <label>Enable this Solution</label>
+                        <config_path>payment/paypal_direct/active</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <requires>
+                            <group id="wpp_and_express_checkout"/>
+                        </requires>
+                        <frontend_class>paypal-enabler</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                </group>
+                <group id="wpp_settings" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                    <label>Basic Settings - PayPal Website Payments Pro</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Title</label>
+                        <comment>It is recommended to set this value to "Debit or Credit Card" per store views.</comment>
+                        <config_path>payment/paypal_direct/title</config_path>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="sort_order" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                        <label>Sort Order</label>
+                        <config_path>payment/paypal_direct/sort_order</config_path>
+                        <frontend_class>validate-number</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                        <label>Payment Action</label>
+                        <config_path>payment/paypal_direct/payment_action</config_path>
+                        <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="heading_cc" translate="label" sortOrder="40" showInDefault="1" showInWebsite="1">
+                        <label>Credit Card Settings</label>
+                        <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="cctypes" translate="label comment" type="multiselect" sortOrder="50" showInDefault="1" showInWebsite="1">
+                        <label>Allowed Credit Card Types</label>
+                        <comment>
+                            <![CDATA[3D Secure validation is required for Maestro cards. Supporting of American Express cards require additional agreement. Learn more at <a href="http://www.paypal.com/amexupdate">http://www.paypal.com/amexupdate</a>.]]>
+                        </comment>
+                        <config_path>payment/paypal_direct/cctypes</config_path>
+                        <source_model>Magento\Paypal\Model\Config::getWppCcTypesAsOptionArray</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <group id="wpp_settings_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="60">
+                        <label>Advanced Settings</label>
+                        <fieldset_css>config-advanced</fieldset_css>
+                        <field id="allowspecific" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <label>Payment Applicable From</label>
+                            <config_path>payment/paypal_direct/allowspecific</config_path>
+                            <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="specificcountry" translate="label" type="multiselect" sortOrder="25" showInDefault="1" showInWebsite="1">
+                            <label>Countries Payment Applicable From</label>
+                            <config_path>payment/paypal_direct/specificcountry</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
+                            <depends>
+                                <field id="allowspecific">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>Debug Mode</label>
+                            <config_path>payment/paypal_direct/debug</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
+                            <label>Enable SSL verification</label>
+                            <config_path>payment/paypal_direct/verify_peer</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="line_items_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <label>Transfer Cart Line Items</label>
+                            <config_path>payment/paypal_direct/line_items_enabled</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="useccv" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <label>Require CVV Entry</label>
+                            <config_path>payment/paypal_direct/useccv</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="heading_3dsecure" translate="label" sortOrder="55" showInDefault="1" showInWebsite="1">
+                            <label>3D Secure</label>
+                            <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="centinel" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
+                            <label>3D Secure Card Validation</label>
+                            <config_path>payment/paypal_direct/centinel</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="centinel_is_mode_strict" translate="label comment" type="select" sortOrder="65" showInDefault="1" showInWebsite="1">
+                            <label>Severe 3D Secure Card Validation</label>
+                            <config_path>payment/paypal_direct/centinel_is_mode_strict</config_path>
+                            <comment>Severe Validation Removes Chargeback Liability on Merchant</comment>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <depends>
+                                <field id="centinel">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="centinel_api_url" translate="label comment" type="text" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <label>Centinel Custom API URL</label>
+                            <config_path>payment/paypal_direct/centinel_api_url</config_path>
+                            <comment>If empty, a default value will be used. Custom URL may be provided by CardinalCommerce agreement.</comment>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <depends>
+                                <field id="centinel">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <group id="wpp_billing_agreement" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="80">
+                            <label>PayPal Billing Agreement Settings</label>
+                            <field id="active" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/active"/>
+                            <field id="title" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/title"/>
+                            <field id="sort_order" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/sort_order"/>
+                            <field id="payment_action" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/payment_action"/>
+                            <field id="allowspecific" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/allowspecific"/>
+                            <field id="specificcountry" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/specificcountry"/>
+                            <field id="debug" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/debug"/>
+                            <field id="verify_peer" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/verify_peer"/>
+                            <field id="line_items_enabled" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/line_items_enabled"/>
+                            <field id="allow_billing_agreement_wizard" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/allow_billing_agreement_wizard"/>
+                        </group>
+                        <group id="wpp_settlement_report" translate="label" showInDefault="1" showInWebsite="1" sortOrder="90">
+                            <label>Settlement Report Settings</label>
+                            <field id="heading_sftp" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
+                            <field id="settlement_reports_ftp_login" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login"/>
+                            <field id="settlement_reports_ftp_password" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password"/>
+                            <field id="settlement_reports_ftp_sandbox" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox"/>
+                            <field id="settlement_reports_ftp_ip" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip"/>
+                            <field id="settlement_reports_ftp_path" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path"/>
+                            <field id="heading_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule"/>
+                            <field id="settlement_reports_active" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active"/>
+                            <field id="settlement_reports_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule"/>
+                            <field id="settlement_reports_time" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time"/>
+                        </group>
+                        <group id="wpp_frontend" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="100">
+                            <label>Frontend Experience Settings</label>
+                            <field id="logo" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo"/>
+                            <field id="paypal_pages" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages"/>
+                            <field id="page_style" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style"/>
+                            <field id="paypal_hdrimg" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg"/>
+                            <field id="paypal_hdrbackcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor"/>
+                            <field id="paypal_hdrbordercolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor"/>
+                            <field id="paypal_payflowcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor"/>
+                        </group>
                     </group>
                 </group>
-                <group id="wps_us" translate="label" extends="*/paypal_payments/wps">
-                    <label>Payments Standard</label>
-                    <group id="settings_payments_standart" translate="label">
-                        <label>Basic Settings - PayPal Payments Standard</label>
+                <group id="wpp_settings_express_checkout" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
+                    <label>Basic Settings - PayPal Express Checkout</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="title" extends="payment_all_paypal/express_checkout/settings_ec/title"/>
+                    <field id="sort_order" extends="payment_all_paypal/express_checkout/settings_ec/sort_order"/>
+                    <field id="payment_action" extends="payment_all_paypal/express_checkout/settings_ec/payment_action"/>
+                    <field id="visible_on_cart" extends="payment_all_paypal/express_checkout/settings_ec/visible_on_cart"/>
+                    <field id="visible_on_product" extends="payment_all_paypal/express_checkout/settings_ec/visible_on_product"/>
+                    <field id="authorization_honor_period" extends="payment_all_paypal/express_checkout/settings_ec/authorization_honor_period"/>
+                    <field id="order_valid_period" extends="payment_all_paypal/express_checkout/settings_ec/order_valid_period"/>
+                    <field id="child_authorization_number" extends="payment_all_paypal/express_checkout/settings_ec/child_authorization_number"/>
+                    <group id="wpp_settings_express_checkout_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="80">
+                        <label>Advanced Settings</label>
+                        <fieldset_css>config-advanced</fieldset_css>
+                        <field id="allowspecific" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/allowspecific"/>
+                        <field id="specificcountry" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/specificcountry"/>
+                        <field id="debug" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/debug"/>
+                        <field id="verify_peer" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/verify_peer"/>
+                        <field id="line_items_enabled" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/line_items_enabled"/>
+                        <field id="transfer_shipping_options" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/transfer_shipping_options"/>
+                        <field id="button_flavor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/button_flavor"/>
+                        <field id="solution_type" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/solution_type"/>
+                        <field id="require_billing_address" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/require_billing_address"/>
+                        <field id="allow_ba_signup" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/allow_ba_signup"/>
                     </group>
                 </group>
             </group>
-            <group id="paypal_payment_gateways" translate="label comment paypal_title" sortOrder="15" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>PayPal Payment Gateways</label>
-                <fieldset_css>complex</fieldset_css>
-                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
-                <comment>Process payments using your own internet merchant account.</comment>
-                <help_url>https://merchant.paypal.com/cgi-bin/marketingweb?cmd=_render-content</help_url>
-                <group id="payflow_link_us" extends="*/paypal_payments/payflow_link" />
-                <group id="paypal_payflowpro_with_express_checkout_us" extends="*/paypal_payments/paypal_payflowpro_with_express_checkout">
-                    <group id="paypal_payflow_required">
-                        <field id="enable_paypal_payflow">
-                            <frontend_class>paypal-enabler paypal-ec-pe</frontend_class>
+            <group id="wps" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="50">
+                <label>Website Payments Standard</label>
+                <fieldset_css>pp-method-general</fieldset_css>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
+                <comment>Accept credit card and PayPal payments securely.</comment>
+                <attribute type="activity_path">payment/paypal_standard/active</attribute>
+                <more_url>https://www.paypal.com/webapps/mpp/referral/website-payments-standard?partner_id=NB9WWHYEMVUMS</more_url>
+                <group id="wps_required_settings" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                    <label>Required PayPal Settings</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="business_account" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account"/>
+                    <field id="enable_wps" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
+                        <label>Enable this Solution</label>
+                        <config_path>payment/paypal_standard/active</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <requires>
+                            <field id="business_account"/>
+                        </requires>
+                        <frontend_class>paypal-enabler paypal-ec-conflicts</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                </group>
+                <group id="settings_payments_standart" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                    <label>Basic Settings - PayPal Website Payments Standard</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Title</label>
+                        <comment>It is recommended to set this value to "PayPal" per store views.</comment>
+                        <config_path>payment/paypal_standard/title</config_path>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Sort Order</label>
+                        <config_path>payment/paypal_standard/sort_order</config_path>
+                        <frontend_class>validate-number</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                        <label>Payment Action</label>
+                        <config_path>payment/paypal_standard/payment_action</config_path>
+                        <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <group id="settings_payments_standart_advanced" translate="label" showInDefault="1" showInWebsite="1" sortOrder="40">
+                        <label>Advanced Settings</label>
+                        <fieldset_css>config-advanced</fieldset_css>
+                        <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
+                            <label>Payment Applicable From</label>
+                            <config_path>payment/paypal_standard/allowspecific</config_path>
+                            <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <label>Countries Payment Applicable From</label>
+                            <config_path>payment/paypal_standard/specificcountry</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
+                            <depends>
+                                <field id="allowspecific">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="sandbox_flag" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>Sandbox Mode</label>
+                            <config_path>payment/paypal_standard/sandbox_flag</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="line_items_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <label>Transfer Cart Line Items</label>
+                            <config_path>payment/paypal_standard/line_items_enabled</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="line_items_summary" translate="label comment" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
+                            <label>Summary Text for Aggregated Cart</label>
+                            <config_path>payment/paypal_standard/line_items_summary</config_path>
+                            <comment>Uses store frontend name by default.</comment>
+                            <depends>
+                                <field id="line_items_enabled">0</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="debug" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
+                            <label>Debug Mode</label>
+                            <config_path>payment/paypal_standard/debug</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="verify_peer" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <label>Enable SSL verification</label>
+                            <config_path>payment/paypal_standard/verify_peer</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
                         </field>
                     </group>
                 </group>
             </group>
-            <group id="paypal_alternative_payment_methods" translate="label comment attribute" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                <label>PayPal Express Checkout</label>
-                <expanded>1</expanded>
-                <fieldset_css>complex</fieldset_css>
-                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
-                <comment>Add another payment method to your existing solution or as a stand-alone option.</comment>
-                <attribute type="paypal_title">Select a Payment Solution</attribute>
-                <help_url>https://merchant.paypal.com/cgi-bin/marketingweb?cmd=_render-content</help_url>
-                <group id="express_checkout_us" extends="*/paypal_payments/express_checkout" />
-            </group>
-            <group id="paypal_payments">
-                <group id="payflow_advanced" type="text" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
-                    <label>Payments Advanced (Includes Express Checkout)</label>
-                    <fieldset_css>pp-method-general</fieldset_css>
-                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
-                    <more_url>https://www.paypal.com/webapps/mpp/referral/paypal-payments-advanced?partner_id=NB9WWHYEMVUMS</more_url>
-                    <comment>Accept payments with a PCI-compliant checkout that keeps customers on your site.</comment>
-                    <attribute type="activity_path">payment/payflow_advanced/active</attribute>
-                    <group id="required_settings" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                        <label>Required PayPal Settings</label>
+            <group id="paypal_payflowpro" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="10">
+                <label>Payflow Pro</label>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
+                <fieldset_css>pp-method-payflow</fieldset_css>
+                <comment>Connect your merchant account with a fully customizable gateway that lets customers pay without leaving your site.</comment>
+                <attribute type="activity_path">payment/payflowpro/active</attribute>
+                <more_url>https://www.paypal.com/webapps/mpp/referral/paypal-payflow-pro?partner_id=NB9WWHYEMVUMS</more_url>
+                <attribute type="paypal_ec_separate">1</attribute>
+                <group id="paypal_payflow_required" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                    <label>Required PayPal Settings</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <group id="paypal_payflow_api_settings" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                        <label>Payflow Pro</label>
                         <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <group id="payments_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                            <label>Payments Advanced and Express Checkout</label>
-                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                            <field id="business_account" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account">
-                                <label>Email Associated with PayPal Merchant Account (Optional)</label>
-                            </field>
-                            <field id="partner" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1">
-                                <label>Partner</label>
-                                <config_path>payment/payflow_advanced/partner</config_path>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="vendor" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                <label>Vendor</label>
-                                <config_path>payment/payflow_advanced/vendor</config_path>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="user" translate="label comment tooltip" type="text" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                <label>User</label>
-                                <comment>PayPal recommends that you set up an additional User on your account at manager.paypal.com</comment>
-                                <tooltip>PayPal recommends you set up an additional User on your account at manager.paypal.com, instead of entering your admin username and password here. This will enhance your security and prevent service interruptions if you later change your password. If you do not want to set up an additional User, you can re-enter your Merchant Login here.</tooltip>
-                                <config_path>payment/payflow_advanced/user</config_path>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="pwd" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1">
-                                <label>Password</label>
-                                <config_path>payment/payflow_advanced/pwd</config_path>
-                                <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="sandbox_flag" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                <label>Test Mode</label>
-                                <config_path>payment/payflow_advanced/sandbox_flag</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="use_proxy" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                <label>Use Proxy</label>
-                                <config_path>payment/payflow_advanced/use_proxy</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="proxy_host" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1">
-                                <label>Proxy Host</label>
-                                <config_path>payment/payflow_advanced/proxy_host</config_path>
-                                <depends>
-                                    <field id="use_proxy">1</field>
-                                </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="proxy_port" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1">
-                                <label>Proxy Port</label>
-                                <config_path>payment/payflow_advanced/proxy_port</config_path>
-                                <depends>
-                                    <field id="use_proxy">1</field>
-                                </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="payflow_advanced_info" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="100">
-                                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Payflowlink\Advanced</frontend_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                        </group>
-                        <field id="enable_payflow_advanced" translate="label comment" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                            <label>Enable this Solution</label>
-                            <config_path>payment/payflow_advanced/active</config_path>
+                        <field id="partner" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <label>Partner</label>
+                            <config_path>payment/payflowpro/partner</config_path>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="user" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>User</label>
+                            <config_path>payment/payflowpro/user</config_path>
+                            <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="vendor" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <label>Vendor</label>
+                            <config_path>payment/payflowpro/vendor</config_path>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="pwd" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <label>Password</label>
+                            <config_path>payment/payflowpro/pwd</config_path>
+                            <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="sandbox_flag" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
+                            <label>Test Mode</label>
+                            <config_path>payment/payflowpro/sandbox_flag</config_path>
                             <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <requires>
-                                <group id="payments_advanced"/>
-                            </requires>
-                            <frontend_class>paypal-enabler paypal-ec-pe paypal-payflow-advanced</frontend_class>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="enable_express_checkout" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                            <config_path>payment/payflow_express/active</config_path>
-                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Field\Hidden</frontend_model>
+                        <field id="use_proxy" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <label>Use Proxy</label>
+                            <config_path>payment/payflowpro/use_proxy</config_path>
                             <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <frontend_class>paypal-ec-payflow-enabler</frontend_class>
                             <attribute type="shared">1</attribute>
-                            <requires>
-                                <field id="enable_payflow_advanced"/>
-                            </requires>
+                        </field>
+                        <field id="proxy_host" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1">
+                            <label>Proxy Host</label>
+                            <config_path>payment/payflowpro/proxy_host</config_path>
+                            <depends>
+                                <field id="use_proxy">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="proxy_port" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1">
+                            <label>Proxy Port</label>
+                            <config_path>payment/payflowpro/proxy_port</config_path>
+                            <depends>
+                                <field id="use_proxy">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
                         </field>
                     </group>
-                    <group id="settings_payments_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
-                        <label>Basic Settings - PayPal Payments Advanced</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Title</label>
-                            <comment>It is recommended to set this value to "Debit or Credit Card" per store views.</comment>
-                            <config_path>payment/payflow_advanced/title</config_path>
+                    <field id="enable_paypal_payflow" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
+                        <label>Enable this Solution</label>
+                        <config_path>payment/payflowpro/active</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <requires>
+                            <group id="paypal_payflow_api_settings"/>
+                        </requires>
+                        <frontend_class>paypal-enabler paypal-ec-separate</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                </group>
+                <group id="settings_paypal_payflow" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                    <label>Basic Settings - PayPal Payflow Pro</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Title</label>
+                        <comment>It is recommended to set this value to "Debit or Credit Card" per store views.</comment>
+                        <config_path>payment/payflowpro/title</config_path>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Sort Order</label>
+                        <config_path>payment/payflowpro/sort_order</config_path>
+                        <frontend_class>validate-number</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                        <label>Payment Action</label>
+                        <config_path>payment/payflowpro/payment_action</config_path>
+                        <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="heading_cc" translate="label" sortOrder="40" showInDefault="1" showInWebsite="1">
+                        <label>Credit Card Settings</label>
+                        <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="cctypes" translate="label comment" type="multiselect" sortOrder="50" showInDefault="1" showInWebsite="1">
+                        <label>Allowed Credit Card Types</label>
+                        <comment>
+                            <![CDATA[Supporting of American Express cards require additional agreement. Learn more at <a href="http://www.paypal.com/amexupdate">http://www.paypal.com/amexupdate</a>.]]>
+                        </comment>
+                        <config_path>payment/payflowpro/cctypes</config_path>
+                        <source_model>Magento\Paypal\Model\Config::getPayflowproCcTypesAsOptionArray</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <group id="settings_paypal_payflow_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="60">
+                        <label>Advanced Settings</label>
+                        <fieldset_css>config-advanced</fieldset_css>
+                        <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
+                            <label>Payment Applicable From</label>
+                            <config_path>payment/payflowpro/allowspecific</config_path>
+                            <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Sort Order</label>
-                            <config_path>payment/payflow_advanced/sort_order</config_path>
-                            <frontend_class>validate-number</frontend_class>
+                        <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <label>Countries Payment Applicable From</label>
+                            <config_path>payment/payflowpro/specificcountry</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
+                            <depends>
+                                <field id="allowspecific">1</field>
+                            </depends>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                            <label>Payment Action</label>
-                            <config_path>payment/payflow_advanced/payment_action</config_path>
-                            <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                        <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>Debug Mode</label>
+                            <config_path>payment/payflowpro/debug</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <group id="settings_payments_advanced_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="40">
-                            <label>Advanced Settings</label>
-                            <fieldset_css>config-advanced</fieldset_css>
-                            <field id="allowspecific" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
-                                <label>Payment Applicable From</label>
-                                <config_path>payment/payflow_advanced/allowspecific</config_path>
-                                <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="specificcountry" translate="label" type="multiselect" sortOrder="25" showInDefault="1" showInWebsite="1">
-                                <label>Countries Payment Applicable From</label>
-                                <config_path>payment/payflow_advanced/specificcountry</config_path>
-                                <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
-                                <depends>
-                                    <field id="allowspecific">1</field>
-                                </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                <label>Debug Mode</label>
-                                <config_path>payment/payflow_advanced/debug</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
-                                <label>Enable SSL verification</label>
-                                <config_path>payment/payflow_advanced/verify_peer</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="csc_editable" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                <label>CVV Entry is Editable</label>
-                                <config_path>payment/payflow_advanced/csc_editable</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="csc_required" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
-                                <label>Require CVV Entry</label>
-                                <config_path>payment/payflow_advanced/csc_required</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <depends>
-                                    <field id="csc_editable">1</field>
-                                </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="email_confirmation" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                <label>Send Email Confirmation</label>
-                                <config_path>payment/payflow_advanced/email_confirmation</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="url_method" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                <label>URL method for Cancel URL and Return URL</label>
-                                <config_path>payment/payflow_advanced/url_method</config_path>
-                                <source_model>Magento\Paypal\Model\System\Config\Source\UrlMethod</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <group id="settlement_report" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="80">
-                                <label>Settlement Report Settings</label>
-                                <field id="heading_sftp" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
-                                <field id="settlement_reports_ftp_login" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login"/>
-                                <field id="settlement_reports_ftp_password" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password"/>
-                                <field id="settlement_reports_ftp_sandbox" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox"/>
-                                <field id="settlement_reports_ftp_ip" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip"/>
-                                <field id="settlement_reports_ftp_path" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path"/>
-                                <field id="heading_schedule" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule"/>
-                                <field id="settlement_reports_active" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active"/>
-                                <field id="settlement_reports_schedule" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule"/>
-                                <field id="settlement_reports_time" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time"/>
-                            </group>
-                            <group id="frontend" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="90">
-                                <label>Frontend Experience Settings</label>
-                                <field id="logo" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo"/>
-                                <field id="paypal_pages" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages"/>
-                                <field id="page_style" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style"/>
-                                <field id="paypal_hdrimg" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg"/>
-                                <field id="paypal_hdrbackcolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor"/>
-                                <field id="paypal_hdrbordercolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor"/>
-                                <field id="paypal_payflowcolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor"/>
-                            </group>
+                        <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
+                            <label>Enable SSL verification</label>
+                            <config_path>payment/payflowpro/verify_peer</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="useccv" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <label>Require CVV Entry</label>
+                            <config_path>payment/payflowpro/useccv</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="heading_3dsecure" translate="label" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <label>3D Secure</label>
+                            <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="centinel" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
+                            <label>3D Secure Card Validation</label>
+                            <config_path>payment/payflowpro/centinel</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="centinel_is_mode_strict" translate="label comment" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <label>Severe 3D Secure Card Validation</label>
+                            <config_path>payment/payflowpro/centinel_is_mode_strict</config_path>
+                            <comment>Severe validation removes chargeback liability on merchant.</comment>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <depends>
+                                <field id="centinel">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="centinel_api_url" translate="label comment" type="text" sortOrder="80" showInDefault="1" showInWebsite="1">
+                            <label>Centinel API URL</label>
+                            <config_path>payment/payflowpro/centinel_api_url</config_path>
+                            <comment>A value is required for live mode. Refer to your CardinalCommerce agreement.</comment>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <depends>
+                                <field id="centinel">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <group id="paypal_payflow_settlement_report" translate="label" showInDefault="1" showInWebsite="1" sortOrder="90">
+                            <label>Settlement Report Settings</label>
+                            <field id="heading_sftp" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
+                            <field id="settlement_reports_ftp_login" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login"/>
+                            <field id="settlement_reports_ftp_password" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password"/>
+                            <field id="settlement_reports_ftp_sandbox" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox"/>
+                            <field id="settlement_reports_ftp_ip" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip"/>
+                            <field id="settlement_reports_ftp_path" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path"/>
+                            <field id="heading_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule"/>
+                            <field id="settlement_reports_active" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active"/>
+                            <field id="settlement_reports_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule"/>
+                            <field id="settlement_reports_time" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time"/>
                         </group>
                     </group>
-                    <group id="settings_express_checkout" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
-                        <label>Basic Settings - PayPal Express Checkout</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/title" />
-                        <field id="sort_order" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/sort_order" />
-                        <field id="payment_action" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/payment_action" />
-                        <field id="visible_on_cart" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/visible_on_cart" />
-                        <field id="visible_on_product" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/visible_on_product" />
-                        <group id="settings_express_checkout_advanced" type="group" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/paypal_payflow_express_checkout_advanced"/>
-                    </group>
                 </group>
-                <group id="wpp" type="text" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="40">
-                    <label>Website Payments Pro (Includes Express Checkout)</label>
-                    <fieldset_css>pp-method-general</fieldset_css>
-                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
-                    <comment>Accept payments with a completely customizable checkout.</comment>
-                    <attribute type="activity_path">payment/paypal_direct/active</attribute>
-                    <more_url>https://www.paypal.com/webapps/mpp/referral/website-payments-pro?partner_id=NB9WWHYEMVUMS</more_url>
-                    <group id="wpp_required_settings" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                        <label>Required PayPal Settings</label>
+            </group>
+            <group id="payflow_link" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                <label>Payflow Link (Includes Express Checkout)</label>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
+                <fieldset_css>pp-method-payflow</fieldset_css>
+                <comment>Connect your merchant account with a PCI-compliant gateway that lets customers pay without leaving your site.</comment>
+                <attribute type="activity_path">payment/payflow_link/active</attribute>
+                <more_url>https://www.paypal.com/webapps/mpp/referral/paypal-payflow-link?partner_id=NB9WWHYEMVUMS</more_url>
+                <group id="payflow_link_required" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                    <label>Required PayPal Settings</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <group id="payflow_link_payflow_link" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                        <label>Payflow Link and Express Checkout</label>
                         <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <group id="wpp_and_express_checkout" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                            <label>Website Payments Pro and Express Checkout</label>
-                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                            <field id="business_account" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account"/>
-                            <field id="api_authentication" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_authentication"/>
-                            <field id="api_username" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_username"/>
-                            <field id="api_password" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_password"/>
-                            <field id="api_signature" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_signature"/>
-                            <field id="api_cert" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_cert"/>
-                            <field id="api_wizard" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_wizard"/>
-                            <field id="sandbox_flag" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/sandbox_flag"/>
-                            <field id="use_proxy" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/use_proxy"/>
-                            <field id="proxy_host" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/proxy_host"/>
-                            <field id="proxy_port" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/proxy_port"/>
-                        </group>
-                        <field id="enable_wpp" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
-                            <label>Enable this Solution</label>
-                            <config_path>payment/paypal_direct/active</config_path>
+                        <field id="business_account" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account" translate="label" sortOrder="5">
+                            <frontend_class>not-required</frontend_class>
+                            <label>Email Associated with PayPal Merchant Account (Optional)</label>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="partner" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1">
+                            <label>Partner</label>
+                            <config_path>payment/payflow_link/partner</config_path>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="vendor" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <label>Vendor</label>
+                            <config_path>payment/payflow_link/vendor</config_path>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="user" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>User</label>
+                            <comment>If you do not have multiple users set up on your account, please re-enter your Vendor/Merchant Login here.</comment>
+                            <config_path>payment/payflow_link/user</config_path>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="pwd" translate="label" type="obscure" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <label>Password</label>
+                            <config_path>payment/payflow_link/pwd</config_path>
+                            <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="sandbox_flag" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <label>Test Mode</label>
+                            <config_path>payment/payflow_link/sandbox_flag</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="use_proxy" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
+                            <label>Use Proxy</label>
+                            <config_path>payment/payflow_link/use_proxy</config_path>
                             <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <requires>
-                                <group id="wpp_and_express_checkout"/>
-                            </requires>
-                            <frontend_class>paypal-enabler</frontend_class>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="proxy_host" translate="label" type="text" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <label>Proxy Host</label>
+                            <config_path>payment/payflow_link/proxy_host</config_path>
+                            <depends>
+                                <field id="use_proxy">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="proxy_port" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1">
+                            <label>Proxy Port</label>
+                            <config_path>payment/payflow_link/proxy_port</config_path>
+                            <depends>
+                                <field id="use_proxy">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="payflowlink_info" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="90">
+                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Payflowlink\Info</frontend_model>
                             <attribute type="shared">1</attribute>
                         </field>
                     </group>
-                    <group id="wpp_settings" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
-                        <label>Basic Settings - PayPal Website Payments Pro</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Title</label>
-                            <comment>It is recommended to set this value to "Debit or Credit Card" per store views.</comment>
-                            <config_path>payment/paypal_direct/title</config_path>
+                    <field id="enable_payflow_link" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
+                        <label>Enable Payflow Link</label>
+                        <config_path>payment/payflow_link/active</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <requires>
+                            <group id="payflow_link_payflow_link"/>
+                        </requires>
+                        <frontend_class>paypal-enabler paypal-ec-pe paypal-payflowlink</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="enable_express_checkout_basic" translate="label" type="select" sortOrder="40">
+                        <label>Enable Express Checkout</label>
+                        <config_path>payment/payflow_express/active</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <frontend_class>paypal-ec-payflow-enabler</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="enable_express_checkout" extends="payment_all_paypal/payflow_link/payflow_link_required/enable_express_checkout_basic" showInDefault="1" showInWebsite="1">
+                        <requires>
+                            <field id="enable_payflow_link"/>
+                        </requires>
+                    </field>
+                </group>
+                <group id="settings_payflow_link" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                    <label>Basic Settings - PayPal Payflow Link</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Title</label>
+                        <comment>It is recommended to set this value to "Debit or Credit Card" per store views.</comment>
+                        <config_path>payment/payflow_link/title</config_path>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Sort Order</label>
+                        <config_path>payment/payflow_link/sort_order</config_path>
+                        <frontend_class>validate-number</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                        <label>Payment Action</label>
+                        <config_path>payment/payflow_link/payment_action</config_path>
+                        <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <group id="settings_payflow_link_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="40">
+                        <label>Advanced Settings</label>
+                        <fieldset_css>config-advanced</fieldset_css>
+                        <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
+                            <label>Payment Applicable From</label>
+                            <config_path>payment/payflow_link/allowspecific</config_path>
+                            <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="sort_order" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
-                            <label>Sort Order</label>
-                            <config_path>payment/paypal_direct/sort_order</config_path>
-                            <frontend_class>validate-number</frontend_class>
+                        <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <label>Countries Payment Applicable From</label>
+                            <config_path>payment/payflow_link/specificcountry</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
+                            <depends>
+                                <field id="allowspecific">1</field>
+                            </depends>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                            <label>Payment Action</label>
-                            <config_path>payment/paypal_direct/payment_action</config_path>
-                            <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                        <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>Debug Mode</label>
+                            <config_path>payment/payflow_link/debug</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="heading_cc" translate="label" sortOrder="40" showInDefault="1" showInWebsite="1">
-                            <label>Credit Card Settings</label>
-                            <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
+                        <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
+                            <label>Enable SSL verification</label>
+                            <config_path>payment/payflow_link/verify_peer</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="cctypes" translate="label comment" type="multiselect" sortOrder="50" showInDefault="1" showInWebsite="1">
-                            <label>Allowed Credit Card Types</label>
-                            <comment>
-                                <![CDATA[3D Secure validation is required for Maestro cards. Supporting of American Express cards require additional agreement. Learn more at <a href="http://www.paypal.com/amexupdate">http://www.paypal.com/amexupdate</a>.]]>
-                            </comment>
-                            <config_path>payment/paypal_direct/cctypes</config_path>
-                            <source_model>Magento\Paypal\Model\Config::getWppCcTypesAsOptionArray</source_model>
+                        <field id="csc_editable" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <label>CVV Entry is Editable</label>
+                            <config_path>payment/payflow_link/csc_editable</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <group id="wpp_settings_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="60">
-                            <label>Advanced Settings</label>
-                            <fieldset_css>config-advanced</fieldset_css>
-                            <field id="allowspecific" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
-                                <label>Payment Applicable From</label>
-                                <config_path>payment/paypal_direct/allowspecific</config_path>
-                                <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="specificcountry" translate="label" type="multiselect" sortOrder="25" showInDefault="1" showInWebsite="1">
-                                <label>Countries Payment Applicable From</label>
-                                <config_path>payment/paypal_direct/specificcountry</config_path>
-                                <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
-                                <depends>
-                                    <field id="allowspecific">1</field>
-                                </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                <label>Debug Mode</label>
-                                <config_path>payment/paypal_direct/debug</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
-                                <label>Enable SSL verification</label>
-                                <config_path>payment/paypal_direct/verify_peer</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="line_items_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                <label>Transfer Cart Line Items</label>
-                                <config_path>payment/paypal_direct/line_items_enabled</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="useccv" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
-                                <label>Require CVV Entry</label>
-                                <config_path>payment/paypal_direct/useccv</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="heading_3dsecure" translate="label" sortOrder="55" showInDefault="1" showInWebsite="1">
-                                <label>3D Secure</label>
-                                <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="centinel" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                <label>3D Secure Card Validation</label>
-                                <config_path>payment/paypal_direct/centinel</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="centinel_is_mode_strict" translate="label comment" type="select" sortOrder="65" showInDefault="1" showInWebsite="1">
-                                <label>Severe 3D Secure Card Validation</label>
-                                <config_path>payment/paypal_direct/centinel_is_mode_strict</config_path>
-                                <comment>Severe Validation Removes Chargeback Liability on Merchant</comment>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <depends>
-                                    <field id="centinel">1</field>
-                                </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="centinel_api_url" translate="label comment" type="text" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                <label>Centinel Custom API URL</label>
-                                <config_path>payment/paypal_direct/centinel_api_url</config_path>
-                                <comment>If empty, a default value will be used. Custom URL may be provided by CardinalCommerce agreement.</comment>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <depends>
-                                    <field id="centinel">1</field>
-                                </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <group id="wpp_billing_agreement" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="80">
-                                <label>PayPal Billing Agreement Settings</label>
-                                <field id="active" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/active"/>
-                                <field id="title" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/title"/>
-                                <field id="sort_order" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/sort_order"/>
-                                <field id="payment_action" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/payment_action"/>
-                                <field id="allowspecific" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/allowspecific"/>
-                                <field id="specificcountry" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/specificcountry"/>
-                                <field id="debug" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/debug"/>
-                                <field id="verify_peer" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/verify_peer"/>
-                                <field id="line_items_enabled" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/line_items_enabled"/>
-                                <field id="allow_billing_agreement_wizard" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/allow_billing_agreement_wizard"/>
-                            </group>
-                            <group id="wpp_settlement_report" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="90">
-                                <label>Settlement Report Settings</label>
-                                <field id="heading_sftp" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
-                                <field id="settlement_reports_ftp_login" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login"/>
-                                <field id="settlement_reports_ftp_password" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password"/>
-                                <field id="settlement_reports_ftp_sandbox" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox"/>
-                                <field id="settlement_reports_ftp_ip" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip"/>
-                                <field id="settlement_reports_ftp_path" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path"/>
-                                <field id="heading_schedule" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule"/>
-                                <field id="settlement_reports_active" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active"/>
-                                <field id="settlement_reports_schedule" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule"/>
-                                <field id="settlement_reports_time" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time"/>
-                            </group>
-                            <group id="wpp_frontend" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="100">
-                                <label>Frontend Experience Settings</label>
-                                <field id="logo" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo"/>
-                                <field id="paypal_pages" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages"/>
-                                <field id="page_style" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style"/>
-                                <field id="paypal_hdrimg" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg"/>
-                                <field id="paypal_hdrbackcolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor"/>
-                                <field id="paypal_hdrbordercolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor"/>
-                                <field id="paypal_payflowcolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor"/>
-                            </group>
+                        <field id="csc_required" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <label>Require CVV Entry</label>
+                            <config_path>payment/payflow_link/csc_required</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <depends>
+                                <field id="csc_editable">1</field>
+                            </depends>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="email_confirmation" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
+                            <label>Send Email Confirmation</label>
+                            <config_path>payment/payflow_link/email_confirmation</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="url_method" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <label>URL method for Cancel URL and Return URL</label>
+                            <config_path>payment/payflow_link/url_method</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\UrlMethod</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <group id="payflow_link_settlement_report" translate="label" showInDefault="1" showInWebsite="1" sortOrder="80">
+                            <label>Settlement Report Settings</label>
+                            <field id="heading_sftp" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
+                            <field id="settlement_reports_ftp_login" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login"/>
+                            <field id="settlement_reports_ftp_password" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password"/>
+                            <field id="settlement_reports_ftp_sandbox" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox"/>
+                            <field id="settlement_reports_ftp_ip" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip"/>
+                            <field id="settlement_reports_ftp_path" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path"/>
+                            <field id="heading_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule"/>
+                            <field id="settlement_reports_active" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active"/>
+                            <field id="settlement_reports_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule"/>
+                            <field id="settlement_reports_time" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time"/>
+                        </group>
+                        <group id="payflow_link_frontend" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="90">
+                            <label>Frontend Experience Settings</label>
+                            <field id="logo" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo"/>
+                            <field id="paypal_pages" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages"/>
+                            <field id="page_style" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style"/>
+                            <field id="paypal_hdrimg" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg"/>
+                            <field id="paypal_hdrbackcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor"/>
+                            <field id="paypal_hdrbordercolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor"/>
+                            <field id="paypal_payflowcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor"/>
                         </group>
                     </group>
-                    <group id="wpp_settings_express_checkout" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
-                        <label>Basic Settings - PayPal Express Checkout</label>
+                </group>
+                <group id="settings_payflow_link_express_checkout" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
+                    <label>Basic Settings - PayPal Express Checkout</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="title" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/title" />
+                    <field id="sort_order" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/sort_order" />
+                    <field id="payment_action" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/payment_action" />
+                    <field id="visible_on_cart" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/visible_on_cart" />
+                    <field id="visible_on_product" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/visible_on_product" />
+                    <group id="settings_payflow_link_express_checkout_advanced" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/paypal_payflow_express_checkout_advanced"/>
+                </group>
+            </group>
+            <group id="express_checkout" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="60">
+                <label>Express Checkout</label>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
+                <fieldset_css>pp-method-express</fieldset_css>
+                <comment>Add PayPal as an additional payment method to your checkout page.</comment>
+                <attribute type="activity_path">payment/paypal_express/active</attribute>
+                <more_url>https://www.paypal.com/webapps/mpp/referral/paypal-express-checkout?partner_id=NB9WWHYEMVUMS</more_url>
+                <group id="express_checkout_required" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                    <label>Required PayPal Settings</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <group id="express_checkout_required_express_checkout" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                        <label>Express Checkout</label>
                         <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" extends="payment/paypal_payments/express_checkout/settings_ec/title"/>
-                        <field id="sort_order" extends="payment/paypal_payments/express_checkout/settings_ec/sort_order"/>
-                        <field id="payment_action" extends="payment/paypal_payments/express_checkout/settings_ec/payment_action"/>
-                        <field id="visible_on_cart" extends="payment/paypal_payments/express_checkout/settings_ec/visible_on_cart"/>
-                        <field id="visible_on_product" extends="payment/paypal_payments/express_checkout/settings_ec/visible_on_product"/>
-                        <field id="authorization_honor_period" extends="payment/paypal_payments/express_checkout/settings_ec/authorization_honor_period"/>
-                        <field id="order_valid_period" extends="payment/paypal_payments/express_checkout/settings_ec/order_valid_period"/>
-                        <field id="child_authorization_number" extends="payment/paypal_payments/express_checkout/settings_ec/child_authorization_number"/>
-                        <group id="wpp_settings_express_checkout_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="80">
-                            <label>Advanced Settings</label>
-                            <fieldset_css>config-advanced</fieldset_css>
-                            <field id="allowspecific" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/allowspecific"/>
-                            <field id="specificcountry" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/specificcountry"/>
-                            <field id="debug" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/debug"/>
-                            <field id="verify_peer" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/verify_peer"/>
-                            <field id="line_items_enabled" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/line_items_enabled"/>
-                            <field id="transfer_shipping_options" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/transfer_shipping_options"/>
-                            <field id="button_flavor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/button_flavor"/>
-                            <field id="solution_type" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/solution_type"/>
-                            <field id="require_billing_address" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/require_billing_address"/>
-                            <field id="allow_ba_signup" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/allow_ba_signup"/>
-                        </group>
+                        <field id="business_account" translate="label comment tooltip" showInDefault="1" showInWebsite="1" sortOrder="5">
+                            <label>Email Associated with PayPal Merchant Account</label>
+                            <comment>
+                                <![CDATA[<a href="http://www.magentocommerce.com/paypal">Start accepting payments via PayPal!</a>]]>
+                            </comment>
+                            <tooltip>Don't have a PayPal account? Simply enter your email address.</tooltip>
+                            <config_path>paypal/general/business_account</config_path>
+                            <validate>validate-email</validate>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="api_authentication" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <label>API Authentication Methods</label>
+                            <config_path>paypal/wpp/api_authentication</config_path>
+                            <source_model>Magento\Paypal\Model\Config::getApiAuthenticationMethods</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="api_username" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>API Username</label>
+                            <config_path>paypal/wpp/api_username</config_path>
+                            <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="api_password" translate="label" type="obscure" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <label>API Password</label>
+                            <config_path>paypal/wpp/api_password</config_path>
+                            <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="api_signature" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <label>API Signature</label>
+                            <config_path>paypal/wpp/api_signature</config_path>
+                            <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
+                            <attribute type="shared">1</attribute>
+                            <depends>
+                                <field id="api_authentication">0</field>
+                            </depends>
+                        </field>
+                        <field id="api_cert" translate="label" type="file" sortOrder="60" showInDefault="1" showInWebsite="1">
+                            <label>API Certificate</label>
+                            <config_path>paypal/wpp/api_cert</config_path>
+                            <backend_model>Magento\Paypal\Model\System\Config\Backend\Cert</backend_model>
+                            <attribute type="shared">1</attribute>
+                            <depends>
+                                <field id="api_authentication">1</field>
+                            </depends>
+                        </field>
+                        <field id="api_wizard" translate="button_label attribute sandbox_button_label" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <button_label>Get Credentials from PayPal</button_label>
+                            <button_url>
+                                <![CDATA[https://www.paypal.com/us/cgi-bin/webscr?cmd=_login-api-run]]>
+                            </button_url>
+                            <attribute type="sandbox_button_label">Sandbox Credentials</attribute>
+                            <attribute type="sandbox_button_url">
+                                <![CDATA[https://www.sandbox.paypal.com/us/cgi-bin/webscr?cmd=_login-api-run]]>
+                            </attribute>
+                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\ApiWizard</frontend_model>
+                            <label/>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="sandbox_flag" translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1">
+                            <label>Sandbox Mode</label>
+                            <config_path>paypal/wpp/sandbox_flag</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="use_proxy" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1">
+                            <label>API Uses Proxy</label>
+                            <config_path>paypal/wpp/use_proxy</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="proxy_host" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1">
+                            <label>Proxy Host</label>
+                            <config_path>paypal/wpp/proxy_host</config_path>
+                            <attribute type="shared">1</attribute>
+                            <depends>
+                                <field id="use_proxy">1</field>
+                            </depends>
+                        </field>
+                        <field id="proxy_port" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1">
+                            <label>Proxy Port</label>
+                            <config_path>paypal/wpp/proxy_port</config_path>
+                            <attribute type="shared">1</attribute>
+                            <depends>
+                                <field id="use_proxy">1</field>
+                            </depends>
+                        </field>
                     </group>
+                    <field id="enable_express_checkout" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
+                        <label>Enable this Solution</label>
+                        <config_path>payment/paypal_express/active</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <attribute type="shared">1</attribute>
+                        <requires>
+                            <group id="express_checkout_required_express_checkout"/>
+                        </requires>
+                        <frontend_class>paypal-enabler paypal-ec-enabler</frontend_class>
+                    </field>
                 </group>
-                <group id="wps" type="text" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="50">
-                    <label>Website Payments Standard</label>
-                    <fieldset_css>pp-method-general</fieldset_css>
-                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
-                    <comment>Accept credit card and PayPal payments securely.</comment>
-                    <attribute type="activity_path">payment/paypal_standard/active</attribute>
-                    <more_url>https://www.paypal.com/webapps/mpp/referral/website-payments-standard?partner_id=NB9WWHYEMVUMS</more_url>
-                    <group id="wps_required_settings" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                        <label>Required PayPal Settings</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="business_account" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account"/>
-                        <field id="enable_wps" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
-                            <label>Enable this Solution</label>
-                            <config_path>payment/paypal_standard/active</config_path>
+                <group id="settings_ec" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                    <label>Basic Settings - PayPal Express Checkout</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Title</label>
+                        <comment>It is recommended to set this value to "Magento_Paypal" per store views.</comment>
+                        <config_path>payment/paypal_express/title</config_path>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Sort Order</label>
+                        <config_path>payment/paypal_express/sort_order</config_path>
+                        <frontend_class>validate-number</frontend_class>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                        <label>Payment Action</label>
+                        <config_path>payment/paypal_express/payment_action</config_path>
+                        <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions\Express</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="visible_on_cart" translate="label comment" type="select" sortOrder="35" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Shortcut on Shopping Cart</label>
+                        <config_path>payment/paypal_express/visible_on_cart</config_path>
+                        <comment>Also affects mini-shopping cart.</comment>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="visible_on_product" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <label>Shortcut on Product View</label>
+                        <config_path>payment/paypal_express/visible_on_product</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <attribute type="shared">1</attribute>
+                    </field>
+                    <field id="authorization_honor_period" translate="label comment" type="text" sortOrder="50" showInDefault="1" showInWebsite="1">
+                        <label>Authorization Honor Period (days)</label>
+                        <comment>Specifies what the Authorization Honor Period is on the merchant&#8217;s PayPal account. It must mirror the setting in PayPal.</comment>
+                        <config_path>payment/paypal_express/authorization_honor_period</config_path>
+                        <attribute type="shared">1</attribute>
+                        <depends>
+                            <field id="payment_action">Order</field>
+                        </depends>
+                    </field>
+                    <field id="order_valid_period" translate="label comment" type="text" sortOrder="60" showInDefault="1" showInWebsite="1">
+                        <label>Order Valid Period (days)</label>
+                        <comment>Specifies what the Order Valid Period is on the merchant&#x2019;s PayPal account. It must mirror the setting in PayPal.</comment>
+                        <config_path>payment/paypal_express/order_valid_period</config_path>
+                        <attribute type="shared">1</attribute>
+                        <depends>
+                            <field id="payment_action">Order</field>
+                        </depends>
+                    </field>
+                    <field id="child_authorization_number" translate="label comment" type="text" sortOrder="70" showInDefault="1" showInWebsite="1">
+                        <label>Number of Child Authorizations</label>
+                        <comment>The default number of child authorizations in your PayPal account is 1. To do multiple authorizations please contact PayPal to request an increase.</comment>
+                        <config_path>payment/paypal_express/child_authorization_number</config_path>
+                        <attribute type="shared">1</attribute>
+                        <depends>
+                            <field id="payment_action">Order</field>
+                        </depends>
+                    </field>
+                    <group id="settings_ec_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="80">
+                        <label>Advanced Settings</label>
+                        <fieldset_css>config-advanced</fieldset_css>
+                        <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
+                            <label>Payment Applicable From</label>
+                            <config_path>payment/paypal_express/allowspecific</config_path>
+                            <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <label>Countries Payment Applicable From</label>
+                            <config_path>payment/paypal_express/specificcountry</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
+                            <attribute type="shared">1</attribute>
+                            <depends>
+                                <field id="allowspecific">1</field>
+                            </depends>
+                        </field>
+                        <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>Debug Mode</label>
+                            <config_path>payment/paypal_express/debug</config_path>
                             <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <requires>
-                                <field id="business_account"/>
-                            </requires>
-                            <frontend_class>paypal-enabler paypal-ec-conflicts</frontend_class>
                             <attribute type="shared">1</attribute>
                         </field>
-                    </group>
-                    <group id="settings_payments_standart" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
-                        <label>Basic Settings - PayPal Website Payments Standard</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Title</label>
-                            <comment>It is recommended to set this value to "PayPal" per store views.</comment>
-                            <config_path>payment/paypal_standard/title</config_path>
+                        <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
+                            <label>Enable SSL verification</label>
+                            <config_path>payment/paypal_express/verify_peer</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Sort Order</label>
-                            <config_path>payment/paypal_standard/sort_order</config_path>
-                            <frontend_class>validate-number</frontend_class>
+                        <field id="line_items_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <label>Transfer Cart Line Items</label>
+                            <config_path>payment/paypal_express/line_items_enabled</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                            <label>Payment Action</label>
-                            <config_path>payment/paypal_standard/payment_action</config_path>
-                            <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                        <field id="transfer_shipping_options" translate="label tooltip comment" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <label>Transfer Shipping Options</label>
+                            <config_path>payment/paypal_express/transfer_shipping_options</config_path>
+                            <tooltip>If this option is enabled, customer can change shipping address and shipping method on PayPal website. In live mode works via HTTPS protocol only.</tooltip>
+                            <comment>Notice that PayPal can handle up to 10 shipping options. That is why Magento will transfer only first 10 cheapest shipping options if there are more than 10 available.</comment>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
+                            <depends>
+                                <field id="line_items_enabled">1</field>
+                            </depends>
                         </field>
-                        <group id="settings_payments_standart_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="40">
-                            <label>Advanced Settings</label>
-                            <fieldset_css>config-advanced</fieldset_css>
-                            <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
+                        <field id="button_flavor" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
+                            <label>Shortcut Buttons Flavor</label>
+                            <config_path>paypal/wpp/button_flavor</config_path>
+                            <source_model>Magento\Paypal\Model\Config::getExpressCheckoutButtonFlavors</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="solution_type" translate="label comment" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <label>Enable PayPal Guest Checkout</label>
+                            <comment>Ability for buyer to purchase without PayPal account.</comment>
+                            <config_path>payment/paypal_express/solution_type</config_path>
+                            <source_model>Magento\Paypal\Model\Config::getExpressCheckoutSolutionTypes</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="require_billing_address" translate="label comment" type="select" sortOrder="80" showInDefault="1" showInWebsite="1">
+                            <label>Require Customer's Billing Address</label>
+                            <comment>This feature needs be enabled first for the merchant account through PayPal technical support.</comment>
+                            <config_path>payment/paypal_express/require_billing_address</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\RequireBillingAddress</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <field id="allow_ba_signup" translate="label comment tooltip" type="select" sortOrder="90" showInDefault="1" showInWebsite="1">
+                            <label>Billing Agreement Signup</label>
+                            <comment>Whether to create a billing agreement, if there are no active billing agreements available.</comment>
+                            <tooltip>
+                                <![CDATA[Merchants need to apply to PayPal for enabling billing agreements feature. Do not enable this option until PayPal confirms that billing agreements are enabled for your merchant account.]]>
+                            </tooltip>
+                            <config_path>payment/paypal_express/allow_ba_signup</config_path>
+                            <source_model>Magento\Paypal\Model\Config::getExpressCheckoutBASignupOptions</source_model>
+                            <attribute type="shared">1</attribute>
+                        </field>
+                        <group id="express_checkout_billing_agreement" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="100">
+                            <label>PayPal Billing Agreement Settings</label>
+                            <field id="active" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
+                                <label>Enabled</label>
+                                <comment>
+                                    <![CDATA[Will appear as a payment option only for customers who have at least one active billing agreement.]]>
+                                </comment>
+                                <config_path>payment/paypal_billing_agreement/active</config_path>
+                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                                <attribute type="shared">1</attribute>
+                            </field>
+                            <field id="title" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>Title</label>
+                                <config_path>payment/paypal_billing_agreement/title</config_path>
+                                <attribute type="shared">1</attribute>
+                            </field>
+                            <field id="sort_order" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>Sort Order</label>
+                                <config_path>payment/paypal_billing_agreement/sort_order</config_path>
+                                <frontend_class>validate-number</frontend_class>
+                                <attribute type="shared">1</attribute>
+                            </field>
+                            <field id="payment_action" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
+                                <label>Payment Action</label>
+                                <config_path>payment/paypal_billing_agreement/payment_action</config_path>
+                                <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                                <attribute type="shared">1</attribute>
+                            </field>
+                            <field id="allowspecific" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
                                 <label>Payment Applicable From</label>
-                                <config_path>payment/paypal_standard/allowspecific</config_path>
+                                <config_path>payment/paypal_billing_agreement/allowspecific</config_path>
                                 <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <field id="specificcountry" translate="label" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1">
                                 <label>Countries Payment Applicable From</label>
-                                <config_path>payment/paypal_standard/specificcountry</config_path>
+                                <config_path>payment/paypal_billing_agreement/specificcountry</config_path>
                                 <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
+                                <attribute type="shared">1</attribute>
                                 <depends>
                                     <field id="allowspecific">1</field>
                                 </depends>
-                                <attribute type="shared">1</attribute>
                             </field>
-                            <field id="sandbox_flag" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                <label>Sandbox Mode</label>
-                                <config_path>payment/paypal_standard/sandbox_flag</config_path>
+                            <field id="debug" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
+                                <label>Debug Mode</label>
+                                <config_path>payment/paypal_billing_agreement/debug</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="line_items_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                <label>Transfer Cart Line Items</label>
-                                <config_path>payment/paypal_standard/line_items_enabled</config_path>
+                            <field id="verify_peer" translate="label" type="select" sortOrder="75" showInDefault="1" showInWebsite="1">
+                                <label>Enable SSL verification</label>
+                                <config_path>payment/paypal_billing_agreement/verify_peer</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="line_items_summary" translate="label comment" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
-                                <label>Summary Text for Aggregated Cart</label>
-                                <config_path>payment/paypal_standard/line_items_summary</config_path>
-                                <comment>Uses store frontend name by default.</comment>
-                                <depends>
-                                    <field id="line_items_enabled">1</field>
-                                </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="debug" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                <label>Debug Mode</label>
-                                <config_path>payment/paypal_standard/debug</config_path>
+                            <field id="line_items_enabled" translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1">
+                                <label>Transfer Cart Line Items</label>
+                                <config_path>payment/paypal_billing_agreement/line_items_enabled</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="verify_peer" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                <label>Enable SSL verification</label>
-                                <config_path>payment/paypal_standard/verify_peer</config_path>
+                            <field id="allow_billing_agreement_wizard" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1">
+                                <label>Allow in Billing Agreement Wizard</label>
+                                <config_path>payment/paypal_billing_agreement/allow_billing_agreement_wizard</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                         </group>
-                    </group>
-                </group>
-                <group id="paypal_payflowpro" type="text" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="10">
-                    <label>Payflow Pro</label>
-                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
-                    <fieldset_css>pp-method-payflow</fieldset_css>
-                    <comment>Connect your merchant account with a fully customizable gateway that lets customers pay without leaving your site.</comment>
-                    <attribute type="activity_path">payment/payflowpro/active</attribute>
-                    <more_url>https://www.paypal.com/webapps/mpp/referral/paypal-payflow-pro?partner_id=NB9WWHYEMVUMS</more_url>
-                    <attribute type="paypal_ec_separate">1</attribute>
-                    <group id="paypal_payflow_required" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                        <label>Required PayPal Settings</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <group id="paypal_payflow_api_settings" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                            <label>Payflow Pro</label>
-                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                            <field id="partner" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1">
-                                <label>Partner</label>
-                                <config_path>payment/payflowpro/partner</config_path>
+                        <group id="express_checkout_settlement_report" translate="label" showInDefault="1" showInWebsite="1" sortOrder="110">
+                            <label>Settlement Report Settings</label>
+                            <field id="heading_sftp" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1">
+                                <label>SFTP Credentials</label>
+                                <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="user" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                <label>User</label>
-                                <config_path>payment/payflowpro/user</config_path>
+                            <field id="settlement_reports_ftp_login" translate="label" type="obscure" sortOrder="20" showInDefault="1" showInWebsite="1">
+                                <label>Login</label>
+                                <config_path>paypal/fetch_reports/ftp_login</config_path>
                                 <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="vendor" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                <label>Vendor</label>
-                                <config_path>payment/payflowpro/vendor</config_path>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="pwd" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <field id="settlement_reports_ftp_password" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1">
                                 <label>Password</label>
-                                <config_path>payment/payflowpro/pwd</config_path>
+                                <config_path>paypal/fetch_reports/ftp_password</config_path>
                                 <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="sandbox_flag" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                <label>Test Mode</label>
-                                <config_path>payment/payflowpro/sandbox_flag</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="use_proxy" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                <label>Use Proxy</label>
-                                <config_path>payment/payflowpro/use_proxy</config_path>
+                            <field id="settlement_reports_ftp_sandbox" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
+                                <label>Sandbox Mode</label>
+                                <config_path>paypal/fetch_reports/ftp_sandbox</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="proxy_host" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1">
-                                <label>Proxy Host</label>
-                                <config_path>payment/payflowpro/proxy_host</config_path>
-                                <depends>
-                                    <field id="use_proxy">1</field>
-                                </depends>
+                            <field id="settlement_reports_ftp_ip" translate="label comment tooltip" type="text" sortOrder="50" showInDefault="1" showInWebsite="1">
+                                <label>Custom Endpoint Hostname or IP-Address</label>
+                                <comment>By default it is "reports.paypal.com".</comment>
+                                <tooltip>Use colon to specify port. For example: "test.example.com:5224".</tooltip>
+                                <config_path>paypal/fetch_reports/ftp_ip</config_path>
                                 <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="proxy_port" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1">
-                                <label>Proxy Port</label>
-                                <config_path>payment/payflowpro/proxy_port</config_path>
                                 <depends>
-                                    <field id="use_proxy">1</field>
+                                    <field id="settlement_reports_ftp_sandbox">0</field>
                                 </depends>
-                                <attribute type="shared">1</attribute>
                             </field>
-                        </group>
-                        <field id="enable_paypal_payflow" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
-                            <label>Enable this Solution</label>
-                            <config_path>payment/payflowpro/active</config_path>
-                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <requires>
-                                <group id="paypal_payflow_api_settings"/>
-                            </requires>
-                            <frontend_class>paypal-enabler paypal-ec-separate</frontend_class>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                    </group>
-                    <group id="settings_paypal_payflow" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
-                        <label>Basic Settings - PayPal Payflow Pro</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Title</label>
-                            <comment>It is recommended to set this value to "Debit or Credit Card" per store views.</comment>
-                            <config_path>payment/payflowpro/title</config_path>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Sort Order</label>
-                            <config_path>payment/payflowpro/sort_order</config_path>
-                            <frontend_class>validate-number</frontend_class>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                            <label>Payment Action</label>
-                            <config_path>payment/payflowpro/payment_action</config_path>
-                            <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <field id="heading_cc" translate="label" sortOrder="40" showInDefault="1" showInWebsite="1">
-                            <label>Credit Card Settings</label>
-                            <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <field id="cctypes" translate="label comment" type="multiselect" sortOrder="50" showInDefault="1" showInWebsite="1">
-                            <label>Allowed Credit Card Types</label>
-                            <comment>
-                                <![CDATA[Supporting of American Express cards require additional agreement. Learn more at <a href="http://www.paypal.com/amexupdate">http://www.paypal.com/amexupdate</a>.]]>
-                            </comment>
-                            <config_path>payment/payflowpro/cctypes</config_path>
-                            <source_model>Magento\Paypal\Model\Config::getPayflowproCcTypesAsOptionArray</source_model>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <group id="settings_paypal_payflow_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="60">
-                            <label>Advanced Settings</label>
-                            <fieldset_css>config-advanced</fieldset_css>
-                            <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
-                                <label>Payment Applicable From</label>
-                                <config_path>payment/payflowpro/allowspecific</config_path>
-                                <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
+                            <field id="settlement_reports_ftp_path" translate="label comeent" type="text" sortOrder="60" showInDefault="1" showInWebsite="1">
+                                <label>Custom Path</label>
+                                <comment>By default it is "/ppreports/outgoing".</comment>
+                                <config_path>paypal/fetch_reports/ftp_path</config_path>
                                 <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
-                                <label>Countries Payment Applicable From</label>
-                                <config_path>payment/payflowpro/specificcountry</config_path>
-                                <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
                                 <depends>
-                                    <field id="allowspecific">1</field>
+                                    <field id="settlement_reports_ftp_sandbox">0</field>
                                 </depends>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                <label>Debug Mode</label>
-                                <config_path>payment/payflowpro/debug</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
-                                <label>Enable SSL verification</label>
-                                <config_path>payment/payflowpro/verify_peer</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="useccv" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                <label>Require CVV Entry</label>
-                                <config_path>payment/payflowpro/useccv</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
                             </field>
-                            <field id="heading_3dsecure" translate="label" sortOrder="50" showInDefault="1" showInWebsite="1">
-                                <label>3D Secure</label>
+                            <field id="heading_schedule" translate="label" sortOrder="70" showInDefault="1" showInWebsite="1">
+                                <label>Scheduled Fetching</label>
                                 <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="centinel" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                <label>3D Secure Card Validation</label>
-                                <config_path>payment/payflowpro/centinel</config_path>
+                            <field id="settlement_reports_active" translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1">
+                                <label>Enable Automatic Fetching</label>
+                                <config_path>paypal/fetch_reports/active</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="centinel_is_mode_strict" translate="label comment" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                <label>Severe 3D Secure Card Validation</label>
-                                <config_path>payment/payflowpro/centinel_is_mode_strict</config_path>
-                                <comment>Severe validation removes chargeback liability on merchant.</comment>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <depends>
-                                    <field id="centinel">1</field>
-                                </depends>
+                            <field id="settlement_reports_schedule" translate="label comment" type="select" sortOrder="90" showInDefault="1">
+                                <label>Schedule</label>
+                                <comment>PayPal retains reports for 45 days.</comment>
+                                <config_path>paypal/fetch_reports/schedule</config_path>
+                                <source_model>Magento\Paypal\Model\System\Config\Source\FetchingSchedule</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="centinel_api_url" translate="label comment" type="text" sortOrder="80" showInDefault="1" showInWebsite="1">
-                                <label>Centinel API URL</label>
-                                <config_path>payment/payflowpro/centinel_api_url</config_path>
-                                <comment>A value is required for live mode. Refer to your CardinalCommerce agreement.</comment>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <depends>
-                                    <field id="centinel">1</field>
-                                </depends>
+                            <field id="settlement_reports_time" translate="label" type="time" sortOrder="100" showInDefault="1">
+                                <label>Time of Day</label>
+                                <config_path>paypal/fetch_reports/time</config_path>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <group id="paypal_payflow_settlement_report" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="90">
-                                <label>Settlement Report Settings</label>
-                                <field id="heading_sftp" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
-                                <field id="settlement_reports_ftp_login" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login"/>
-                                <field id="settlement_reports_ftp_password" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password"/>
-                                <field id="settlement_reports_ftp_sandbox" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox"/>
-                                <field id="settlement_reports_ftp_ip" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip"/>
-                                <field id="settlement_reports_ftp_path" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path"/>
-                                <field id="heading_schedule" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule"/>
-                                <field id="settlement_reports_active" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active"/>
-                                <field id="settlement_reports_schedule" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule"/>
-                                <field id="settlement_reports_time" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time"/>
-                            </group>
                         </group>
-                    </group>
-                </group>
-                <group id="paypal_payflowpro_with_express_checkout" type="group" translate="label comment" extends="payment/paypal_payments/paypal_payflowpro">
-                    <label>Payflow Pro (Includes Express Checkout)</label>
-                    <attribute type="paypal_ec_separate">0</attribute>
-                    <group id="paypal_payflow_required" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                        <label>Required PayPal Settings</label>
-                        <group id="paypal_payflow_api_settings" type="group" translate="label">
-                            <label>Payflow Pro and Express Checkout</label>
-                            <field id="business_account" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account" translate="label" sortOrder="10">
-                                <frontend_class>not-required</frontend_class>
-                                <label>Email Associated with PayPal Merchant Account (Optional)</label>
+                        <group id="express_checkout_frontend" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="120">
+                            <label>Frontend Experience Settings</label>
+                            <field id="logo" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>PayPal Product Logo</label>
+                                <comment>Displays on catalog pages and homepage.</comment>
+                                <config_path>paypal/style/logo</config_path>
+                                <source_model>Magento\Paypal\Model\System\Config\Source\Logo</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                        </group>
-                    </group>
-                    <group id="settings_paypal_payflow" type="group" translate="label">
-                        <group id="settings_paypal_payflow_advanced" type="group" translate="label">
-                            <group id="paypal_payflow_frontend" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="100">
-                                <label>Frontend Experience Settings</label>
-                                <field id="logo" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo"/>
-                                <field id="paypal_pages" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages"/>
-                                <field id="page_style" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style"/>
-                                <field id="paypal_hdrimg" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg"/>
-                                <field id="paypal_hdrbackcolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor"/>
-                                <field id="paypal_hdrbordercolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor"/>
-                                <field id="paypal_payflowcolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor"/>
-                            </group>
-                        </group>
-                    </group>
-                    <group id="paypal_payflow_express_checkout" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
-                        <label>Basic Settings - PayPal Express Checkout</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Title</label>
-                            <config_path>payment/payflow_express/title</config_path>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Sort Order</label>
-                            <config_path>payment/payflow_express/sort_order</config_path>
-                            <frontend_class>validate-number</frontend_class>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                            <label>Payment Action</label>
-                            <config_path>payment/payflow_express/payment_action</config_path>
-                            <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <field id="visible_on_cart" translate="label comment" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Shortcut on Shopping Cart</label>
-                            <comment>Also affects mini-shopping cart.</comment>
-                            <config_path>payment/payflow_express/visible_on_cart</config_path>
-                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <field id="visible_on_product" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
-                            <label>Shortcut on Product View</label>
-                            <config_path>payment/payflow_express/visible_on_product</config_path>
-                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <attribute type="shared">1</attribute>
-                        </field>
-                        <group id="paypal_payflow_express_checkout_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="60">
-                            <label>Advanced Settings</label>
-                            <fieldset_css>config-advanced</fieldset_css>
-                            <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
-                                <label>Payment Applicable From</label>
-                                <config_path>payment/payflow_express/allowspecific</config_path>
-                                <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
+                            <field id="paypal_pages" translate="label" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>PayPal Merchant Pages Style</label>
+                                <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
-                                <label>Countries Payment Applicable From</label>
-                                <config_path>payment/payflow_express/specificcountry</config_path>
-                                <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
-                                <depends>
-                                    <field id="allowspecific">1</field>
-                                </depends>
+                            <field id="page_style" translate="label tooltip" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>Page Style</label>
+                                <config_path>paypal/style/page_style</config_path>
+                                <tooltip>
+                                    <![CDATA[Allowable values: "paypal", "primary" (default), your_custom_value (a custom payment page style from your merchant account profile).]]>
+                                </tooltip>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                <label>Debug Mode</label>
-                                <config_path>payment/payflow_express/debug</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <field id="paypal_hdrimg" translate="label tooltip" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>Header Image URL</label>
+                                <config_path>paypal/style/paypal_hdrimg</config_path>
+                                <tooltip>
+                                    <![CDATA[The image at the top left of the checkout page. Max size is 750x90-pixel. <strong style="color:red">https</strong> is highly encouraged.]]>
+                                </tooltip>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
-                                <label>Enable SSL verification</label>
-                                <config_path>payment/payflow_express/verify_peer</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <field id="paypal_hdrbackcolor" translate="label tooltip" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>Header Background Color</label>
+                                <config_path>paypal/style/paypal_hdrbackcolor</config_path>
+                                <tooltip>
+                                    <![CDATA[The background color for the header of the checkout page. Case-insensitive six-character HTML hexadecimal color code in ASCII.]]>
+                                </tooltip>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="line_items_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                <label>Transfer Cart Line Items</label>
-                                <config_path>payment/payflow_express/line_items_enabled</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                            <field id="paypal_hdrbordercolor" translate="label tooltip" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>Header Border Color</label>
+                                <config_path>paypal/style/paypal_hdrbordercolor</config_path>
+                                <tooltip>2-pixel perimeter around the header space.</tooltip>
+                                <attribute type="shared">1</attribute>
+                            </field>
+                            <field id="paypal_payflowcolor" translate="label tooltip" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="1">
+                                <label>Page Background Color</label>
+                                <config_path>paypal/style/paypal_payflowcolor</config_path>
+                                <tooltip>
+                                    <![CDATA[The background color for the checkout page around the header and payment form.]]>
+                                </tooltip>
                                 <attribute type="shared">1</attribute>
                             </field>
                         </group>
                     </group>
                 </group>
-                <group id="payflow_link" type="text" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
-                    <label>Payflow Link (Includes Express Checkout)</label>
+            </group>
+            <group id="payments_pro_hosted_solution" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                <label>Website Payments Pro Hosted Solution</label>
+                <fieldset_css>pp-method-general</fieldset_css>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
+                <attribute type="activity_path">payment/hosted_pro/active</attribute>
+                <comment>Accept payments with a PCI compliant checkout that keeps customers on your site.</comment>
+                <attribute type="paypal_ec_separate">1</attribute>
+                <group id="pphs_required_settings" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                    <label>Required PayPal Settings</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <group id="pphs_required_settings_pphs" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                        <label>Payments Pro Hosted Solution</label>
+                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                        <field id="business_account" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account"/>
+                        <field id="api_authentication" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_authentication"/>
+                        <field id="api_username" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_username" />
+                        <field id="api_password" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_password" />
+                        <field id="api_signature" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_signature" />
+                        <field id="api_cert" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_cert" />
+                        <field id="api_wizard" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/api_wizard" />
+                        <field id="sandbox_flag" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/sandbox_flag" />
+                        <field id="use_proxy" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/use_proxy" />
+                        <field id="proxy_host" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/proxy_host" />
+                        <field id="proxy_port" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/proxy_port" />
+                    </group>
+                    <field id="pphs_enable" type="select" translate="label" sortOrder="20" showInDefault="1" showInWebsite="1">
+                        <label>Enable this Solution</label>
+                        <config_path>payment/hosted_pro/active</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        <requires>
+                            <group id="pphs_required_settings"/>
+                        </requires>
+                        <frontend_class>paypal-enabler paypal-ec-separate</frontend_class>
+                    </field>
+                </group>
+                <group id="pphs_settings" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                    <label>Basic Settings - PayPal Payments Pro Hosted Solution</label>
+                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                    <field id="title" type="text" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="10" translate="label comment">
+                        <label>Title</label>
+                        <comment>It is recommended to set this value to "PayPal" per store views.</comment>
+                        <config_path>payment/hosted_pro/title</config_path>
+                    </field>
+                    <field id="sort_order" type="text" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20" translate="label">
+                        <label>Sort Order</label>
+                        <config_path>payment/hosted_pro/sort_order</config_path>
+                        <frontend_class>validate-number</frontend_class>
+                    </field>
+                    <field id="payment_action" type="select" showInDefault="1" showInWebsite="1" sortOrder="30" translate="label">
+                        <label>Payment Action</label>
+                        <config_path>payment/hosted_pro/payment_action</config_path>
+                        <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
+                    </field>
+                    <field id="display_ec" type="select" showInDefault="1" showInWebsite="1" sortOrder="40" translate="label">
+                        <label>Display Express Checkout in the Payment Information step</label>
+                        <config_path>payment/hosted_pro/display_ec</config_path>
+                        <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                    </field>
+                    <group id="pphs_settings_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="50">
+                        <label>Advanced Settings</label>
+                        <fieldset_css>config-advanced</fieldset_css>
+                        <field id="allowspecific" type="select" showInDefault="1" showInWebsite="1" sortOrder="10" translate="label">
+                            <label>Payment Applicable From</label>
+                            <config_path>payment/hosted_pro/allowspecific</config_path>
+                            <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
+                        </field>
+                        <field id="specificcountry" type="multiselect" showInDefault="1" showInWebsite="1" sortOrder="20" translate="label">
+                            <label>Countries Payment Applicable From</label>
+                            <config_path>payment/hosted_pro/specificcountry</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
+                            <depends>
+                                <field id="allowspecific">1</field>
+                            </depends>
+                        </field>
+                        <field id="debug" type="select" showInDefault="1" showInWebsite="1" sortOrder="30" translate="label">
+                            <label>Debug Mode</label>
+                            <config_path>payment/hosted_pro/debug</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        </field>
+                        <field id="verify_peer" type="select" showInDefault="1" showInWebsite="1" sortOrder="35" translate="label">
+                            <label>Enable SSL verification</label>
+                            <config_path>payment/hosted_pro/verify_peer</config_path>
+                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                        </field>
+                        <group id="pphs_settlement_report" showInDefault="1" showInWebsite="1" sortOrder="50" translate="label">
+                            <label>Settlement Report Settings</label>
+                            <field id="heading_sftp" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
+                            <field id="settlement_reports_ftp_login" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login" />
+                            <field id="settlement_reports_ftp_password" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password" />
+                            <field id="settlement_reports_ftp_sandbox" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox" />
+                            <field id="settlement_reports_ftp_ip" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip" />
+                            <field id="settlement_reports_ftp_path" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path" />
+                            <field id="heading_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule" />
+                            <field id="settlement_reports_active" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active" />
+                            <field id="settlement_reports_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule" />
+                            <field id="settlement_reports_time" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time" />
+                        </group>
+                    </group>
+                </group>
+            </group>
+        </section>
+        <section id="payment_usgb" extends="payment" showInDefault="0" showInWebsite="0" showInStore="0">
+            <group id="paypal_group_all_in_one" translate="label comment" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>
+                    <![CDATA[PayPal All-in-One Payment Solutions&nbsp;&nbsp;<i>Accept and process credit cards and PayPal payments.</i>]]>
+                </label>
+                <attribute type="expanded">1</attribute>
+                <fieldset_css>complex</fieldset_css>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
+                <comment>Choose a secure bundled payment solution for your business.</comment>
+                <help_url>https://www.paypal-marketing.com/emarketing/partner/na/merchantlineup/home.page#mainTab=checkoutlineup&amp;subTab=newlineup</help_url>
+                <group id="wpp_usuk" extends="payment_all_paypal/wpp"/>
+                <group id="wps_usuk" extends="payment_all_paypal/wps"/>
+            </group>
+            <group id="paypal_alternative_payment_methods" translate="label comment attribute" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>PayPal Express Checkout</label>
+                <attribute type="expanded">1</attribute>
+                <fieldset_css>complex</fieldset_css>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
+                <comment>Add another payment method to your existing solution or as a stand-alone option.</comment>
+                <help_url>https://merchant.paypal.com/cgi-bin/marketingweb?cmd=_render-content</help_url>
+                <group id="express_checkout_us" extends="payment_all_paypal/express_checkout" />
+            </group>
+        </section>
+        <section id="payment_us" extends="payment_usgb">
+            <group id="paypal_group_all_in_one">
+                <group id="payflow_advanced" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
+                    <label>Payments Advanced (Includes Express Checkout)</label>
+                    <fieldset_css>pp-method-general</fieldset_css>
                     <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
-                    <fieldset_css>pp-method-payflow</fieldset_css>
-                    <comment>Connect your merchant account with a PCI-compliant gateway that lets customers pay without leaving your site.</comment>
-                    <attribute type="activity_path">payment/payflow_link/active</attribute>
-                    <more_url>https://www.paypal.com/webapps/mpp/referral/paypal-payflow-link?partner_id=NB9WWHYEMVUMS</more_url>
-                    <group id="payflow_link_required" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                    <more_url>https://www.paypal.com/webapps/mpp/referral/paypal-payments-advanced?partner_id=NB9WWHYEMVUMS</more_url>
+                    <comment>Accept payments with a PCI-compliant checkout that keeps customers on your site.</comment>
+                    <attribute type="activity_path">payment/payflow_advanced/active</attribute>
+                    <group id="required_settings" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
                         <label>Required PayPal Settings</label>
                         <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <group id="payflow_link_payflow_link" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                            <label>Payflow Link and Express Checkout</label>
+                        <group id="payments_advanced" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                            <label>Payments Advanced and Express Checkout</label>
                             <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                            <field id="business_account" extends="payment/paypal_payments/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account" translate="label" sortOrder="5">
-                                <frontend_class>not-required</frontend_class>
+                            <field id="business_account" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account">
                                 <label>Email Associated with PayPal Merchant Account (Optional)</label>
-                                <attribute type="shared">1</attribute>
                             </field>
-                            <field id="partner" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1">
+                            <field id="partner" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1">
                                 <label>Partner</label>
-                                <config_path>payment/payflow_link/partner</config_path>
+                                <config_path>payment/payflow_advanced/partner</config_path>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="vendor" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <field id="vendor" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1">
                                 <label>Vendor</label>
-                                <config_path>payment/payflow_link/vendor</config_path>
+                                <config_path>payment/payflow_advanced/vendor</config_path>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="user" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <field id="user" translate="label comment tooltip" type="text" sortOrder="40" showInDefault="1" showInWebsite="1">
                                 <label>User</label>
-                                <comment>If you do not have multiple users set up on your account, please re-enter your Vendor/Merchant Login here.</comment>
-                                <config_path>payment/payflow_link/user</config_path>
+                                <comment>PayPal recommends that you set up an additional User on your account at manager.paypal.com</comment>
+                                <tooltip>PayPal recommends you set up an additional User on your account at manager.paypal.com, instead of entering your admin username and password here. This will enhance your security and prevent service interruptions if you later change your password. If you do not want to set up an additional User, you can re-enter your Merchant Login here.</tooltip>
+                                <config_path>payment/payflow_advanced/user</config_path>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="pwd" translate="label" type="obscure" sortOrder="40" showInDefault="1" showInWebsite="1">
+                            <field id="pwd" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1">
                                 <label>Password</label>
-                                <config_path>payment/payflow_link/pwd</config_path>
+                                <config_path>payment/payflow_advanced/pwd</config_path>
                                 <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="sandbox_flag" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
+                            <field id="sandbox_flag" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
                                 <label>Test Mode</label>
-                                <config_path>payment/payflow_link/sandbox_flag</config_path>
+                                <config_path>payment/payflow_advanced/sandbox_flag</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="use_proxy" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
+                            <field id="use_proxy" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
                                 <label>Use Proxy</label>
-                                <config_path>payment/payflow_link/use_proxy</config_path>
+                                <config_path>payment/payflow_advanced/use_proxy</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="proxy_host" translate="label" type="text" sortOrder="70" showInDefault="1" showInWebsite="1">
+                            <field id="proxy_host" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1">
                                 <label>Proxy Host</label>
-                                <config_path>payment/payflow_link/proxy_host</config_path>
+                                <config_path>payment/payflow_advanced/proxy_host</config_path>
                                 <depends>
                                     <field id="use_proxy">1</field>
                                 </depends>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="proxy_port" translate="label" type="text" sortOrder="80" showInDefault="1" showInWebsite="1">
+                            <field id="proxy_port" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1">
                                 <label>Proxy Port</label>
-                                <config_path>payment/payflow_link/proxy_port</config_path>
+                                <config_path>payment/payflow_advanced/proxy_port</config_path>
                                 <depends>
                                     <field id="use_proxy">1</field>
                                 </depends>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="payflowlink_info" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="90">
-                                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Payflowlink\Info</frontend_model>
+                            <field id="payflow_advanced_info" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="100">
+                                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Payflowlink\Advanced</frontend_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                         </group>
-                        <field id="enable_payflow_link" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
-                            <label>Enable Payflow Link</label>
-                            <config_path>payment/payflow_link/active</config_path>
+                        <field id="enable_payflow_advanced" translate="label comment" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
+                            <label>Enable this Solution</label>
+                            <config_path>payment/payflow_advanced/active</config_path>
                             <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <requires>
-                                <group id="payflow_link_payflow_link"/>
+                                <group id="payments_advanced"/>
                             </requires>
-                            <frontend_class>paypal-enabler paypal-ec-pe paypal-payflowlink</frontend_class>
+                            <frontend_class>paypal-enabler paypal-ec-pe paypal-payflow-advanced</frontend_class>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="enable_express_checkout" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                            <label>Enable Express Checkout</label>
-                            <config_path>payment/payflow_express/active</config_path>
-                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <frontend_class>paypal-ec-payflow-enabler</frontend_class>
-                            <attribute type="shared">1</attribute>
+                        <field id="enable_express_checkout" extends="payment_all_paypal/payflow_link/payflow_link_required/enable_express_checkout_basic" showInDefault="1" showInWebsite="1">
+                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Field\Hidden</frontend_model>
                             <requires>
-                                <field id="enable_payflow_link"/>
+                                <field id="enable_payflow_advanced"/>
                             </requires>
                         </field>
                     </group>
-                    <group id="settings_payflow_link" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
-                        <label>Basic Settings - PayPal Payflow Link</label>
+                    <group id="settings_payments_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                        <label>Basic Settings - PayPal Payments Advanced</label>
                         <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
                         <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                             <label>Title</label>
                             <comment>It is recommended to set this value to "Debit or Credit Card" per store views.</comment>
-                            <config_path>payment/payflow_link/title</config_path>
+                            <config_path>payment/payflow_advanced/title</config_path>
                             <attribute type="shared">1</attribute>
                         </field>
                         <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                             <label>Sort Order</label>
-                            <config_path>payment/payflow_link/sort_order</config_path>
+                            <config_path>payment/payflow_advanced/sort_order</config_path>
                             <frontend_class>validate-number</frontend_class>
                             <attribute type="shared">1</attribute>
                         </field>
                         <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
                             <label>Payment Action</label>
-                            <config_path>payment/payflow_link/payment_action</config_path>
+                            <config_path>payment/payflow_advanced/payment_action</config_path>
                             <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <group id="settings_payflow_link_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="40">
+                        <group id="settings_payments_advanced_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="40">
                             <label>Advanced Settings</label>
                             <fieldset_css>config-advanced</fieldset_css>
-                            <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
+                            <field id="allowspecific" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
                                 <label>Payment Applicable From</label>
-                                <config_path>payment/payflow_link/allowspecific</config_path>
+                                <config_path>payment/payflow_advanced/allowspecific</config_path>
                                 <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
+                            <field id="specificcountry" translate="label" type="multiselect" sortOrder="25" showInDefault="1" showInWebsite="1">
                                 <label>Countries Payment Applicable From</label>
-                                <config_path>payment/payflow_link/specificcountry</config_path>
+                                <config_path>payment/payflow_advanced/specificcountry</config_path>
                                 <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
                                 <depends>
                                     <field id="allowspecific">1</field>
@@ -1029,25 +1452,25 @@
                             </field>
                             <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
                                 <label>Debug Mode</label>
-                                <config_path>payment/payflow_link/debug</config_path>
+                                <config_path>payment/payflow_advanced/debug</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                             <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
                                 <label>Enable SSL verification</label>
-                                <config_path>payment/payflow_link/verify_peer</config_path>
+                                <config_path>payment/payflow_advanced/verify_peer</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                             <field id="csc_editable" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
                                 <label>CVV Entry is Editable</label>
-                                <config_path>payment/payflow_link/csc_editable</config_path>
+                                <config_path>payment/payflow_advanced/csc_editable</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                             <field id="csc_required" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
                                 <label>Require CVV Entry</label>
-                                <config_path>payment/payflow_link/csc_required</config_path>
+                                <config_path>payment/payflow_advanced/csc_required</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <depends>
                                     <field id="csc_editable">1</field>
@@ -1056,495 +1479,368 @@
                             </field>
                             <field id="email_confirmation" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1">
                                 <label>Send Email Confirmation</label>
-                                <config_path>payment/payflow_link/email_confirmation</config_path>
+                                <config_path>payment/payflow_advanced/email_confirmation</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                             <field id="url_method" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
                                 <label>URL method for Cancel URL and Return URL</label>
-                                <config_path>payment/payflow_link/url_method</config_path>
+                                <config_path>payment/payflow_advanced/url_method</config_path>
                                 <source_model>Magento\Paypal\Model\System\Config\Source\UrlMethod</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
-                            <group id="payflow_link_settlement_report" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="80">
+                            <group id="settlement_report" translate="label" showInDefault="1" showInWebsite="1" sortOrder="80">
                                 <label>Settlement Report Settings</label>
-                                <field id="heading_sftp" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
-                                <field id="settlement_reports_ftp_login" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login"/>
-                                <field id="settlement_reports_ftp_password" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password"/>
-                                <field id="settlement_reports_ftp_sandbox" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox"/>
-                                <field id="settlement_reports_ftp_ip" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip"/>
-                                <field id="settlement_reports_ftp_path" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path"/>
-                                <field id="heading_schedule" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule"/>
-                                <field id="settlement_reports_active" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active"/>
-                                <field id="settlement_reports_schedule" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule"/>
-                                <field id="settlement_reports_time" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time"/>
+                                <field id="heading_sftp" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_sftp"/>
+                                <field id="settlement_reports_ftp_login" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_login"/>
+                                <field id="settlement_reports_ftp_password" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_password"/>
+                                <field id="settlement_reports_ftp_sandbox" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_sandbox"/>
+                                <field id="settlement_reports_ftp_ip" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_ip"/>
+                                <field id="settlement_reports_ftp_path" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_ftp_path"/>
+                                <field id="heading_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/heading_schedule"/>
+                                <field id="settlement_reports_active" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_active"/>
+                                <field id="settlement_reports_schedule" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_schedule"/>
+                                <field id="settlement_reports_time" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_settlement_report/settlement_reports_time"/>
                             </group>
-                            <group id="payflow_link_frontend" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="90">
+                            <group id="frontend" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="90">
                                 <label>Frontend Experience Settings</label>
-                                <field id="logo" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo"/>
-                                <field id="paypal_pages" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages"/>
-                                <field id="page_style" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style"/>
-                                <field id="paypal_hdrimg" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg"/>
-                                <field id="paypal_hdrbackcolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor"/>
-                                <field id="paypal_hdrbordercolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor"/>
-                                <field id="paypal_payflowcolor" extends="payment/paypal_payments/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor"/>
+                                <field id="logo" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo"/>
+                                <field id="paypal_pages" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages"/>
+                                <field id="page_style" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style"/>
+                                <field id="paypal_hdrimg" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg"/>
+                                <field id="paypal_hdrbackcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor"/>
+                                <field id="paypal_hdrbordercolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor"/>
+                                <field id="paypal_payflowcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor"/>
                             </group>
                         </group>
                     </group>
-                    <group id="settings_payflow_link_express_checkout" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
+                    <group id="settings_express_checkout" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
                         <label>Basic Settings - PayPal Express Checkout</label>
                         <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/title" />
-                        <field id="sort_order" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/sort_order" />
-                        <field id="payment_action" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/payment_action" />
-                        <field id="visible_on_cart" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/visible_on_cart" />
-                        <field id="visible_on_product" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/visible_on_product" />
-                        <group id="settings_payflow_link_express_checkout_advanced" type="group" extends="payment/paypal_payments/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/paypal_payflow_express_checkout_advanced"/>
+                        <field id="title" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/title" />
+                        <field id="sort_order" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/sort_order" />
+                        <field id="payment_action" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/payment_action" />
+                        <field id="visible_on_cart" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/visible_on_cart" />
+                        <field id="visible_on_product" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/visible_on_product" />
+                        <group id="settings_express_checkout_advanced" extends="payment_us/paypal_payment_gateways/paypal_payflowpro_with_express_checkout/paypal_payflow_express_checkout/paypal_payflow_express_checkout_advanced"/>
                     </group>
                 </group>
-                <group id="express_checkout" type="text" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="60">
-                    <label>Express Checkout</label>
-                    <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment</frontend_model>
-                    <fieldset_css>pp-method-express</fieldset_css>
-                    <comment>Add PayPal as an additional payment method to your checkout page.</comment>
-                    <attribute type="activity_path">payment/paypal_express/active</attribute>
-                    <more_url>https://www.paypal.com/webapps/mpp/referral/paypal-express-checkout?partner_id=NB9WWHYEMVUMS</more_url>
-                    <group id="express_checkout_required" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
+                <group id="wpp_usuk" translate="label">
+                    <label>Payments Pro (Includes Express Checkout)</label>
+                    <group id="wpp_required_settings">
+                        <group id="wpp_and_express_checkout" translate="label">
+                            <label>Payments Pro and Express Checkout</label>
+                        </group>
+                    </group>
+                    <group id="wpp_settings" translate="label">
+                        <label>Basic Settings - PayPal Payments Pro</label>
+                    </group>
+                </group>
+                <group id="wps_usuk" translate="label">
+                    <label>Payments Standard</label>
+                    <group id="settings_payments_standart" translate="label">
+                        <label>Basic Settings - PayPal Payments Standard</label>
+                    </group>
+                </group>
+            </group>
+            <group id="paypal_payment_gateways" translate="label comment" sortOrder="15" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>PayPal Payment Gateways</label>
+                <fieldset_css>complex</fieldset_css>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
+                <comment>Process payments using your own internet merchant account.</comment>
+                <help_url>https://merchant.paypal.com/cgi-bin/marketingweb?cmd=_render-content</help_url>
+                <group id="payflow_link_us" extends="payment_all_paypal/payflow_link"/>
+                <group id="paypal_payflowpro_with_express_checkout" translate="label comment" extends="payment_all_paypal/paypal_payflowpro">
+                    <label>Payflow Pro (Includes Express Checkout)</label>
+                    <attribute type="paypal_ec_separate">0</attribute>
+                    <group id="paypal_payflow_required" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
                         <label>Required PayPal Settings</label>
-                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <group id="express_checkout_required_express_checkout" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="10">
-                            <label>Express Checkout</label>
-                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                            <field id="business_account" translate="label comment tooltip" showInDefault="1" showInWebsite="1" sortOrder="5">
-                                <label>Email Associated with PayPal Merchant Account</label>
-                                <comment>
-                                    <![CDATA[<a href="http://www.magentocommerce.com/paypal">Start accepting payments via PayPal!</a>]]>
-                                </comment>
-                                <tooltip>Don't have a PayPal account? Simply enter your email address.</tooltip>
-                                <config_path>paypal/general/business_account</config_path>
-                                <validate>validate-email</validate>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="api_authentication" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
-                                <label>API Authentication Methods</label>
-                                <config_path>paypal/wpp/api_authentication</config_path>
-                                <source_model>Magento\Paypal\Model\Config::getApiAuthenticationMethods</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="api_username" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                <label>API Username</label>
-                                <config_path>paypal/wpp/api_username</config_path>
-                                <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="api_password" translate="label" type="obscure" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                <label>API Password</label>
-                                <config_path>paypal/wpp/api_password</config_path>
-                                <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="api_signature" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1">
-                                <label>API Signature</label>
-                                <config_path>paypal/wpp/api_signature</config_path>
-                                <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
-                                <attribute type="shared">1</attribute>
-                                <depends>
-                                    <field id="api_authentication">0</field>
-                                </depends>
-                            </field>
-                            <field id="api_cert" translate="label" type="file" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                <label>API Certificate</label>
-                                <config_path>paypal/wpp/api_cert</config_path>
-                                <backend_model>Magento\Paypal\Model\System\Config\Backend\Cert</backend_model>
-                                <attribute type="shared">1</attribute>
-                                <depends>
-                                    <field id="api_authentication">1</field>
-                                </depends>
-                            </field>
-                            <field id="api_wizard" translate="button_label attribute" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                <button_label>Get Credentials from PayPal</button_label>
-                                <button_url>
-                                    <![CDATA[https://www.paypal.com/us/cgi-bin/webscr?cmd=_login-api-run]]>
-                                </button_url>
-                                <attribute type="sandbox_button_label">Sandbox Credentials</attribute>
-                                <attribute type="sandbox_button_url">
-                                    <![CDATA[https://www.sandbox.paypal.com/us/cgi-bin/webscr?cmd=_login-api-run]]>
-                                </attribute>
-                                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\ApiWizard</frontend_model>
-                                <label/>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="sandbox_flag" translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1">
-                                <label>Sandbox Mode</label>
-                                <config_path>paypal/wpp/sandbox_flag</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="use_proxy" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1">
-                                <label>API Uses Proxy</label>
-                                <config_path>paypal/wpp/use_proxy</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="proxy_host" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1">
-                                <label>Proxy Host</label>
-                                <config_path>paypal/wpp/proxy_host</config_path>
-                                <attribute type="shared">1</attribute>
-                                <depends>
-                                    <field id="use_proxy">1</field>
-                                </depends>
-                            </field>
-                            <field id="proxy_port" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1">
-                                <label>Proxy Port</label>
-                                <config_path>paypal/wpp/proxy_port</config_path>
+                        <field id="enable_paypal_payflow">
+                            <frontend_class>paypal-enabler paypal-ec-pe</frontend_class>
+                        </field>
+                        <group id="paypal_payflow_api_settings" translate="label">
+                            <label>Payflow Pro and Express Checkout</label>
+                            <field id="business_account" extends="payment_all_paypal/express_checkout/express_checkout_required/express_checkout_required_express_checkout/business_account" translate="label" sortOrder="10">
+                                <frontend_class>not-required</frontend_class>
+                                <label>Email Associated with PayPal Merchant Account (Optional)</label>
                                 <attribute type="shared">1</attribute>
-                                <depends>
-                                    <field id="use_proxy">1</field>
-                                </depends>
                             </field>
                         </group>
-                        <field id="enable_express_checkout" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1">
-                            <label>Enable this Solution</label>
-                            <config_path>payment/paypal_express/active</config_path>
-                            <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                            <attribute type="shared">1</attribute>
+                        <field id="enable_express_checkout" extends="payment_all_paypal/payflow_link/payflow_link_required/enable_express_checkout_basic" showInDefault="1" showInWebsite="1">
+                            <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Field\Hidden</frontend_model>
                             <requires>
-                                <group id="express_checkout_required_express_checkout"/>
+                                <field id="enable_paypal_payflow"/>
                             </requires>
-                            <frontend_class>paypal-enabler paypal-ec-enabler</frontend_class>
                         </field>
                     </group>
-                    <group id="settings_ec" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="20">
+                    <group id="settings_paypal_payflow" translate="label">
+                        <group id="settings_paypal_payflow_advanced" translate="label">
+                            <group id="paypal_payflow_frontend" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="100">
+                                <label>Frontend Experience Settings</label>
+                                <field id="logo" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo"/>
+                                <field id="paypal_pages" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages"/>
+                                <field id="page_style" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style"/>
+                                <field id="paypal_hdrimg" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg"/>
+                                <field id="paypal_hdrbackcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor"/>
+                                <field id="paypal_hdrbordercolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor"/>
+                                <field id="paypal_payflowcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor"/>
+                            </group>
+                        </group>
+                    </group>
+                    <group id="paypal_payflow_express_checkout" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
                         <label>Basic Settings - PayPal Express Checkout</label>
                         <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
-                        <field id="title" translate="label comment" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <field id="title" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                             <label>Title</label>
-                            <comment>It is recommended to set this value to "Magento_Paypal" per store views.</comment>
-                            <config_path>payment/paypal_express/title</config_path>
+                            <config_path>payment/payflow_express/title</config_path>
                             <attribute type="shared">1</attribute>
                         </field>
                         <field id="sort_order" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
                             <label>Sort Order</label>
-                            <config_path>payment/paypal_express/sort_order</config_path>
+                            <config_path>payment/payflow_express/sort_order</config_path>
                             <frontend_class>validate-number</frontend_class>
                             <attribute type="shared">1</attribute>
                         </field>
                         <field id="payment_action" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
                             <label>Payment Action</label>
-                            <config_path>payment/paypal_express/payment_action</config_path>
-                            <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions\Express</source_model>
+                            <config_path>payment/payflow_express/payment_action</config_path>
+                            <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="visible_on_cart" translate="label comment" type="select" sortOrder="35" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <field id="visible_on_cart" translate="label comment" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
                             <label>Shortcut on Shopping Cart</label>
-                            <config_path>payment/paypal_express/visible_on_cart</config_path>
                             <comment>Also affects mini-shopping cart.</comment>
+                            <config_path>payment/payflow_express/visible_on_cart</config_path>
                             <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="visible_on_product" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
+                        <field id="visible_on_product" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
                             <label>Shortcut on Product View</label>
-                            <config_path>payment/paypal_express/visible_on_product</config_path>
+                            <config_path>payment/payflow_express/visible_on_product</config_path>
                             <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                             <attribute type="shared">1</attribute>
                         </field>
-                        <field id="authorization_honor_period" translate="label comment" type="text" sortOrder="50" showInDefault="1" showInWebsite="1">
-                            <label>Authorization Honor Period (days)</label>
-                            <comment>Specifies what the Authorization Honor Period is on the merchant&#8217;s PayPal account. It must mirror the setting in PayPal.</comment>
-                            <config_path>payment/paypal_express/authorization_honor_period</config_path>
-                            <attribute type="shared">1</attribute>
-                            <depends>
-                                <field id="payment_action">Order</field>
-                            </depends>
-                        </field>
-                        <field id="order_valid_period" translate="label comment" type="text" sortOrder="60" showInDefault="1" showInWebsite="1">
-                            <label>Order Valid Period (days)</label>
-                            <comment>Specifies what the Order Valid Period is on the merchant&#x2019;s PayPal account. It must mirror the setting in PayPal.</comment>
-                            <config_path>payment/paypal_express/order_valid_period</config_path>
-                            <attribute type="shared">1</attribute>
-                            <depends>
-                                <field id="payment_action">Order</field>
-                            </depends>
-                        </field>
-                        <field id="child_authorization_number" translate="label comment" type="text" sortOrder="70" showInDefault="1" showInWebsite="1">
-                            <label>Number of Child Authorizations</label>
-                            <comment>The default number of child authorizations in your PayPal account is 1. To do multiple authorizations please contact PayPal to request an increase.</comment>
-                            <config_path>payment/paypal_express/child_authorization_number</config_path>
-                            <attribute type="shared">1</attribute>
-                            <depends>
-                                <field id="payment_action">Order</field>
-                            </depends>
-                        </field>
-                        <group id="settings_ec_advanced" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="80">
+                        <group id="paypal_payflow_express_checkout_advanced" translate="label" showInDefault="1" showInWebsite="1" sortOrder="60">
                             <label>Advanced Settings</label>
                             <fieldset_css>config-advanced</fieldset_css>
                             <field id="allowspecific" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
                                 <label>Payment Applicable From</label>
-                                <config_path>payment/paypal_express/allowspecific</config_path>
+                                <config_path>payment/payflow_express/allowspecific</config_path>
                                 <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                             <field id="specificcountry" translate="label" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="1">
                                 <label>Countries Payment Applicable From</label>
-                                <config_path>payment/paypal_express/specificcountry</config_path>
+                                <config_path>payment/payflow_express/specificcountry</config_path>
                                 <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
-                                <attribute type="shared">1</attribute>
                                 <depends>
                                     <field id="allowspecific">1</field>
                                 </depends>
+                                <attribute type="shared">1</attribute>
                             </field>
                             <field id="debug" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="1">
                                 <label>Debug Mode</label>
-                                <config_path>payment/paypal_express/debug</config_path>
+                                <config_path>payment/payflow_express/debug</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                             <field id="verify_peer" translate="label" type="select" sortOrder="35" showInDefault="1" showInWebsite="1">
                                 <label>Enable SSL verification</label>
-                                <config_path>payment/paypal_express/verify_peer</config_path>
+                                <config_path>payment/payflow_express/verify_peer</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
                             </field>
                             <field id="line_items_enabled" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
                                 <label>Transfer Cart Line Items</label>
-                                <config_path>payment/paypal_express/line_items_enabled</config_path>
-                                <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="transfer_shipping_options" translate="label tooltip comment" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
-                                <label>Transfer Shipping Options</label>
-                                <config_path>payment/paypal_express/transfer_shipping_options</config_path>
-                                <tooltip>If this option is enabled, customer can change shipping address and shipping method on PayPal website. In live mode works via HTTPS protocol only.</tooltip>
-                                <comment>Notice that PayPal can handle up to 10 shipping options. That is why Magento will transfer only first 10 cheapest shipping options if there are more than 10 available.</comment>
+                                <config_path>payment/payflow_express/line_items_enabled</config_path>
                                 <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                                 <attribute type="shared">1</attribute>
-                                <depends>
-                                    <field id="line_items_enabled">1</field>
-                                </depends>
-                            </field>
-                            <field id="button_flavor" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
-                                <label>Shortcut Buttons Flavor</label>
-                                <config_path>paypal/wpp/button_flavor</config_path>
-                                <source_model>Magento\Paypal\Model\Config::getExpressCheckoutButtonFlavors</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="solution_type" translate="label comment" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                <label>Enable PayPal Guest Checkout</label>
-                                <comment>Ability for buyer to purchase without PayPal account.</comment>
-                                <config_path>payment/paypal_express/solution_type</config_path>
-                                <source_model>Magento\Paypal\Model\Config::getExpressCheckoutSolutionTypes</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="require_billing_address" translate="label comment" type="select" sortOrder="80" showInDefault="1" showInWebsite="1">
-                                <label>Require Customer's Billing Address</label>
-                                <comment>This feature needs be enabled first for the merchant account through PayPal technical support.</comment>
-                                <config_path>payment/paypal_express/require_billing_address</config_path>
-                                <source_model>Magento\Paypal\Model\System\Config\Source\RequireBillingAddress</source_model>
-                                <attribute type="shared">1</attribute>
-                            </field>
-                            <field id="allow_ba_signup" translate="label comment tooltip" type="select" sortOrder="90" showInDefault="1" showInWebsite="1">
-                                <label>Billing Agreement Signup</label>
-                                <comment>Whether to create a billing agreement, if there are no active billing agreements available.</comment>
-                                <tooltip>
-                                    <![CDATA[Merchants need to apply to PayPal for enabling billing agreements feature. Do not enable this option until PayPal confirms that billing agreements are enabled for your merchant account.]]>
-                                </tooltip>
-                                <config_path>payment/paypal_express/allow_ba_signup</config_path>
-                                <source_model>Magento\Paypal\Model\Config::getExpressCheckoutBASignupOptions</source_model>
-                                <attribute type="shared">1</attribute>
                             </field>
-                            <group id="express_checkout_billing_agreement" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="100">
+                        </group>
+                    </group>
+                </group>
+            </group>
+            <group id="paypal_alternative_payment_methods">
+                <group id="express_checkout_us">
+                    <attribute type="activity_path">payment/payflow_express/active</attribute>
+                </group>
+            </group>
+        </section>
+        <section id="payment_gb" extends="payment_usgb">
+            <group id="paypal_group_all_in_one">
+                <group id="wps_usuk" translate="comment" sortOrder="10">
+                    <fieldset_css>pp-general-uk</fieldset_css>
+                    <more_url>https://www.paypal-business.co.uk/accept-online-payments-with-paypal/index.htm</more_url>
+                    <demo_link>http://www.youtube.com/watch?v=mdPjvziH_rk&amp;list=PLF18B1094ABCD7CE8&amp;index=6&amp;feature=plpp_video</demo_link>
+                    <comment>Accept credit cards, debit cards and PayPal payments securely.</comment>
+                </group>
+                <group id="wpp_usuk" translate="comment" sortOrder="20">
+                    <fieldset_css>pp-general-uk</fieldset_css>
+                    <more_url>https://www.paypal-business.co.uk/process-online-payments-with-paypal/index.htm</more_url>
+                    <demo_link>http://www.youtube.com/watch?v=LBe-TW87eGI&amp;list=PLF18B1094ABCD7CE8&amp;index=1&amp;feature=plpp_video</demo_link>
+                    <comment>Accept payments with a completely customizable checkout page.</comment>
+                </group>
+                <group id="payments_pro_hosted_solution_with_express_checkout" translate="label comment" extends="payment_all_paypal/payments_pro_hosted_solution" sortOrder="30">
+                    <label>Website Payments Pro Hosted Solution (Includes Express Checkout)</label>
+                    <fieldset_css>pp-general-uk</fieldset_css>
+                    <more_url>https://cms.paypal.com/cms_content/GB/en_GB/files/developer/HostedSolution.pdf</more_url>
+                    <attribute type="paypal_ec_separate">0</attribute>
+                    <group id="pphs_required_settings">
+                        <group id="pphs_required_settings_pphs" translate="label">
+                            <label>Website Payments Pro Hosted Solution and Express Checkout</label>
+                        </group>
+                        <field id="pphs_enable">
+                            <frontend_class>paypal-enabler</frontend_class>
+                        </field>
+                    </group>
+                    <group id="pphs_settings" translate="label">
+                        <label>Basic Settings - PayPal Website Payments Pro Hosted Solution</label>
+                        <group id="pphs_settings_advanced">
+                            <group id="pphs_billing_agreement" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="40">
                                 <label>PayPal Billing Agreement Settings</label>
-                                <field id="active" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1">
-                                    <label>Enabled</label>
-                                    <comment>
-                                        <![CDATA[Will appear as a payment option only for customers who have at least one active billing agreement.]]>
-                                    </comment>
-                                    <config_path>payment/paypal_billing_agreement/active</config_path>
-                                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="title" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>Title</label>
-                                    <config_path>payment/paypal_billing_agreement/title</config_path>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="sort_order" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>Sort Order</label>
-                                    <config_path>payment/paypal_billing_agreement/sort_order</config_path>
-                                    <frontend_class>validate-number</frontend_class>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="payment_action" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                    <label>Payment Action</label>
-                                    <config_path>payment/paypal_billing_agreement/payment_action</config_path>
-                                    <source_model>Magento\Paypal\Model\System\Config\Source\PaymentActions</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="allowspecific" translate="label" type="select" sortOrder="50" showInDefault="1" showInWebsite="1">
-                                    <label>Payment Applicable From</label>
-                                    <config_path>payment/paypal_billing_agreement/allowspecific</config_path>
-                                    <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="specificcountry" translate="label" type="multiselect" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                    <label>Countries Payment Applicable From</label>
-                                    <config_path>payment/paypal_billing_agreement/specificcountry</config_path>
-                                    <source_model>Magento\Paypal\Model\System\Config\Source\BuyerCountry</source_model>
-                                    <attribute type="shared">1</attribute>
-                                    <depends>
-                                        <field id="allowspecific">1</field>
-                                    </depends>
-                                </field>
-                                <field id="debug" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                    <label>Debug Mode</label>
-                                    <config_path>payment/paypal_billing_agreement/debug</config_path>
-                                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="verify_peer" translate="label" type="select" sortOrder="75" showInDefault="1" showInWebsite="1">
-                                    <label>Enable SSL verification</label>
-                                    <config_path>payment/paypal_billing_agreement/verify_peer</config_path>
-                                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="line_items_enabled" translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1">
-                                    <label>Transfer Cart Line Items</label>
-                                    <config_path>payment/paypal_billing_agreement/line_items_enabled</config_path>
-                                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="allow_billing_agreement_wizard" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1">
-                                    <label>Allow in Billing Agreement Wizard</label>
-                                    <config_path>payment/paypal_billing_agreement/allow_billing_agreement_wizard</config_path>
-                                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                            </group>
-                            <group id="express_checkout_settlement_report" type="text" translate="label" showInDefault="1" showInWebsite="1" sortOrder="110">
-                                <label>Settlement Report Settings</label>
-                                <field id="heading_sftp" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1">
-                                    <label>SFTP Credentials</label>
-                                    <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="settlement_reports_ftp_login" translate="label" type="obscure" sortOrder="20" showInDefault="1" showInWebsite="1">
-                                    <label>Login</label>
-                                    <config_path>paypal/fetch_reports/ftp_login</config_path>
-                                    <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="settlement_reports_ftp_password" translate="label" type="obscure" sortOrder="30" showInDefault="1" showInWebsite="1">
-                                    <label>Password</label>
-                                    <config_path>paypal/fetch_reports/ftp_password</config_path>
-                                    <backend_model>Magento\Backend\Model\Config\Backend\Encrypted</backend_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="settlement_reports_ftp_sandbox" translate="label" type="select" sortOrder="40" showInDefault="1" showInWebsite="1">
-                                    <label>Sandbox Mode</label>
-                                    <config_path>paypal/fetch_reports/ftp_sandbox</config_path>
-                                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="settlement_reports_ftp_ip" translate="label comment tooltip" type="text" sortOrder="50" showInDefault="1" showInWebsite="1">
-                                    <label>Custom Endpoint Hostname or IP-Address</label>
-                                    <comment>By default it is "reports.paypal.com".</comment>
-                                    <tooltip>Use colon to specify port. For example: "test.example.com:5224".</tooltip>
-                                    <config_path>paypal/fetch_reports/ftp_ip</config_path>
-                                    <attribute type="shared">1</attribute>
-                                    <depends>
-                                        <field id="settlement_reports_ftp_sandbox">0</field>
-                                    </depends>
-                                </field>
-                                <field id="settlement_reports_ftp_path" translate="label comeent" type="text" sortOrder="60" showInDefault="1" showInWebsite="1">
-                                    <label>Custom Path</label>
-                                    <comment>By default it is "/ppreports/outgoing".</comment>
-                                    <config_path>paypal/fetch_reports/ftp_path</config_path>
-                                    <attribute type="shared">1</attribute>
-                                    <depends>
-                                        <field id="settlement_reports_ftp_sandbox">0</field>
-                                    </depends>
-                                </field>
-                                <field id="heading_schedule" translate="label" sortOrder="70" showInDefault="1" showInWebsite="1">
-                                    <label>Scheduled Fetching</label>
-                                    <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="settlement_reports_active" translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1">
-                                    <label>Enable Automatic Fetching</label>
-                                    <config_path>paypal/fetch_reports/active</config_path>
-                                    <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="settlement_reports_schedule" translate="label comment" type="select" sortOrder="90" showInDefault="1">
-                                    <label>Schedule</label>
-                                    <comment>PayPal retains reports for 45 days.</comment>
-                                    <config_path>paypal/fetch_reports/schedule</config_path>
-                                    <source_model>Magento\Paypal\Model\System\Config\Source\FetchingSchedule</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="settlement_reports_time" translate="label" type="time" sortOrder="100" showInDefault="1">
-                                    <label>Time of Day</label>
-                                    <config_path>paypal/fetch_reports/time</config_path>
-                                    <attribute type="shared">1</attribute>
-                                </field>
+                                <field id="active" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/active" />
+                                <field id="title" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/title" />
+                                <field id="sort_order" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/sort_order" />
+                                <field id="payment_action" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/payment_action" />
+                                <field id="allowspecific" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/allowspecific" />
+                                <field id="specificcountry" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/specificcountry" />
+                                <field id="debug" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/debug" />
+                                <field id="verify_peer" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/verify_peer" />
+                                <field id="line_items_enabled" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/line_items_enabled" />
+                                <field id="allow_billing_agreement_wizard" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_billing_agreement/allow_billing_agreement_wizard" />
                             </group>
-                            <group id="express_checkout_frontend" type="text" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="120">
+                            <group id="pphs_frontend" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="60">
                                 <label>Frontend Experience Settings</label>
-                                <field id="logo" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>PayPal Product Logo</label>
-                                    <comment>Displays on catalog pages and homepage.</comment>
-                                    <config_path>paypal/style/logo</config_path>
-                                    <source_model>Magento\Paypal\Model\System\Config\Source\Logo</source_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="paypal_pages" translate="label" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>PayPal Merchant Pages Style</label>
-                                    <frontend_model>Magento\Backend\Block\System\Config\Form\Field\Heading</frontend_model>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="page_style" translate="label tooltip" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>Page Style</label>
-                                    <config_path>paypal/style/page_style</config_path>
-                                    <tooltip>
-                                        <![CDATA[Allowable values: "paypal", "primary" (default), your_custom_value (a custom payment page style from your merchant account profile).]]>
-                                    </tooltip>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="paypal_hdrimg" translate="label tooltip" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>Header Image URL</label>
-                                    <config_path>paypal/style/paypal_hdrimg</config_path>
-                                    <tooltip>
-                                        <![CDATA[The image at the top left of the checkout page. Max size is 750x90-pixel. <strong style="color:red">https</strong> is highly encouraged.]]>
-                                    </tooltip>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="paypal_hdrbackcolor" translate="label tooltip" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>Header Background Color</label>
-                                    <config_path>paypal/style/paypal_hdrbackcolor</config_path>
-                                    <tooltip>
-                                        <![CDATA[The background color for the header of the checkout page. Case-insensitive six-character HTML hexadecimal color code in ASCII.]]>
-                                    </tooltip>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="paypal_hdrbordercolor" translate="label tooltip" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>Header Border Color</label>
-                                    <config_path>paypal/style/paypal_hdrbordercolor</config_path>
-                                    <tooltip>2-pixel perimeter around the header space.</tooltip>
-                                    <attribute type="shared">1</attribute>
-                                </field>
-                                <field id="paypal_payflowcolor" translate="label tooltip" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="1">
-                                    <label>Page Background Color</label>
-                                    <config_path>paypal/style/paypal_payflowcolor</config_path>
-                                    <tooltip>
-                                        <![CDATA[The background color for the checkout page around the header and payment form.]]>
-                                    </tooltip>
-                                    <attribute type="shared">1</attribute>
-                                </field>
+                                <field id="logo" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/logo" />
+                                <field id="paypal_pages" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_pages" />
+                                <field id="page_style" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/page_style" />
+                                <field id="paypal_hdrimg" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrimg" />
+                                <field id="paypal_hdrbackcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbackcolor" />
+                                <field id="paypal_hdrbordercolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_hdrbordercolor" />
+                                <field id="paypal_payflowcolor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/express_checkout_frontend/paypal_payflowcolor" />
                             </group>
                         </group>
                     </group>
+                    <group id="pphs_settings_express_checkout" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="30">
+                        <label>Basic Settings - PayPal Express Checkout</label>
+                        <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Expanded</frontend_model>
+                        <field id="title" extends="payment_all_paypal/express_checkout/settings_ec/title" />
+                        <field id="sort_order" extends="payment_all_paypal/express_checkout/settings_ec/sort_order" />
+                        <field id="payment_action" extends="payment_all_paypal/express_checkout/settings_ec/payment_action" />
+                        <field id="visible_on_cart" extends="payment_all_paypal/express_checkout/settings_ec/visible_on_cart" />
+                        <field id="visible_on_product" extends="payment_all_paypal/express_checkout/settings_ec/visible_on_product" />
+                        <field id="authorization_honor_period" extends="payment_all_paypal/express_checkout/settings_ec/authorization_honor_period" />
+                        <field id="order_valid_period" extends="payment_all_paypal/express_checkout/settings_ec/order_valid_period" />
+                        <field id="child_authorization_number" extends="payment_all_paypal/express_checkout/settings_ec/child_authorization_number" />
+                        <group id="pphs_settings_express_checkout_advanced" translate="label" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="80">
+                            <label>Advanced Settings</label>
+                            <fieldset_css>config-advanced</fieldset_css>
+                            <field id="allowspecific" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/allowspecific" />
+                            <field id="specificcountry" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/specificcountry" />
+                            <field id="debug" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/debug" />
+                            <field id="verify_peer" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/verify_peer" />
+                            <field id="line_items_enabled" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/line_items_enabled" />
+                            <field id="transfer_shipping_options" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/transfer_shipping_options" />
+                            <field id="button_flavor" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/button_flavor" />
+                            <field id="solution_type" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/solution_type" />
+                            <field id="require_billing_address" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/require_billing_address" />
+                            <field id="allow_ba_signup" extends="payment_all_paypal/express_checkout/settings_ec/settings_ec_advanced/allow_ba_signup" />
+                        </group>
+                    </group>
+                </group>
+            </group>
+        </section>
+        <section id="payment_de" extends="payment" showInDefault="0" showInWebsite="0" showInStore="0">
+            <group id="paypal_payment_solutions" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="10">
+                <label>PayPal Payment Solutions</label>
+                <attribute type="expanded">1</attribute>
+                <fieldset_css>complex</fieldset_css>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
+                <comment>Add another payment method to your existing solution or as a stand-alone option.</comment>
+                <help_url>https://www.paypal-marketing.com/emarketing/partner/na/merchantlineup/home.page#mainTab=checkoutlineup&amp;subTab=newlineup</help_url>
+                <group id="express_checkout_de" extends="payment_all_paypal/express_checkout"/>
+            </group>
+        </section>
+        <section id="payment_other" extends="payment" showInDefault="0" showInWebsite="0" showInStore="0">
+            <group id="paypal_payment_solutions" translate="label comment" showInDefault="1" showInWebsite="1" showInStore="1" sortOrder="10">
+                <label>PayPal Payment Solutions</label>
+                <attribute type="expanded">1</attribute>
+                <fieldset_css>complex</fieldset_css>
+                <frontend_model>Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group</frontend_model>
+                <comment>Add another payment method to your existing solution or as a stand-alone option.</comment>
+                <help_url>https://www.paypal-marketing.com/emarketing/partner/na/merchantlineup/home.page#mainTab=checkoutlineup&amp;subTab=newlineup</help_url>
+                <group id="wps_other" extends="payment_all_paypal/wps"/>
+                <group id="express_checkout_other" extends="payment_all_paypal/express_checkout"/>
+            </group>
+        </section>
+        <section id="payment_ca" extends="payment_other">
+            <group id="paypal_payment_solutions">
+                <group id="wps_other" sortOrder="20"/>
+                <group id="express_checkout_other" sortOrder="50">
+                    <attribute type="activity_path">payment/payflow_express/active</attribute>
+                </group>
+                <group id="wpp_ca" extends="payment_all_paypal/wpp" sortOrder="10"/>
+                <group id="paypal_payflowpro_ca" extends="payment_all_paypal/paypal_payflowpro" sortOrder="30"/>
+                <group id="payflow_link_ca" extends="payment_all_paypal/payflow_link" sortOrder="40"/>
+            </group>
+        </section>
+        <section id="payment_au" extends="payment_other">
+            <group id="paypal_payment_solutions">
+                <group id="wps_other" sortOrder="10"/>
+                <group id="express_checkout_other" sortOrder="40"/>
+                <group id="paypal_payflowpro_au" extends="payment_all_paypal/paypal_payflowpro" sortOrder="20"/>
+                <group id="payments_pro_hosted_solution_au" extends="payment_all_paypal/payments_pro_hosted_solution" sortOrder="30"/>
+            </group>
+        </section>
+        <section id="payment_jp" extends="payment_other">
+            <group id="paypal_payment_solutions">
+                <group id="wps_other" sortOrder="12"/>
+                <group id="express_checkout_other" sortOrder="30"/>
+                <group id="payments_pro_hosted_solution_jp" extends="payment_all_paypal/payments_pro_hosted_solution" sortOrder="10">
+                    <label>Website Payments Plus</label>
+                </group>
+            </group>
+        </section>
+        <section id="payment_fr" extends="payment_other">
+            <group id="paypal_payment_solutions">
+                <group id="wps_other" sortOrder="12"/>
+                <group id="express_checkout_other" sortOrder="30"/>
+                <group id="payments_pro_hosted_solution_fr" extends="payment_all_paypal/payments_pro_hosted_solution" sortOrder="10">
+                    <label>Integral Evolution</label>
+                </group>
+            </group>
+        </section>
+        <section id="payment_it" extends="payment_other">
+            <group id="paypal_payment_solutions">
+                <group id="wps_other" sortOrder="12"/>
+                <group id="express_checkout_other" sortOrder="30"/>
+                <group id="payments_pro_hosted_solution_it" extends="payment_all_paypal/payments_pro_hosted_solution" sortOrder="10">
+                    <label>Pro</label>
+                </group>
+            </group>
+        </section>
+        <section id="payment_es" extends="payment_other">
+            <group id="paypal_payment_solutions">
+                <group id="wps_other" sortOrder="12"/>
+                <group id="express_checkout_other" sortOrder="30"/>
+                <group id="payments_pro_hosted_solution_es" extends="payment_all_paypal/payments_pro_hosted_solution" sortOrder="10">
+                    <label>Pasarela integral</label>
                 </group>
             </group>
         </section>
+        <section id="payment_hk" extends="payment_other">
+            <group id="paypal_payment_solutions">
+                <group id="wps_other" sortOrder="12"/>
+                <group id="express_checkout_other" sortOrder="30"/>
+                <group id="payments_pro_hosted_solution_hk" extends="payment_all_paypal/payments_pro_hosted_solution" sortOrder="10"/>
+            </group>
+        </section>
+        <section id="payment_nz" extends="payment_other">
+            <group id="paypal_payment_solutions">
+                <group id="wps_other" sortOrder="12"/>
+                <group id="express_checkout_other" sortOrder="30"/>
+                <group id="paypal_payflowpro_nz" extends="payment_all_paypal/paypal_payflowpro" sortOrder="10"/>
+            </group>
+        </section>
     </system>
 </config>
diff --git a/app/code/Magento/Paypal/etc/config.xml b/app/code/Magento/Paypal/etc/config.xml
index 95c0ec9730e0d660fe049cc8faa82fd8725ccc0b..6202193ac0097dea57c6ecc04a2a83ae2aaa5622 100644
--- a/app/code/Magento/Paypal/etc/config.xml
+++ b/app/code/Magento/Paypal/etc/config.xml
@@ -89,15 +89,6 @@
                 <verify_peer>1</verify_peer>
                 <model>Magento\Paypal\Model\PayflowExpress</model>
             </payflow_express>
-            <payflow_direct>
-                <title>PayPal Direct Payment Payflow Edition</title>
-                <payment_action>Authorization</payment_action>
-                <cctypes>VI,MC,AE</cctypes>
-                <useccv>1</useccv>
-                <group>paypal</group>
-                <verify_peer>1</verify_peer>
-                <model>Magento\Paypal\Model\PayflowDirect</model>
-            </payflow_direct>
             <payflowpro>
                 <model>Magento\Paypal\Model\Payflowpro</model>
                 <title>Payflow Pro</title>
diff --git a/app/code/Magento/Paypal/etc/di.xml b/app/code/Magento/Paypal/etc/di.xml
index 902cae04b2a1a94b1c9151b1812d978087a4df73..e9488eaa55119f83a8b428ff103b753168af0694 100644
--- a/app/code/Magento/Paypal/etc/di.xml
+++ b/app/code/Magento/Paypal/etc/di.xml
@@ -41,4 +41,14 @@
             <argument name="payflowModelFactory" xsi:type="object">Magento\Paypal\Model\PayflowadvancedFactory</argument>
         </arguments>
     </type>
+    <virtualType name="Magento\Paypal\Model\Payflow\ProFactory" type="Magento\Paypal\Model\ProFactory">
+        <arguments>
+            <argument name="instanceName" xsi:type="string">Magento\Paypal\Model\Payflow\Pro</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\Paypal\Model\PayflowExpress">
+        <arguments>
+            <argument name="proFactory" xsi:type="object">Magento\Paypal\Model\Payflow\ProFactory</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Paypal/etc/payment.xml b/app/code/Magento/Paypal/etc/payment.xml
index 8fc4bafa670083427521bc76f0383b4816dadad5..ca6074525cba356b17b5c293c9af777626d4244b 100644
--- a/app/code/Magento/Paypal/etc/payment.xml
+++ b/app/code/Magento/Paypal/etc/payment.xml
@@ -52,10 +52,6 @@
             <allow_multiple_address>1</allow_multiple_address>
             <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure>
         </method>
-        <method name="payflow_direct">
-            <allow_multiple_address>1</allow_multiple_address>
-            <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure>
-        </method>
         <method name="payflow_express">
             <allow_multiple_address>1</allow_multiple_address>
             <allow_multiple_with_3dsecure>1</allow_multiple_with_3dsecure>
diff --git a/app/code/Magento/Paypal/view/adminhtml/templates/system/config/fieldset/store.phtml b/app/code/Magento/Paypal/view/adminhtml/templates/system/config/fieldset/store.phtml
deleted file mode 100644
index 6f45512aeaaacfc0840374665bb6be50873de1dc..0000000000000000000000000000000000000000
--- a/app/code/Magento/Paypal/view/adminhtml/templates/system/config/fieldset/store.phtml
+++ /dev/null
@@ -1,99 +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
-/**
- * @see \Magento\Paypal\Block\System\Config\Fieldset\Store
- */
-?>
-<script type="text/javascript">
-
-Event.observe(window, 'load', function () {
-    var pConfigDisabler = new PaypalConfigDisabler;
-    var disabledMethods = <?php echo $this->helper('Magento\Core\Helper\Data')->jsonEncode($this->getPaypalDisabledMethods()); ?>;
-    pConfigDisabler.disableMethods(disabledMethods);
-});
-
-PaypalConfigDisabler = Class.create();
-PaypalConfigDisabler.prototype = {
-    initialize: function () {
-        this.methods = $H({
-            express: $H({fieldset: 'express'}),
-            wps: $H({fieldset: 'wps'}),
-            wpp: $H({fieldset: 'wpp'}),
-            wpppe: $H({fieldset: 'wpp_pe'}),
-            expresspe: $H({fieldset: 'express_pe'}),
-            payflowpro: $H({fieldset: 'payflowpro'}),
-            wpppl: $H({fieldset: 'payflow_link'}),
-            hosted_pro: $H({fieldset: 'hosted_pro'})
-        });
-    },
-
-    getMethods: function ()
-    {
-        return this.methods;
-    },
-
-    getMethod: function (method)
-    {
-        return this.methods.get(method);
-    },
-
-    getMethodFieldset: function (method)
-    {
-        var fieldsetId = 'paypal_' + this.getMethod(method).get('fieldset');
-        return $(fieldsetId);
-    },
-
-    disableMethod: function (method)
-    {
-        this.hideFieldset(this.getMethodFieldset(method));
-    },
-
-    disableMethods: function (methods)
-    {
-        for(var methodId in methods) {
-            this.disableMethod(methodId);
-        }
-    },
-
-    hideFieldset: function (fieldset)
-    {
-        this.disableValueElements(fieldset);
-        fieldset.hide();
-        var heading = fieldset.previous('div');
-        var headingLink = heading.down('a');
-        heading.addClassName('disabled');
-        headingLink.onclick = "return false;";
-        headingLink.href = "javascript:void(0)";
-    },
-
-    disableValueElements: function (container)
-    {
-        $(container).select('select', 'input', 'textarea', 'button').each(function (elem) {
-            elem.addClassName('disabled');
-        });
-    }
-}
-</script>
diff --git a/app/code/Magento/ProductAlert/Block/Email/AbstractEmail.php b/app/code/Magento/ProductAlert/Block/Email/AbstractEmail.php
index e90c97ed33bdc8ef9eff1083e96e874f7dde6fa0..a72226942f212ef2d8f9f85d896485cf55786db4 100644
--- a/app/code/Magento/ProductAlert/Block/Email/AbstractEmail.php
+++ b/app/code/Magento/ProductAlert/Block/Email/AbstractEmail.php
@@ -44,6 +44,36 @@ abstract class AbstractEmail extends \Magento\Framework\View\Element\Template
      */
     protected $_store;
 
+    /**
+     * @var \Magento\Framework\Filter\Input\MaliciousCode
+     */
+    protected $_maliciousCode;
+
+    /**
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\Filter\Input\MaliciousCode $maliciousCode
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\Filter\Input\MaliciousCode $maliciousCode,
+        array $data = array()
+    ) {
+        $this->_maliciousCode = $maliciousCode;
+        parent::__construct($context, $data);
+    }
+
+    /**
+    * Filter malicious code before insert content to email
+    *
+    * @param  string|array $content
+    * @return string|array
+    */
+    public function getFilteredContent($content)
+    {
+        return $this->_maliciousCode->filter($content);
+    }
+
     /**
      * Set Store scope
      *
diff --git a/app/code/Magento/ProductAlert/Block/Email/Stock.php b/app/code/Magento/ProductAlert/Block/Email/Stock.php
index 6af99158c287f69e8df86d3bca8ee2cbaa19bcb6..f7bd8da4ba51f1b88820eba703e2020aa8023706 100644
--- a/app/code/Magento/ProductAlert/Block/Email/Stock.php
+++ b/app/code/Magento/ProductAlert/Block/Email/Stock.php
@@ -43,15 +43,17 @@ class Stock extends \Magento\ProductAlert\Block\Email\AbstractEmail
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
      * @param \Magento\Catalog\Helper\Image $imageHelper
+     * @param \Magento\Framework\Filter\Input\MaliciousCode $maliciousCode
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\Filter\Input\MaliciousCode $maliciousCode,
         \Magento\Catalog\Helper\Image $imageHelper,
         array $data = array()
     ) {
         $this->_imageHelper = $imageHelper;
-        parent::__construct($context, $data);
+        parent::__construct($context, $maliciousCode, $data);
     }
 
     /**
diff --git a/app/code/Magento/ProductAlert/view/frontend/templates/email/price.phtml b/app/code/Magento/ProductAlert/view/frontend/templates/email/price.phtml
index 048411bd3e0e18188f659d0b4325aa50ce0862ce..aa7fac0b397c45ce2dc2b6f6d6d0ffb376dcd46e 100644
--- a/app/code/Magento/ProductAlert/view/frontend/templates/email/price.phtml
+++ b/app/code/Magento/ProductAlert/view/frontend/templates/email/price.phtml
@@ -41,7 +41,7 @@
                     <a href="<?php echo $_product->getProductUrl() ?>"><?php echo $this->escapeHtml($_product->getName()) ?></a>
                 </strong>
             </p>
-            <?php if ($shortDescription = $this->escapeHtml($_product->getShortDescription())): ?>
+            <?php if ($shortDescription = $this->getFilteredContent($_product->getShortDescription())): ?>
                 <p><small><?php echo $shortDescription ?></small></p>
             <?php endif; ?>
             <p><?php echo $this->getProductPriceHtml(
diff --git a/app/code/Magento/ProductAlert/view/frontend/templates/email/stock.phtml b/app/code/Magento/ProductAlert/view/frontend/templates/email/stock.phtml
index ae83ff32a66587bb15f4baee437d118818985532..16c740ec320b33c54020f4730009abb6ff93dd40 100644
--- a/app/code/Magento/ProductAlert/view/frontend/templates/email/stock.phtml
+++ b/app/code/Magento/ProductAlert/view/frontend/templates/email/stock.phtml
@@ -40,7 +40,7 @@
                     <a href="<?php echo $_product->getProductUrl() ?>"><?php echo $this->escapeHtml($_product->getName()) ?></a>
                 </strong>
             </p>
-            <?php if ($shortDescription = $this->escapeHtml($_product->getShortDescription())): ?>
+            <?php if ($shortDescription = $this->getFilteredContent($_product->getShortDescription())): ?>
             <p><small><?php echo $shortDescription ?></small></p>
             <?php endif; ?>
             <p><?php echo $this->getProductPriceHtml(
diff --git a/app/code/Magento/RecurringPayment/sql/recurringpayment_setup/install-1.0.0.0.php b/app/code/Magento/RecurringPayment/sql/recurringpayment_setup/install-1.0.0.0.php
index 83926d89129658c779b4a11296dbd3c6657aa69c..b89f2cae73a38c31ec99399f8705dd4666a02f02 100644
--- a/app/code/Magento/RecurringPayment/sql/recurringpayment_setup/install-1.0.0.0.php
+++ b/app/code/Magento/RecurringPayment/sql/recurringpayment_setup/install-1.0.0.0.php
@@ -314,3 +314,4 @@ $table = $this->getConnection()->newTable(
 $this->getConnection()->createTable($table);
 
 $this->installEntities();
+$this->endSetup();
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product.php b/app/code/Magento/Review/Controller/Adminhtml/Product.php
index 6bf8b0735e50885d287d0a278b7d04ce13331482..e2877ab095828df0a98f81ce4c02364b30af10ec 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product.php
@@ -42,13 +42,35 @@ class Product extends \Magento\Backend\App\Action
      */
     protected $_coreRegistry = null;
 
+    /**
+     * Review model factory
+     *
+     * @var \Magento\Review\Model\ReviewFactory
+     */
+    protected $_reviewFactory;
+
+    /**
+     * Rating model factory
+     *
+     * @var \Magento\Review\Model\RatingFactory
+     */
+    protected $_ratingFactory;
+
     /**
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Review\Model\ReviewFactory $reviewFactory
+     * @param \Magento\Review\Model\RatingFactory $ratingFactory
      */
-    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry,
+        \Magento\Review\Model\ReviewFactory $reviewFactory,
+        \Magento\Review\Model\RatingFactory $ratingFactory
+    ) {
         $this->_coreRegistry = $coreRegistry;
+        $this->_reviewFactory = $reviewFactory;
+        $this->_ratingFactory = $ratingFactory;
         parent::__construct($context);
     }
 
@@ -138,7 +160,7 @@ class Product extends \Magento\Backend\App\Action
     public function saveAction()
     {
         if (($data = $this->getRequest()->getPost()) && ($reviewId = $this->getRequest()->getParam('id'))) {
-            $review = $this->_objectManager->create('Magento\Review\Model\Review')->load($reviewId);
+            $review = $this->_reviewFactory->create()->load($reviewId);
             if (!$review->getId()) {
                 $this->messageManager->addError(__('The review was removed by another user or does not exist.'));
             } else {
@@ -153,8 +175,7 @@ class Product extends \Magento\Backend\App\Action
                     )->addOptionInfo()->load()->addRatingOptions();
                     foreach ($arrRatingId as $ratingId => $optionId) {
                         if ($vote = $votes->getItemByColumnValue('rating_id', $ratingId)) {
-                            $this->_objectManager->create(
-                                'Magento\Review\Model\Rating'
+                            $this->_ratingFactory->create(
                             )->setVoteId(
                                 $vote->getId()
                             )->setReviewId(
@@ -163,8 +184,7 @@ class Product extends \Magento\Backend\App\Action
                                 $optionId
                             );
                         } else {
-                            $this->_objectManager->create(
-                                'Magento\Review\Model\Rating'
+                            $this->_ratingFactory->create(
                             )->setRatingId(
                                 $ratingId
                             )->setReviewId(
@@ -203,7 +223,7 @@ class Product extends \Magento\Backend\App\Action
     {
         $reviewId = $this->getRequest()->getParam('id', false);
         try {
-            $this->_objectManager->create('Magento\Review\Model\Review')->setId($reviewId)->aggregate()->delete();
+            $this->_reviewFactory->create()->setId($reviewId)->aggregate()->delete();
 
             $this->messageManager->addSuccess(__('The review has been deleted.'));
             if ($this->getRequest()->getParam('ret') == 'pending') {
@@ -233,7 +253,7 @@ class Product extends \Magento\Backend\App\Action
         } else {
             try {
                 foreach ($reviewsIds as $reviewId) {
-                    $model = $this->_objectManager->create('Magento\Review\Model\Review')->load($reviewId);
+                    $model = $this->_reviewFactory->create()->load($reviewId);
                     $model->delete();
                 }
                 $this->messageManager->addSuccess(
@@ -261,7 +281,7 @@ class Product extends \Magento\Backend\App\Action
             try {
                 $status = $this->getRequest()->getParam('status');
                 foreach ($reviewsIds as $reviewId) {
-                    $model = $this->_objectManager->create('Magento\Review\Model\Review')->load($reviewId);
+                    $model = $this->_reviewFactory->create()->load($reviewId);
                     $model->setStatusId($status)->save()->aggregate();
                 }
                 $this->messageManager->addSuccess(
@@ -293,7 +313,7 @@ class Product extends \Magento\Backend\App\Action
             try {
                 $stores = $this->getRequest()->getParam('stores');
                 foreach ($reviewsIds as $reviewId) {
-                    $model = $this->_objectManager->create('Magento\Review\Model\Review')->load($reviewId);
+                    $model = $this->_reviewFactory->create()->load($reviewId);
                     $model->setSelectStores($stores);
                     $model->save();
                 }
@@ -361,30 +381,29 @@ class Product extends \Magento\Backend\App\Action
         $productId = $this->getRequest()->getParam('product_id', false);
 
         if ($data = $this->getRequest()->getPost()) {
-            if ($this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->hasSingleStore()) {
+            /** @var \Magento\Store\Model\StoreManagerInterface $storeManagerInterface */
+            $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
+            if ($storeManager->hasSingleStore()) {
                 $data['stores'] = array(
-                    $this->_objectManager->get('Magento\Store\Model\StoreManager')->getStore(true)->getId()
+                    $storeManager->getStore(true)->getId()
                 );
             } elseif (isset($data['select_stores'])) {
                 $data['stores'] = $data['select_stores'];
             }
 
-            $review = $this->_objectManager->create('Magento\Review\Model\Review')->setData($data);
-
-            $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
+            $review = $this->_reviewFactory->create()->setData($data);
 
             try {
                 $review->setEntityId(1) // product
                     ->setEntityPkValue($productId)
-                    ->setStoreId($product->getStoreId())
+                    ->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID)
                     ->setStatusId($data['status_id'])
                     ->setCustomerId(null)//null is for administrator only
                     ->save();
 
                 $arrRatingId = $this->getRequest()->getParam('ratings', array());
                 foreach ($arrRatingId as $ratingId => $optionId) {
-                    $this->_objectManager->create(
-                        'Magento\Review\Model\Rating'
+                    $this->_ratingFactory->create(
                     )->setRatingId(
                         $ratingId
                     )->setReviewId(
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Sidebar.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Sidebar.php
index 65b0c1da6cc40dbd07b20a98717b00ede47cb338..b005aacc65b6301062d30aa63ca34017ea24c819 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Sidebar.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create/Sidebar.php
@@ -67,7 +67,7 @@ class Sidebar extends \Magento\Sales\Block\Adminhtml\Order\Create\AbstractCreate
      */
     public function canDisplay($child)
     {
-        if (method_exists($child, 'canDisplay')) {
+        if (method_exists($child, 'canDisplay') && is_callable([$child, 'canDisplay'])) {
             return $child->canDisplay();
         }
         return true;
diff --git a/app/code/Magento/Sales/Block/Order/Link.php b/app/code/Magento/Sales/Block/Order/Link.php
index a048cf2fad9ade531f05b7e9ec5469780471f77d..9e4903979c26122625b888e537bee0ef79ddfb05 100644
--- a/app/code/Magento/Sales/Block/Order/Link.php
+++ b/app/code/Magento/Sales/Block/Order/Link.php
@@ -74,10 +74,9 @@ class Link extends \Magento\Framework\View\Element\Html\Link\Current
      */
     protected function _toHtml()
     {
-        if ($this->hasKey() && method_exists(
-            $this->getOrder(),
-            'has' . $this->getKey()
-        ) && !$this->getOrder()->{'has' . $this->getKey()}()
+        if ($this->hasKey()
+            && method_exists($this->getOrder(), 'has' . $this->getKey())
+            && !$this->getOrder()->{'has' . $this->getKey()}()
         ) {
             return '';
         }
diff --git a/app/code/Magento/Sales/Block/Order/Totals.php b/app/code/Magento/Sales/Block/Order/Totals.php
index 9b88f2b376426aac74b62ae072c6720dc35314b1..fd661ba9d9d95c0226a174175b2c09a1da3b727c 100644
--- a/app/code/Magento/Sales/Block/Order/Totals.php
+++ b/app/code/Magento/Sales/Block/Order/Totals.php
@@ -72,7 +72,7 @@ class Totals extends \Magento\Framework\View\Element\Template
     {
         $this->_initTotals();
         foreach ($this->getLayout()->getChildBlocks($this->getNameInLayout()) as $child) {
-            if (method_exists($child, 'initTotals')) {
+            if (method_exists($child, 'initTotals') && is_callable([$child, 'initTotals'])) {
                 $child->initTotals();
             }
         }
diff --git a/app/code/Magento/Sales/Helper/Quote/Item/Compare.php b/app/code/Magento/Sales/Helper/Quote/Item/Compare.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb665aa5baf5d2f797c65335ff1bfc7da0667deb
--- /dev/null
+++ b/app/code/Magento/Sales/Helper/Quote/Item/Compare.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\Sales\Helper\Quote\Item;
+
+use Magento\Sales\Model\Quote\Item;
+
+/**
+ * Class Compare
+ */
+class Compare
+{
+    /**
+     * Returns option values adopted to compare
+     *
+     * @param mixed $value
+     * @return mixed
+     */
+    protected function getOptionValues($value)
+    {
+        if (is_string($value) && is_array(@unserialize($value))) {
+            $value = @unserialize($value);
+            unset($value['qty'], $value['uenc']);
+        }
+        return $value;
+    }
+
+    /**
+     * Compare two quote items
+     *
+     * @param Item $target
+     * @param Item $compared
+     * @return bool
+     */
+    public function compare(Item $target, Item $compared)
+    {
+        if ($target->getProductId() != $compared->getProductId()) {
+            return false;
+        }
+        $targetOptions = $this->getOptions($target);
+        $comparedOptions = $this->getOptions($compared);
+
+        if (array_diff_key($targetOptions, $comparedOptions) != array_diff_key($comparedOptions, $targetOptions)
+        ) {
+            return false;
+        }
+        foreach ($targetOptions as $name => $value) {
+            if ($comparedOptions[$name] != $value) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns options adopted to compare
+     *
+     * @param Item $item
+     * @return array
+     */
+    public function getOptions(Item $item)
+    {
+        $options = [];
+        foreach ($item->getOptions() as $option) {
+            $options[$option->getCode()] = $this->getOptionValues($option->getValue());
+        }
+        return $options;
+    }
+}
diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php
index f285b0b142296088a13990b6b0335bcfb5c97f89..4ce2ec237a0565632d27e0df909935da8b541701 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/Create.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php
@@ -440,10 +440,8 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
         $quote->getShippingAddress()->setShippingDescription($order->getShippingDescription());
 
         $paymentData = $order->getPayment()->getData();
-        if ('ccsave' !== $paymentData['method']) {
-            unset($paymentData['cc_type'], $paymentData['cc_last4']);
-            unset($paymentData['cc_exp_month'], $paymentData['cc_exp_year']);
-        }
+        unset($paymentData['cc_type'], $paymentData['cc_last4']);
+        unset($paymentData['cc_exp_month'], $paymentData['cc_exp_year']);
         $quote->getPayment()->addData($paymentData);
 
         $orderCouponCode = $order->getCouponCode();
diff --git a/app/code/Magento/Sales/Model/Payment/Method/Converter.php b/app/code/Magento/Sales/Model/Payment/Method/Converter.php
deleted file mode 100644
index 7293a5da804f82299bc7f4072187a75a06c36f4b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Model/Payment/Method/Converter.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-
-/**
- * Data converter
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Sales\Model\Payment\Method;
-
-class Converter
-{
-    /**
-     * List of fields that has to be encrypted
-     * Format: method_name => array(field1, field2, ... )
-     *
-     * @var array
-     */
-    protected $_encryptFields = array(
-        'ccsave' => array('cc_owner' => true, 'cc_exp_year' => true, 'cc_exp_month' => true)
-    );
-
-    /**
-     * @var \Magento\Framework\Encryption\EncryptorInterface
-     */
-    protected $_encryptor;
-
-    /**
-     * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
-     */
-    public function __construct(\Magento\Framework\Encryption\EncryptorInterface $encryptor)
-    {
-        $this->_encryptor = $encryptor;
-    }
-
-    /**
-     * Check if specified field is encrypted
-     *
-     * @param \Magento\Framework\Model\AbstractModel $object
-     * @param string $filedName
-     * @return bool
-     */
-    protected function _shouldBeEncrypted(\Magento\Framework\Model\AbstractModel $object, $filedName)
-    {
-        $method = $object->getData('method');
-        return isset($this->_encryptFields[$method][$filedName]) && $this->_encryptFields[$method][$filedName];
-    }
-
-    /**
-     * Decode data
-     *
-     * @param \Magento\Framework\Model\AbstractModel $object
-     * @param string $filedName
-     * @return mixed
-     */
-    public function decode(\Magento\Framework\Model\AbstractModel $object, $filedName)
-    {
-        $value = $object->getData($filedName);
-
-        if ($this->_shouldBeEncrypted($object, $filedName)) {
-            $value = $this->_encryptor->decrypt($value);
-        }
-
-        return $value;
-    }
-
-    /**
-     * Encode data
-     *
-     * @param \Magento\Framework\Model\AbstractModel $object
-     * @param string $filedName
-     * @return mixed
-     */
-    public function encode(\Magento\Framework\Model\AbstractModel $object, $filedName)
-    {
-        $value = $object->getData($filedName);
-
-        if ($this->_shouldBeEncrypted($object, $filedName)) {
-            $value = $this->_encryptor->encrypt($value);
-        }
-
-        return $value;
-    }
-}
diff --git a/app/code/Magento/Sales/Model/Quote/Item.php b/app/code/Magento/Sales/Model/Quote/Item.php
index 4dea22c070c233803643d3eb72fc0b96103283d3..557efea73a5220d08fce1f92c2a28966fe3d8c0b 100644
--- a/app/code/Magento/Sales/Model/Quote/Item.php
+++ b/app/code/Magento/Sales/Model/Quote/Item.php
@@ -197,13 +197,19 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem
      */
     protected $_itemOptionFactory;
 
+    /**
+     * @var \Magento\Sales\Helper\Quote\Item\Compare
+     */
+    protected $_compareHelper;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param \Magento\Sales\Model\Status\ListFactory $statusListFactory
      * @param \Magento\Framework\Locale\FormatInterface $localeFormat
-     * @param \Magento\Sales\Model\Quote\Item\OptionFactory $itemOptionFactory
+     * @param Item\OptionFactory $itemOptionFactory
+     * @param \Magento\Sales\Helper\Quote\Item\Compare $compareHelper
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
      * @param array $data
@@ -217,6 +223,7 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem
         \Magento\Sales\Model\Status\ListFactory $statusListFactory,
         \Magento\Framework\Locale\FormatInterface $localeFormat,
         \Magento\Sales\Model\Quote\Item\OptionFactory $itemOptionFactory,
+        \Magento\Sales\Helper\Quote\Item\Compare $compareHelper,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
@@ -224,6 +231,7 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem
         $this->_errorInfos = $statusListFactory->create();
         $this->_localeFormat = $localeFormat;
         $this->_itemOptionFactory = $itemOptionFactory;
+        $this->_compareHelper = $compareHelper;
         parent::__construct($context, $registry, $productFactory, $resource, $resourceCollection, $data);
     }
 
@@ -504,46 +512,14 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem
     }
 
     /**
-     * Compare item
+     * Compare items
      *
      * @param   \Magento\Sales\Model\Quote\Item $item
      * @return  bool
      */
     public function compare($item)
     {
-        if ($this->getProductId() != $item->getProductId()) {
-            return false;
-        }
-        foreach ($this->getOptions() as $option) {
-            if (in_array($option->getCode(), $this->_notRepresentOptions)) {
-                continue;
-            }
-            $itemOption = $item->getOptionByCode($option->getCode());
-            if ($itemOption) {
-                $itemOptionValue = $itemOption->getValue();
-                $optionValue = $option->getValue();
-
-                // dispose of some options params, that can cramp comparing of arrays
-                if (is_string($itemOptionValue) && is_string($optionValue)) {
-                    $_itemOptionValue = @unserialize($itemOptionValue);
-                    $_optionValue = @unserialize($optionValue);
-                    if (is_array($_itemOptionValue) && is_array($_optionValue)) {
-                        $itemOptionValue = $_itemOptionValue;
-                        $optionValue = $_optionValue;
-                        // looks like it does not break bundle selection qty
-                        unset($itemOptionValue['qty'], $itemOptionValue['uenc']);
-                        unset($optionValue['qty'], $optionValue['uenc']);
-                    }
-                }
-
-                if ($itemOptionValue != $optionValue) {
-                    return false;
-                }
-            } else {
-                return false;
-            }
-        }
-        return true;
+        return $this->_compareHelper->compare($this, $item);
     }
 
     /**
@@ -609,7 +585,7 @@ class Item extends \Magento\Sales\Model\Quote\Item\AbstractItem
     /**
      * Get all item options
      *
-     * @return array
+     * @return \Magento\Sales\Model\Quote\Item\Option[]
      */
     public function getOptions()
     {
diff --git a/app/code/Magento/Sales/Model/Resource/AbstractResource.php b/app/code/Magento/Sales/Model/Resource/AbstractResource.php
index ed229cee4cc2ea57814d9345a936906681d60691..379b55361c53bcd3a2532d7db5396380130af4f0 100644
--- a/app/code/Magento/Sales/Model/Resource/AbstractResource.php
+++ b/app/code/Magento/Sales/Model/Resource/AbstractResource.php
@@ -30,13 +30,6 @@ namespace Magento\Sales\Model\Resource;
  */
 abstract class AbstractResource extends \Magento\Framework\Model\Resource\Db\AbstractDb
 {
-    /**
-     * Data converter object
-     *
-     * @var \Magento\Sales\Model\ConverterInterface
-     */
-    protected $_converter = null;
-
     /**
      * @var \Magento\Framework\Stdlib\DateTime
      */
@@ -68,64 +61,4 @@ abstract class AbstractResource extends \Magento\Framework\Model\Resource\Db\Abs
         $data = parent::_prepareDataForSave($object);
         return $data;
     }
-
-    /**
-     * Check if current model data should be converted
-     *
-     * @return bool
-     */
-    protected function _shouldBeConverted()
-    {
-        return null !== $this->_converter;
-    }
-
-    /**
-     * Perform actions before object save
-     *
-     * @param \Magento\Framework\Model\AbstractModel $object
-     * @return $this
-     */
-    protected function _beforeSave(\Magento\Framework\Model\AbstractModel $object)
-    {
-        parent::_beforeSave($object);
-
-        if (true == $this->_shouldBeConverted()) {
-            foreach ($object->getData() as $fieldName => $fieldValue) {
-                $object->setData($fieldName, $this->_converter->encode($object, $fieldName));
-            }
-        }
-        return $this;
-    }
-
-    /**
-     * Perform actions after object save
-     *
-     * @param \Magento\Framework\Model\AbstractModel $object
-     * @return $this
-     */
-    protected function _afterSave(\Magento\Framework\Model\AbstractModel $object)
-    {
-        if (true == $this->_shouldBeConverted()) {
-            foreach ($object->getData() as $fieldName => $fieldValue) {
-                $object->setData($fieldName, $this->_converter->decode($object, $fieldName));
-            }
-        }
-        return parent::_afterSave($object);
-    }
-
-    /**
-     * Perform actions after object load
-     *
-     * @param \Magento\Framework\Model\AbstractModel $object
-     * @return $this
-     */
-    protected function _afterLoad(\Magento\Framework\Model\AbstractModel $object)
-    {
-        if (true == $this->_shouldBeConverted()) {
-            foreach ($object->getData() as $fieldName => $fieldValue) {
-                $object->setData($fieldName, $this->_converter->decode($object, $fieldName));
-            }
-        }
-        return parent::_afterLoad($object);
-    }
 }
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Payment.php b/app/code/Magento/Sales/Model/Resource/Order/Payment.php
index d87e40ca9eb122c63f9a1c62518c9f3147481829..b95ce67d42b744fe033165fcfb9ac2c9e6cdea7a 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Payment.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Payment.php
@@ -42,26 +42,18 @@ class Payment extends AbstractOrder
      */
     protected $_eventPrefix = 'sales_order_payment_resource';
 
-    /**
-     * @var \Magento\Sales\Model\Payment\Method\Converter
-     */
-    protected $_paymentConverter;
-
     /**
      * @param \Magento\Framework\App\Resource $resource
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Eav\Model\Entity\TypeFactory $eavEntityTypeFactory
-     * @param \Magento\Sales\Model\Payment\Method\Converter $paymentConverter
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
         \Magento\Framework\Stdlib\DateTime $dateTime,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Eav\Model\Entity\TypeFactory $eavEntityTypeFactory,
-        \Magento\Sales\Model\Payment\Method\Converter $paymentConverter
+        \Magento\Eav\Model\Entity\TypeFactory $eavEntityTypeFactory
     ) {
-        $this->_paymentConverter = $paymentConverter;
         parent::__construct($resource, $dateTime, $eventManager, $eavEntityTypeFactory);
     }
 
@@ -72,7 +64,6 @@ class Payment extends AbstractOrder
      */
     protected function _construct()
     {
-        $this->_converter = $this->_paymentConverter;
         $this->_init('sales_flat_order_payment', 'entity_id');
     }
 }
diff --git a/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php b/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php
index 49d7984a31dba2a7d634ce80b57c048ec22610ab..1ed4e3da4b984c3f8857226bf0ed70e8dc710171 100644
--- a/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Order/Payment/Collection.php
@@ -42,17 +42,11 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Collection\Abstract
      */
     protected $_eventObject = 'order_payment_collection';
 
-    /**
-     * @var \Magento\Sales\Model\Payment\Method\Converter
-     */
-    protected $_converter;
-
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
      * @param \Magento\Framework\Logger $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Sales\Model\Payment\Method\Converter $converter
      * @param \Zend_Db_Adapter_Abstract $connection
      * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource
      */
@@ -61,11 +55,9 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Collection\Abstract
         \Magento\Framework\Logger $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Sales\Model\Payment\Method\Converter $converter,
         $connection = null,
         \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
     ) {
-        $this->_converter = $converter;
         parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
     }
 
@@ -89,14 +81,6 @@ class Collection extends \Magento\Sales\Model\Resource\Order\Collection\Abstract
         foreach ($this->_items as $item) {
             $this->getResource()->unserializeFields($item);
         }
-
-        /** @var \Magento\Sales\Model\Order\Payment $item */
-        foreach ($this->_items as $item) {
-            foreach ($item->getData() as $fieldName => $fieldValue) {
-                $item->setData($fieldName, $this->_converter->decode($item, $fieldName));
-            }
-        }
-
         return parent::_afterLoad();
     }
 }
diff --git a/app/code/Magento/Sales/Model/Resource/Quote/Payment.php b/app/code/Magento/Sales/Model/Resource/Quote/Payment.php
index d36451baca400664c327e8a9065fbbf274bb0223..22b0d7282e224c36e984bc7c34e534f54c372570 100644
--- a/app/code/Magento/Sales/Model/Resource/Quote/Payment.php
+++ b/app/code/Magento/Sales/Model/Resource/Quote/Payment.php
@@ -35,22 +35,14 @@ class Payment extends \Magento\Sales\Model\Resource\AbstractResource
      */
     protected $_serializableFields = array('additional_information' => array(null, array()));
 
-    /**
-     * @var \Magento\Sales\Model\Payment\Method\Converter
-     */
-    protected $_paymentConverter;
-
     /**
      * @param \Magento\Framework\App\Resource $resource
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
-     * @param \Magento\Sales\Model\Payment\Method\Converter $paymentConverter
      */
     public function __construct(
         \Magento\Framework\App\Resource $resource,
-        \Magento\Framework\Stdlib\DateTime $dateTime,
-        \Magento\Sales\Model\Payment\Method\Converter $paymentConverter
+        \Magento\Framework\Stdlib\DateTime $dateTime
     ) {
-        $this->_paymentConverter = $paymentConverter;
         parent::__construct($resource, $dateTime);
     }
 
@@ -61,7 +53,6 @@ class Payment extends \Magento\Sales\Model\Resource\AbstractResource
      */
     protected function _construct()
     {
-        $this->_converter = $this->_paymentConverter;
         $this->_init('sales_flat_quote_payment', 'payment_id');
     }
 }
diff --git a/app/code/Magento/Sales/Model/Resource/Quote/Payment/Collection.php b/app/code/Magento/Sales/Model/Resource/Quote/Payment/Collection.php
index 0f8e74a47c4352c371a94c598df13c8af71b730c..2b4d468396ba01600257cfc2d3b54133c3369069 100644
--- a/app/code/Magento/Sales/Model/Resource/Quote/Payment/Collection.php
+++ b/app/code/Magento/Sales/Model/Resource/Quote/Payment/Collection.php
@@ -28,17 +28,11 @@ namespace Magento\Sales\Model\Resource\Quote\Payment;
  */
 class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
 {
-    /**
-     * @var \Magento\Sales\Model\Payment\Method\Converter
-     */
-    protected $_converter;
-
     /**
      * @param \Magento\Core\Model\EntityFactory $entityFactory
      * @param \Magento\Framework\Logger $logger
      * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Sales\Model\Payment\Method\Converter $converter
      * @param \Zend_Db_Adapter_Abstract $connection
      * @param \Magento\Framework\Model\Resource\Db\AbstractDb $resource
      */
@@ -47,12 +41,10 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
         \Magento\Framework\Logger $logger,
         \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Sales\Model\Payment\Method\Converter $converter,
         $connection = null,
         \Magento\Framework\Model\Resource\Db\AbstractDb $resource = null
     ) {
         parent::__construct($entityFactory, $logger, $fetchStrategy, $eventManager, $connection, $resource);
-        $this->_converter = $converter;
     }
 
     /**
@@ -86,14 +78,6 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
         foreach ($this->_items as $item) {
             $this->getResource()->unserializeFields($item);
         }
-
-        /** @var \Magento\Sales\Model\Quote\Payment $item */
-        foreach ($this->_items as $item) {
-            foreach ($item->getData() as $fieldName => $fieldValue) {
-                $item->setData($fieldName, $this->_converter->decode($item, $fieldName));
-            }
-        }
-
         return parent::_afterLoad();
     }
 }
diff --git a/app/code/Magento/Sales/data/sales_setup/data-upgrade-1.6.0.8-1.6.0.9.php b/app/code/Magento/Sales/data/sales_setup/data-upgrade-1.6.0.8-1.6.0.9.php
deleted file mode 100644
index 42fbd4580f75203af2292a4b877c418692e4818c..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/data/sales_setup/data-upgrade-1.6.0.8-1.6.0.9.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/** @var $installer \Magento\Sales\Model\Resource\Setup */
-$installer = $this;
-
-$installer->startSetup();
-$itemsPerPage = 1000;
-$currentPosition = 0;
-
-/** Update sales order payment */
-do {
-    $select = $installer->getConnection()->select()->from(
-        $installer->getTable('sales_flat_order_payment'),
-        array('entity_id', 'cc_owner', 'cc_exp_month', 'cc_exp_year', 'method')
-    )->where(
-        'method = ?',
-        'ccsave'
-    )->limit(
-        $itemsPerPage,
-        $currentPosition
-    );
-
-    $orders = $select->query()->fetchAll();
-    $currentPosition += $itemsPerPage;
-
-    foreach ($orders as $order) {
-        $installer->getConnection()->update(
-            $installer->getTable('sales_flat_order_payment'),
-            array(
-                'cc_exp_month' => $installer->getEncryptor()->encrypt($order['cc_exp_month']),
-                'cc_exp_year' => $installer->getEncryptor()->encrypt($order['cc_exp_year']),
-                'cc_owner' => $installer->getEncryptor()->encrypt($order['cc_owner'])
-            ),
-            array('entity_id = ?' => $order['entity_id'])
-        );
-    }
-} while (count($orders) > 0);
-
-/** Update sales quote payment */
-$currentPosition = 0;
-do {
-    $select = $installer->getConnection()->select()->from(
-        $installer->getTable('sales_flat_quote_payment'),
-        array('payment_id', 'cc_owner', 'cc_exp_month', 'cc_exp_year', 'method')
-    )->where(
-        'method = ?',
-        'ccsave'
-    )->limit(
-        $itemsPerPage,
-        $currentPosition
-    );
-
-    $quotes = $select->query()->fetchAll();
-    $currentPosition += $itemsPerPage;
-
-    foreach ($quotes as $quote) {
-        $installer->getConnection()->update(
-            $installer->getTable('sales_flat_quote_payment'),
-            array(
-                'cc_exp_month' => $installer->getEncryptor()->encrypt($quote['cc_exp_month']),
-                'cc_exp_year' => $installer->getEncryptor()->encrypt($quote['cc_exp_year']),
-                'cc_owner' => $installer->getEncryptor()->encrypt($quote['cc_owner'])
-            ),
-            array('payment_id = ?' => $quote['payment_id'])
-        );
-    }
-} while (count($quotes) > 0);
-
-$installer->endSetup();
diff --git a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
index 78245571189691eeac32245e9b3331869d804ed7..5c41a0672a3d5757fcf83c726b5d3cf7694c05e6 100644
--- a/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
+++ b/app/code/Magento/Sales/view/adminhtml/web/order/create/scripts.js
@@ -938,22 +938,25 @@ AdminOrder.prototype = {
         }
     },
 
-    loadAreaResponseHandler : function (response){
+    loadAreaResponseHandler : function (response) {
         if (response.error) {
             alert(response.message);
         }
-        if(response.ajaxExpired && response.ajaxRedirect) {
+        if (response.ajaxExpired && response.ajaxRedirect) {
             setLocation(response.ajaxRedirect);
         }
-        if(!this.loadingAreas){
+        if (!this.loadingAreas) {
             this.loadingAreas = [];
         }
-        if(typeof this.loadingAreas == 'string'){
+        if (typeof this.loadingAreas == 'string') {
             this.loadingAreas = [this.loadingAreas];
         }
-        if(this.loadingAreas.indexOf('message') == -1) {
+        if (this.loadingAreas.indexOf('message') == -1) {
             this.loadingAreas.push('message');
         }
+        if (response.header) {
+            jQuery('.page-actions-inner').attr('data-title', response.header);
+        }
 
         for (var i = 0; i < this.loadingAreas.length; i++) {
             var id = this.loadingAreas[i];
@@ -968,7 +971,7 @@ AdminOrder.prototype = {
         }
     },
 
-    prepareArea : function(area){
+    prepareArea : function(area) {
         if (this.giftMessageDataChanged) {
             return area.without('giftmessage');
         }
diff --git a/app/code/Magento/SalesRule/Helper/Data.php b/app/code/Magento/SalesRule/Helper/Data.php
deleted file mode 100644
index 9d0cc66847e2f5373b46a63849bd29558cf1557f..0000000000000000000000000000000000000000
--- a/app/code/Magento/SalesRule/Helper/Data.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\SalesRule\Helper;
-
-use Magento\Sales\Model\Quote\Item\AbstractItem;
-
-/**
- * SalesRule data helper
- */
-class Data extends \Magento\Framework\App\Helper\AbstractHelper
-{
-    /**
-     * Set store and base price which will be used during discount calculation to item object
-     *
-     * @param AbstractItem $item
-     * @param float $basePrice
-     * @param float $price
-     * @return $this
-     */
-    public function setItemDiscountPrices(AbstractItem $item, $basePrice, $price)
-    {
-        $item->setDiscountCalculationPrice($price);
-        $item->setBaseDiscountCalculationPrice($basePrice);
-        return $this;
-    }
-
-    /**
-     * Add additional amounts to discount calculation prices
-     *
-     * @param AbstractItem $item
-     * @param float $basePrice
-     * @param float $price
-     * @return $this
-     */
-    public function addItemDiscountPrices(AbstractItem $item, $basePrice, $price)
-    {
-        $discountPrice = $item->getDiscountCalculationPrice();
-        $baseDiscountPrice = $item->getBaseDiscountCalculationPrice();
-
-        if ($discountPrice || $baseDiscountPrice || $basePrice || $price) {
-            $discountPrice = $discountPrice ? $discountPrice : $item->getCalculationPrice();
-            $baseDiscountPrice = $baseDiscountPrice ? $baseDiscountPrice : $item->getBaseCalculationPrice();
-            $this->setItemDiscountPrices($item, $baseDiscountPrice + $basePrice, $discountPrice + $price);
-        }
-        return $this;
-    }
-}
diff --git a/app/code/Magento/SalesRule/Model/Observer.php b/app/code/Magento/SalesRule/Model/Observer.php
index e6c6a2a69b60dba4f25567602c7839825b209114..9b0b1ceebf161bb941faf06b169fee2ab0f9b602 100644
--- a/app/code/Magento/SalesRule/Model/Observer.php
+++ b/app/code/Magento/SalesRule/Model/Observer.php
@@ -166,10 +166,9 @@ class Observer
     /**
      * Refresh sales coupons report statistics for last day
      *
-     * @param Schedule $schedule
      * @return $this
      */
-    public function aggregateSalesReportCouponsData($schedule)
+    public function aggregateSalesReportCouponsData()
     {
         $this->_localeResolver->emulate(0);
         $currentDate = $this->_localeDate->date();
diff --git a/app/code/Magento/Shipping/Model/Shipping.php b/app/code/Magento/Shipping/Model/Shipping.php
index 467c80a0b34c26425e2153e6482fd03e94b07184..21d3a7f0c1609560b2b256342c074ae5793c57fb 100644
--- a/app/code/Magento/Shipping/Model/Shipping.php
+++ b/app/code/Magento/Shipping/Model/Shipping.php
@@ -305,7 +305,7 @@ class Shipping implements RateCollectorInterface
                 return $this;
             }
             // sort rates by price
-            if (method_exists($result, 'sortRatesByPrice')) {
+            if (method_exists($result, 'sortRatesByPrice') && is_callable([$result, 'sortRatesByPrice'])) {
                 $result->sortRatesByPrice();
             }
             $this->getResult()->append($result);
diff --git a/app/code/Magento/Store/App/Response/Redirect.php b/app/code/Magento/Store/App/Response/Redirect.php
index 6bca24ac9d720353022808a40cdc69261b72dd31..615e1862bfbae8d42d2114d61ac206323ccca933 100644
--- a/app/code/Magento/Store/App/Response/Redirect.php
+++ b/app/code/Magento/Store/App/Response/Redirect.php
@@ -207,10 +207,19 @@ class Redirect implements \Magento\Framework\App\Response\RedirectInterface
     protected function _isUrlInternal($url)
     {
         if (strpos($url, 'http') !== false) {
-            $unsecure = strpos($url, $this->_storeManager->getStore()->getBaseUrl()) === 0;
+            $unsecure = strpos(
+                $url,
+                $this->_storeManager->getStore()->getBaseUrl(
+                    \Magento\Framework\UrlInterface::URL_TYPE_DIRECT_LINK,
+                    false
+                )
+            ) === 0;
             $secure = strpos(
                 $url,
-                $this->_storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK, true)
+                $this->_storeManager->getStore()->getBaseUrl(
+                    \Magento\Framework\UrlInterface::URL_TYPE_DIRECT_LINK,
+                    true
+                )
             ) === 0;
             return $unsecure || $secure;
         }
diff --git a/app/code/Magento/Tax/sql/tax_setup/install-1.6.0.0.php b/app/code/Magento/Tax/sql/tax_setup/install-1.6.0.0.php
index 01c4fc7c0cc98cd4bcf4f3f522c802b9442c37ab..c7ea81fba3dd548b3662a702d21c01d270555125 100644
--- a/app/code/Magento/Tax/sql/tax_setup/install-1.6.0.0.php
+++ b/app/code/Magento/Tax/sql/tax_setup/install-1.6.0.0.php
@@ -23,6 +23,7 @@
  */
 /** @var $installer \Magento\Tax\Model\Resource\Setup */
 $installer = $this;
+$installer->startSetup();
 //
 /**
  * Create table 'tax/class'
diff --git a/app/code/Magento/User/sql/user_setup/upgrade-1.6.1.3-1.6.1.4.php b/app/code/Magento/User/sql/user_setup/upgrade-1.6.1.3-1.6.1.4.php
index c7b18636a6956013738e72d2165fced610dc9be2..5f6bffb9e5465e0a54a6aaee6ff1984fcfc121f1 100644
--- a/app/code/Magento/User/sql/user_setup/upgrade-1.6.1.3-1.6.1.4.php
+++ b/app/code/Magento/User/sql/user_setup/upgrade-1.6.1.3-1.6.1.4.php
@@ -39,3 +39,4 @@ $connection->addColumn(
         'comment' => 'Backend interface locale'
     )
 );
+$installer->endSetup();
diff --git a/app/code/Magento/Weee/Helper/Data.php b/app/code/Magento/Weee/Helper/Data.php
index 98002b4da55273ce0d4884705297e9dd5bc7fc8c..fd423abe59668baae0e593c4a041c7f1e2939821 100644
--- a/app/code/Magento/Weee/Helper/Data.php
+++ b/app/code/Magento/Weee/Helper/Data.php
@@ -25,6 +25,7 @@ namespace Magento\Weee\Helper;
 
 use Magento\Store\Model\Store;
 use Magento\Store\Model\Website;
+use Magento\Sales\Model\Quote\Item\AbstractItem;
 
 /**
  * WEEE data helper
@@ -440,4 +441,40 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
 
         return (float) $amount;
     }
+
+    /**
+     * Set store and base price which will be used during discount calculation to item object
+     *
+     * @param AbstractItem $item
+     * @param float $basePrice
+     * @param float $price
+     * @return $this
+     */
+    public function setItemDiscountPrices(AbstractItem $item, $basePrice, $price)
+    {
+        $item->setDiscountCalculationPrice($price);
+        $item->setBaseDiscountCalculationPrice($basePrice);
+        return $this;
+    }
+
+    /**
+     * Add additional amounts to discount calculation prices
+     *
+     * @param AbstractItem $item
+     * @param float $basePrice
+     * @param float $price
+     * @return $this
+     */
+    public function addItemDiscountPrices(AbstractItem $item, $basePrice, $price)
+    {
+        $discountPrice = $item->getDiscountCalculationPrice();
+        $baseDiscountPrice = $item->getBaseDiscountCalculationPrice();
+
+        if ($discountPrice || $baseDiscountPrice || $basePrice || $price) {
+            $discountPrice = $discountPrice ? $discountPrice : $item->getCalculationPrice();
+            $baseDiscountPrice = $baseDiscountPrice ? $baseDiscountPrice : $item->getBaseCalculationPrice();
+            $this->setItemDiscountPrices($item, $baseDiscountPrice + $basePrice, $discountPrice + $price);
+        }
+        return $this;
+    }
 }
diff --git a/app/code/Magento/Weee/Model/Total/Quote/Weee.php b/app/code/Magento/Weee/Model/Total/Quote/Weee.php
index 7b9155812a666b625da7e1f7fceae5cdfd2dda4b..ab53d2cfdac7191aed4f7c9274b68fc08873b254 100644
--- a/app/code/Magento/Weee/Model/Total/Quote/Weee.php
+++ b/app/code/Magento/Weee/Model/Total/Quote/Weee.php
@@ -77,27 +77,15 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
         if (!count($items)) {
             return $this;
         }
-
         $address->setAppliedTaxesReset(true);
         $address->setAppliedTaxes(array());
-
         $this->_store = $address->getQuote()->getStore();
         foreach ($items as $item) {
-            if ($item->getParentItemId()) {
-                continue;
-            }
-            $this->_resetItemData($item);
-            if ($item->getHasChildren() && $item->isChildrenCalculated()) {
-                foreach ($item->getChildren() as $child) {
-                    $this->_resetItemData($child);
-                    $this->_process($address, $child);
-                }
+            $this->_processItem($item, $address);
+            if ($item->isChildrenCalculated()) {
                 $this->_recalculateParent($item);
-            } else {
-                $this->_process($address, $item);
             }
         }
-
         if ($this->_isTaxAffected) {
             $address->unsSubtotalInclTax();
             $address->unsBaseSubtotalInclTax();
@@ -107,18 +95,14 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
     }
 
     /**
-     * Calculate item fixed tax and prepare information for discount and recular taxation
+     * Calculate item fixed tax and prepare information for discount and regular taxation
      *
      * @param   \Magento\Sales\Model\Quote\Address $address
      * @param   \Magento\Sales\Model\Quote\Item\AbstractItem $item
-     * @return  void|$this
+     * @return  array
      */
     protected function _process(\Magento\Sales\Model\Quote\Address $address, $item)
     {
-        if (!$this->_weeeData->isEnabled($this->_store)) {
-            return $this;
-        }
-
         $attributes = $this->_weeeData->getProductWeeeAttributes(
             $item->getProduct(),
             $address,
@@ -126,27 +110,27 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
             $this->_store->getWebsiteId()
         );
 
-        $applied = array();
-        $productTaxes = array();
+        $taxData['applied'] = array();
+        $taxData['product_taxes'] = array();
 
-        $totalValue = 0;
-        $baseTotalValue = 0;
-        $totalRowValue = 0;
-        $baseTotalRowValue = 0;
+        $valuesData['total'] = 0;
+        $valuesData['base_total'] = 0;
+        $valuesData['total_row'] = 0;
+        $valuesData['base_total_row'] = 0;
 
         foreach ($attributes as $key => $attribute) {
-            $baseValue      = $attribute->getAmount();
-            $value          = $this->_store->convertPrice($baseValue);
-            $rowValue       = $value * $item->getTotalQty();
-            $baseRowValue   = $baseValue * $item->getTotalQty();
-            $title          = $attribute->getName();
-
-            $totalValue += $value;
-            $baseTotalValue += $baseValue;
-            $totalRowValue += $rowValue;
-            $baseTotalRowValue += $baseRowValue;
-
-            $productTaxes[] = array(
+            $baseValue = $attribute->getAmount();
+            $value = $this->_store->convertPrice($baseValue);
+            $rowValue = $value * $item->getTotalQty();
+            $baseRowValue = $baseValue * $item->getTotalQty();
+            $title = $attribute->getName();
+
+            $valuesData['total'] += $value;
+            $valuesData['base_total'] += $baseValue;
+            $valuesData['total_row'] += $rowValue;
+            $valuesData['base_total_row'] += $baseRowValue;
+
+            $taxData['product_taxes'][] = array(
                 'title' => $title,
                 'base_amount' => $baseValue,
                 'amount' => $value,
@@ -161,54 +145,139 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
                 'base_row_amount_incl_tax' => $baseRowValue
             );
 
-            $applied[] = array(
-                'id'        => $attribute->getCode(),
-                'percent'   => null,
-                'hidden'    => $this->_weeeData->includeInSubtotal($this->_store),
-                'rates'     => array(array(
-                    'base_real_amount'=> $baseRowValue,
-                    'base_amount'   => $baseRowValue,
-                    'amount'        => $rowValue,
-                    'code'          => $attribute->getCode(),
-                    'title'         => $title,
-                    'percent'       => null,
-                    'position'      => 1,
-                    'priority'      => -1000 + $key,
-                ))
+            $taxData['applied'][] = array(
+                'id' => $attribute->getCode(),
+                'percent' => null,
+                'hidden' => $this->_weeeData->includeInSubtotal($this->_store),
+                'rates' => array(
+                    array(
+                        'base_real_amount' => $baseRowValue,
+                        'base_amount' => $baseRowValue,
+                        'amount' => $rowValue,
+                        'code' => $attribute->getCode(),
+                        'title' => $title,
+                        'percent' => null,
+                        'position' => 1,
+                        'priority' => -1000 + $key
+                    )
+                )
             );
         }
 
-        $item->setWeeeTaxAppliedAmount($totalValue)
-            ->setBaseWeeeTaxAppliedAmount($baseTotalValue)
-            ->setWeeeTaxAppliedRowAmount($totalRowValue)
-            ->setBaseWeeeTaxAppliedRowAmnt($baseTotalRowValue);
+        return array('values' => $valuesData, 'tax' => $taxData, 'address' => $address, 'item' => $item);
+    }
+
+    /**
+     * Prepare item data for processing.
+     *
+     * @param   \Magento\Sales\Model\Quote\Address $address
+     * @param   \Magento\Sales\Model\Quote\Item\AbstractItem $item
+     * @return $this
+     */
+    protected function _processItem($item, $address)
+    {
+        $this->_resetItemDataIfHasParent($item);
+        if ($item->getHasChildren() && $item->isChildrenCalculated()) {
+            foreach ($item->getChildren() as $child) {
+                $this->_resetItemData($child);
+                $this->_processDataWithWeeeData($address, $child);
+            }
+        } else {
+            $this->_processDataWithWeeeData($address, $item);
+        }
+        return $this;
+    }
+
+    /**
+     * Process item if weee is enabled.
+     *
+     * @param   \Magento\Sales\Model\Quote\Address $address
+     * @param   \Magento\Sales\Model\Quote\Item\AbstractItem $item
+     * @return $this
+     */
+    protected function _processDataWithWeeeData ($address, $item)
+    {
+        if ($this->_weeeData->isEnabled($this->_store)) {
+            $processData = $this->_process($address, $item);
+            $this->_setTax($processData);
+        }
+        return $this;
+    }
+
+    /**
+     * Reset item data if it have parent
+     *
+     * @param   \Magento\Sales\Model\Quote\Item\AbstractItem $item
+     * @return $this
+     */
+    protected function _resetItemDataIfHasParent($item)
+    {
+        if (!$item->getParentItemId()) {
+            $this->_resetItemData($item);
+        }
+        return $this;
+    }
 
+    /**
+     * Set tax to item, process tax with total amount and discount settings
+     *
+     * @param array $processData
+     * @return $this
+     */
+    protected function _setTax($processData)
+    {
+        $values  = $processData['values'];
+        $tax     = $processData['tax'];
+        $item    = $processData['item'];
+        $address = $processData['address'];
+
+        $this->_setAppliedTaxes($item, $values);
         $this->_processTaxSettings(
             $item,
-            $totalValue,
-            $baseTotalValue,
-            $totalRowValue,
-            $baseTotalRowValue
+            $values['total'],
+            $values['base_total'],
+            $values['total_row'],
+            $values['base_total_row']
         )->_processTotalAmount(
             $address,
-            $totalRowValue,
-            $baseTotalRowValue
+            $values['total_row'],
+            $values['base_total_row']
         )->_processDiscountSettings(
             $item,
-            $totalValue,
-            $baseTotalValue
+            $values['total'],
+            $values['base_total']
         );
 
-        $this->_weeeData->setApplied($item, array_merge($this->_weeeData->getApplied($item), $productTaxes));
-        if ($applied) {
+        $this->_weeeData->setApplied($item, array_merge($this->_weeeData->getApplied($item), $tax['product_taxes']));
+        if ($tax['applied']) {
             $this->_saveAppliedTaxes(
                 $address,
-                $applied,
+                $tax['applied'],
                 $item->getWeeeTaxAppliedAmount(),
                 $item->getBaseWeeeTaxAppliedAmount(),
                 null
             );
         }
+        return $this;
+    }
+
+    /**
+     * Set applied taxes to item data.
+     *
+     * @param   \Magento\Sales\Model\Quote\Item\AbstractItem $item
+     * @param array $values
+     * @return $this
+     */
+    protected function _setAppliedTaxes($item, $values)
+    {
+        $taxAppliedData = array(
+            'weee_tax_applied_amount' => $values['total'],
+            'base_weee_tax_applied_amount' => $values['base_total'],
+            'weee_tax_applied_row_amount' => $values['total_row'],
+            'base_weee_tax_applied_row_amnt' => $values['base_total_row'],
+        );
+        $item->addData($taxAppliedData);
+        return $this;
     }
 
     /**
@@ -253,7 +322,7 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
     }
 
     /**
-     * Proces row amount based on FPT total amount configuration setting
+     * Process row amount based on FPT total amount configuration setting
      *
      * @param   \Magento\Sales\Model\Quote\Address $address
      * @param   float $rowValue
@@ -277,7 +346,7 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
      * Recalculate parent item amounts based on children results
      *
      * @param   \Magento\Sales\Model\Quote\Item\AbstractItem $item
-     * @return  void
+     * @return  null
      */
     protected function _recalculateParent(\Magento\Sales\Model\Quote\Item\AbstractItem $item)
     {
@@ -333,7 +402,6 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
     /**
      * No aggregated label for fixed product tax
      *
-     * TODO: fix
      * @return string
      */
     public function getLabel()
diff --git a/app/code/Magento/Weee/sql/weee_setup/install-1.6.0.0.php b/app/code/Magento/Weee/sql/weee_setup/install-1.6.0.0.php
index 33362815bdbe6fd5298d7ba14dd3d9f3296f3ec3..58f89d2eda28c035af6d058782e52348f0bed2e8 100644
--- a/app/code/Magento/Weee/sql/weee_setup/install-1.6.0.0.php
+++ b/app/code/Magento/Weee/sql/weee_setup/install-1.6.0.0.php
@@ -24,6 +24,7 @@
 
 /** @var $installer \Magento\Sales\Model\Resource\Setup */
 $installer = $this;
+$installer->startSetup();
 /**
  * Create table 'weee_tax'
  */
diff --git a/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml b/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml
index 8decbb34245732b567f2d64ef682718012e9b246..e67563b85adc24ef434c792bb9b6c96653dd4ca5 100644
--- a/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml
+++ b/app/design/frontend/Magento/blank/Magento_Theme/layout/default_head_blocks.xml
@@ -40,7 +40,7 @@
                 <argument name="file" xsi:type="string">matchMedia.js</argument>
             </arguments>
         </block>
-        <block class="Magento\Theme\Block\Html\Head\Script" name="js-responsive-js" after="mage-zoom-js">
+        <block class="Magento\Theme\Block\Html\Head\Script" name="js-responsive-js">
             <arguments>
                 <argument name="file" xsi:type="string">js/responsive.js</argument>
             </arguments>
diff --git a/dev/tests/functional/lib/Mtf/App/State/State1.php b/dev/tests/functional/lib/Mtf/App/State/State1.php
index cdd4dd9ea20ac8f8fbdadaffae847ba675fafed5..8184556d5a540062f70df064639c32c95a8e459a 100644
--- a/dev/tests/functional/lib/Mtf/App/State/State1.php
+++ b/dev/tests/functional/lib/Mtf/App/State/State1.php
@@ -24,19 +24,38 @@
 
 namespace Mtf\App\State;
 
+use Magento\Core\Test\Fixture\Config;
+
 /**
  * Class State1
  * Example Application State class
- *
  */
 class State1 extends AbstractState
 {
+    /**
+     * Configuration fixture
+     *
+     * @var Config
+     */
+    protected $config;
+
+    /**
+     * @construct
+     * @param Config $config
+     */
+    public function __construct(Config $config)
+    {
+        $this->config = $config;
+    }
+
     /**
      * @inheritdoc
      */
     public function apply()
     {
         parent::apply();
+        $this->config->switchData('app_state1_configuration');
+        $this->config->persist();
     }
 
     /**
diff --git a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/DatepickerElement.php b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/DatepickerElement.php
index dfebc90bf0336e697eaf158a292aeb790e7864f9..39b76ffce6e2bf20cefc8db0fe2881deff8e2cf1 100644
--- a/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/DatepickerElement.php
+++ b/dev/tests/functional/lib/Mtf/Client/Driver/Selenium/Element/DatepickerElement.php
@@ -39,14 +39,14 @@ class DatepickerElement extends Element
      *
      * @var string
      */
-    protected $datePickerButton = './/following-sibling::img[contains(@class,"ui-datepicker-trigger")]';
+    protected $datePickerButton = './../img[contains(@class,"ui-datepicker-trigger")]';
 
     /**
      * DatePicker block
      *
      * @var string
      */
-    protected $datePickerBlock = './/ancestor::body//*[contains(@id,"ui-datepicker-div")]';
+    protected $datePickerBlock = './ancestor::body//*[@id="ui-datepicker-div"]';
 
     /**
      * Field Month on the DatePicker
diff --git a/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml b/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
index 2f47021158bc1d8a1ff4d1dc5b264383342324e4..79bbd38c3dfe1c55c0d02976e4d462a37e0036c9 100644
--- a/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
+++ b/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
@@ -136,4 +136,34 @@
       <step>Verify created product.</step>
     </steps>
   </testcase>
+  <testcase>
+    <id>MTA-128</id>
+    <ticketId>MTA-128</ticketId>
+    <name>SuggestSearchingResult(SearchEntity)WithFucntionalTestsDesignedForAutomationTest</name>
+    <description>Cover Suggest Searching Result (SearchEntity) with fucntional tests designed for automation</description>
+    <module>Search</module>
+    <components>
+      <component>Search Frontend (CS)</component>
+    </components>
+    <steps/>
+  </testcase>
+  <testcase>
+    <id>MTA-15</id>
+    <ticketId>MTA-15</ticketId>
+    <name>CreateDownloadableProductEntityTest</name>
+    <description>Test Creation for Create DownloadableProductEntity </description>
+    <module>Catalog</module>
+    <components>
+      <component>Downloadable Product (CS)</component>
+    </components>
+    <steps>
+    <step> Log in to Backend.</step>
+    <step> Navigate to Products &gt; Catalog.</step>
+    <step> Start to create new Downloadable product.</step>
+    <step> Fill in data according to data set.</step>
+    <step> Fill Downloadable Information tab according to data set.</step>
+    <step> Save product.</step>
+    <step> Verify created product.</step>
+    </steps>
+  </testcase>
 </testcases>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php
index af74b013d24872854d8f1709a493abb545fcfdc0..3c2da313a6956ce4c5d6c7cf5b9b55264c5fcef4 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Config/PageActions.php
@@ -23,33 +23,25 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Backend\Test\Block\System\Config;
 
 use Mtf\Client\Element\Locator;
-use \Magento\Backend\Test\Block\PageActions as AbstractPageActions;
+use Magento\Backend\Test\Block\FormPageActions as AbstractPageActions;
 
+/**
+ * Class PageActions
+ * System config page action
+ */
 class PageActions extends AbstractPageActions
 {
     /**
-     * Save button
+     * Scope CSS selector
      *
      * @var string
      */
-    protected $saveButton = '#save';
-
-    /**
-     * @var string
-     */
     protected $scopeSelector = '.actions.dropdown';
 
-    /**
-     * Click "Save" button
-     */
-    public function save()
-    {
-        $this->_rootElement->find($this->saveButton)->click();
-    }
-
     /**
      * Select store
      *
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 fd68db66592c63f84854d687e89619b8333b25d7..1a2bc9ce0feaedd5edca587ff0f8f56220cad939 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
@@ -190,10 +190,9 @@ class FormTabs extends Form
         } else {
             $isHasData = ($fixture instanceof InjectableFixture) ? $fixture->hasData() : true;
             $tabsFields = $isHasData ? $this->getFieldsByTabs($fixture) : [];
-            foreach ($this->tabs as $tabName => $tab) {
+            foreach ($tabsFields as $tabName => $fields) {
                 $this->openTab($tabName);
-                $tabFields = isset($tabsFields[$tabName]) ? $tabsFields[$tabName] : [];
-                $tabData = $this->getTabElement($tabName)->getDataFormTab($tabFields, $this->_rootElement);
+                $tabData = $this->getTabElement($tabName)->getDataFormTab($fields, $this->_rootElement);
                 $data = array_merge($data, $tabData);
             }
         }
@@ -289,7 +288,7 @@ class FormTabs extends Form
     protected function getTabElement($tabName)
     {
         $tabClass = $this->tabs[$tabName]['class'];
-        /** @var $tabElement Tab */
+        /** @var Tab $tabElement */
         $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 ad48d1e9ff26fb6662c272753ae9d0c021fe9c58..7d9b5ba21680bb8762758b9488568ffd8cbb2ddb 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
@@ -319,6 +319,7 @@ abstract class Grid extends Block
         $sortBlock = $this->_rootElement->find(sprintf($this->sortLink, $field, $sort));
         if ($sortBlock->isVisible()) {
             $sortBlock->click();
+            $this->getTemplateBlock()->waitLoader();
         }
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ccc06a5de2fd8120caed05d12863e4cfbdc7115
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.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\Backend\Test\Handler;
+
+use Mtf\Util\Protocol\CurlInterface;
+use Mtf\Util\Protocol\CurlTransport;
+use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
+use Mtf\System\Config;
+
+/**
+ * Class Extractor
+ * Used to omit possible issue, when searched Id is not on the same page in cURL response
+ */
+class Extractor
+{
+    /**
+     * Pattern for searching grid table in cURL response
+     *
+     * @var string
+     */
+    protected $regExpPattern;
+
+    /**
+     * Url of cURL request
+     *
+     * @var string
+     */
+    protected $url;
+
+    /**
+     * Setting all Pagination params for Pagination object.
+     * Required url for cURL request and regexp pattern for searching in cURL response.
+     *
+     * @param string $url
+     * @param string $regExpPattern
+     */
+    public function __construct($url, $regExpPattern)
+    {
+        $this->url = $url;
+        $this->regExpPattern = $regExpPattern;
+    }
+
+    /**
+     * Retrieves data from cURL response
+     *
+     * @throws \Exception
+     * @return array
+     */
+    public function getData()
+    {
+        $url = $_ENV['app_backend_url'] . $this->url;
+        $curl = new BackendDecorator(new CurlTransport(), new Config);
+        $curl->addOption(CURLOPT_HEADER, 1);
+        $curl->write(CurlInterface::POST, $url, '1.0');
+        $response = $curl->read();
+        $curl->close();
+        preg_match($this->regExpPattern, $response, $matches);
+
+        if (count($matches) == 0) {
+            throw new \Exception('Matches array can\'t be empty.');
+        }
+        return $matches;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfig.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfig.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb02f962208af8232b7bd7ca361c8c11e292dd8b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfig.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\Backend\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class SystemConfig
+ */
+class SystemConfig extends BackendPage
+{
+    const MCA = 'admin/system_config';
+
+    protected $_blocks = [
+        'pageActions' => [
+            'name' => 'pageActions',
+            'class' => 'Magento\Backend\Test\Block\System\Config\PageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'form' => [
+            'name' => 'form',
+            'class' => 'Magento\Backend\Test\Block\System\Config\Form',
+            'locator' => '#config-edit-form',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Backend\Test\Block\System\Config\PageActions
+     */
+    public function getPageActions()
+    {
+        return $this->getBlockInstance('pageActions');
+    }
+
+    /**
+     * @return \Magento\Backend\Test\Block\System\Config\Form
+     */
+    public function getForm()
+    {
+        return $this->getBlockInstance('form');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfig.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfig.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ea51fba834096126f939fe1f22b4b034390679bf
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Adminhtml/SystemConfig.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/system_config" >
+    <block>
+        <name>pageActions</name>
+        <class>Magento\Backend\Test\Block\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>form</name>
+        <class>Magento\Backend\Test\Block\System\Config\Form</class>
+        <locator>#config-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/Backend/Test/Page/System/Config.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/System/Config.php
deleted file mode 100644
index e61502fe4aa067164896919323d9a5b3c2640217..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/System/Config.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-/**
- * Store configuration form page
- *
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 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\Page\System;
-
-use Magento\Backend\Test\Block\System\Config\Switcher;
-use Magento\Core\Test\Block\Messages;
-use Mtf\Client\Element\Locator;
-use Mtf\Factory\Factory;
-use Mtf\Page\Page;
-
-class Config extends Page
-{
-    /**
-     * Url
-     */
-    const MCA = 'admin/system_config';
-
-    /**
-     * Config Edit form selector
-     *
-     * @var string
-     */
-    protected $form = '#config-edit-form';
-
-    /**
-     * Page actions selector
-     *
-     * @var string
-     */
-    protected $pageActions = '.page-main-actions';
-
-    /**
-     * Messages selector
-     *
-     * @var string
-     */
-    protected $messages = '#messages';
-
-    /**
-     * Constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_backend_url'] . self::MCA;
-    }
-
-    /**
-     * Retrieve form block
-     *
-     * @return \Magento\Backend\Test\Block\System\Config\Form
-     */
-    public function getForm()
-    {
-        return Factory::getBlockFactory()->getMagentoBackendSystemConfigForm($this->_browser->find($this->form));
-    }
-
-    /**
-     * Retrieve page actions block
-     *
-     * @return \Magento\Backend\Test\Block\System\Config\PageActions
-     */
-    public function getPageActions()
-    {
-        return Factory::getBlockFactory()->getMagentoBackendSystemConfigPageActions(
-            $this->_browser->find($this->pageActions)
-        );
-    }
-
-    /**
-     * Retrieve messages block
-     *
-     * @return Messages
-     */
-    public function getMessagesBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messages));
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/etc/global/page.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9085814b562432a3a061319b8cfb56bc089a6357
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/etc/global/page.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page>
+    <config>
+        <mca>admin/system_config</mca>
+        <area>adminhtml</area>
+        <class>Magento\Backend\Test\Page\Adminhtml\SystemConfig</class>
+    </config>
+</page>
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
index ac327030fc2fdbb5ffb6e2e7959d3e16532f16c8..c1694c281b9054acb8462e2d21a73afbe22623e7 100644
--- 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
@@ -88,14 +88,14 @@ class Form extends FormTabs
      *
      * @var string
      */
-    protected $advancedTabPanel = '[role="tablist"] [role="tabpanel"][aria-expanded="true"]:not("overflow")';
+    protected $advancedTabPanel = './/*[role="tablist"]//ul[!contains(@style,"overflow")]';
 
     /**
-     * Locator status of products
+     * CSS locator button status of the product
      *
      * @var string
      */
-    protected $onlineSwitcher = '#product-online-switcher + [for="product-online-switcher"]';
+    protected $onlineSwitcher = '#product-online-switcher%s + [for="product-online-switcher"]';
 
     /**
      * Category fixture
@@ -112,13 +112,25 @@ class Form extends FormTabs
      * @param Element $element
      * @return $this
      */
-    public function fillProduct(FixtureInterface $fixture, CatalogCategoryEntity $category = null, Element $element = null)
-    {
+    public function fillProduct(
+        FixtureInterface $fixture,
+        CatalogCategoryEntity $category = null,
+        Element $element = null
+    ) {
         $this->category = $category;
         $this->fillCategory($fixture);
-        if ($fixture instanceof InjectableFixture && $fixture->getStatus() === 'Product offline') {
-            $this->_rootElement->find($this->onlineSwitcher)->click();
+
+        if ($fixture instanceof InjectableFixture) {
+            $status = $fixture->getStatus();
+            if (($status === 'Product offline'
+                && $this->_rootElement->find(sprintf($this->onlineSwitcher, ':checked'))->isVisible())
+                || ($status === 'Product online'
+                && $this->_rootElement->find(sprintf($this->onlineSwitcher, ':not(:checked)'))->isVisible())
+            ) {
+                $this->_rootElement->find(sprintf($this->onlineSwitcher, ''))->click();
+            }
         }
+
         return parent::fill($fixture, $element);
     }
 
@@ -152,7 +164,7 @@ class Form extends FormTabs
             $categoryName = $this->category->getName();
         }
         if (empty($categoryName) && !($fixture instanceof InjectableFixture)) {
-                $categoryName = $fixture->getCategoryName();
+            $categoryName = $fixture->getCategoryName();
         }
         if (empty($categoryName)) {
             return;
@@ -268,11 +280,11 @@ class Form extends FormTabs
         $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
+        $advancedTabList = $this->advancedTabList;
         $this->_rootElement->waitUntil(
             function () use ($rootElement, $advancedTabList) {
                 return $rootElement->find($advancedTabList)->isVisible();
@@ -287,12 +299,17 @@ class Form extends FormTabs
             $tabPanel = $this->advancedTabPanel;
             $this->_rootElement->waitUntil(
                 function () use ($rootElement, $tabPanel) {
-                    return $rootElement->find($tabPanel)->isVisible();
+                    return $rootElement->find($tabPanel, Locator::SELECTOR_XPATH)->isVisible();
                 }
             );
             // Wait until needed tab will appear
             $this->_rootElement->waitUntil(
-                function () use ($rootElement, $selector, $strategy) {
+                function () use ($rootElement, $selector, $strategy, $tabPanel) {
+                    $this->_rootElement->waitUntil(
+                        function () use ($rootElement, $tabPanel) {
+                            return $rootElement->find($tabPanel, Locator::SELECTOR_XPATH)->isVisible();
+                        }
+                    );
                     return $rootElement->find($selector, $strategy)->isVisible();
                 }
             );
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
index fc1169c2d07dc26f596aa2c22b16e150f7d8e602..b488bff8a9092fdbae306713ede23c8ec065f6cb 100644
--- 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
@@ -85,6 +85,13 @@
             <inventory_qty>
                 <selector>[name='product[stock_data][qty]']</selector>
             </inventory_qty>
+            <stock_data_use_config_min_qty>
+                <selector>[name='product[stock_data][use_config_min_qty]']</selector>
+                <input>checkbox</input>
+            </stock_data_use_config_min_qty>
+            <stock_data_min_qty>
+                <selector>[name='product[stock_data][min_qty]']</selector>
+            </stock_data_min_qty>
         </fields>
     </advanced-inventory>
     <autosettings>
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
index 55376f2f69d1654f09e0bbf6cd39e2243ac86d83..316afd6e097f425dc4b73a7717dfb80322ab0fc3 100644
--- 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
@@ -27,7 +27,7 @@ namespace Magento\Catalog\Test\Block\Adminhtml\Product;
 use Magento\Backend\Test\Block\Widget\Grid as ParentGrid;
 
 /**
- * Class ProductGrid
+ * Class Grid
  * Backend catalog product grid
  */
 class Grid extends ParentGrid
@@ -35,24 +35,24 @@ class Grid extends ParentGrid
     /**
      * Initialize block elements
      */
-    protected $filters = array(
-        'name' => array(
+    protected $filters = [
+        'name' => [
             'selector' => '#productGrid_product_filter_name'
-        ),
-        'sku' => array(
+        ],
+        'sku' => [
             'selector' => '#productGrid_product_filter_sku'
-        ),
-        'type' => array(
+        ],
+        'type' => [
             'selector' => '#productGrid_product_filter_type',
             'input' => 'select'
-        ),
-        'price_from' => array(
+        ],
+        'price_from' => [
             'selector' => '#productGrid_product_filter_price_from'
-        ),
-        'price_to' => array(
+        ],
+        'price_to' => [
             'selector' => '#productGrid_product_filter_price_to'
-        )
-    );
+        ]
+    ];
 
     /**
      * Update attributes for selected items
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
index f1e7ce1b27a75707187ab0ad10a08ee988bea454..8bbdb92f1e0507cfbf7f90f15e0aaa6019d28851 100644
--- 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
@@ -27,7 +27,7 @@ namespace Magento\Catalog\Test\Block\Product\ProductList;
 use Mtf\Block\Block;
 
 /**
- * Class ProductPagination
+ * Class Toolbar
  * Toolbar the product list page
  */
 class Toolbar extends Block
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 f03aa6d5e63dce1e45e88dcba4a0374f9be505d4..eb37a68a232deab062e7445e545ae412a2deef25 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
@@ -238,8 +238,9 @@ class View extends Block
      */
     public function getProductPriceBlock()
     {
-        return Factory::getBlockFactory()->getMagentoCatalogProductPrice(
-            $this->_rootElement->find($this->priceBlockClass, Locator::SELECTOR_CLASS_NAME)
+        return $this->blockFactory->create(
+            'Magento\Catalog\Test\Block\Product\Price',
+            ['element' => $this->_rootElement->find($this->priceBlockClass, Locator::SELECTOR_CLASS_NAME)]
         );
     }
 
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 24029a7351bbc0eb387bf3cd9ed69a3a6b20d781..ec26a9203f0eaf8b5af8cd39c89113f11958c64c 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
@@ -33,6 +33,20 @@ use Mtf\Client\Element\Locator;
  */
 class Search extends Block
 {
+    /**
+     * Selector matches found - "Suggest Search"
+     *
+     * @var string
+     */
+    protected $searchAutocomplete = './/div[@id="search_autocomplete"]//li[text()="%s"]';
+
+    /**
+     * Selector number of matches for a given row
+     *
+     * @var string
+     */
+    protected $searchItemAmount = '/span[contains(@class,"amount") and text()="%d"]';
+
     /**
      * Search field
      *
@@ -62,10 +76,21 @@ class Search extends Block
      */
     public function search($keyword)
     {
-        $this->_rootElement->find($this->searchInput, Locator::SELECTOR_CSS)->setValue($keyword);
+        $this->fillSearch($keyword);
         $this->_rootElement->find($this->searchButton, Locator::SELECTOR_CSS)->click();
     }
 
+    /**
+     * Fills the search field
+     *
+     * @param string $text
+     * @return void
+     */
+    public function fillSearch($text)
+    {
+        $this->_rootElement->find($this->searchInput, Locator::SELECTOR_CSS)->setValue($text);
+    }
+
     /**
      * Check that placeholder contains text
      *
@@ -80,4 +105,23 @@ class Search extends Block
         );
         return $field->isVisible();
     }
+
+    /**
+     * Checking block visibility "Suggest Search"
+     *
+     * @param string $text
+     * @param int|null $amount
+     * @return bool
+     */
+    public function isSuggestSearchVisible($text, $amount = null)
+    {
+        $searchAutocomplete = sprintf($this->searchAutocomplete, $text);
+        if ($amount !== null) {
+            $searchAutocomplete .= sprintf($this->searchItemAmount, $amount);
+        }
+
+        $this->waitForElementVisible($searchAutocomplete, Locator::SELECTOR_XPATH);
+        return $this->_rootElement->find($searchAutocomplete, Locator::SELECTOR_XPATH)
+            ->isVisible();
+    }
 }
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
index cfcff41e0c71d4d909da439d4b401a8bc9620c22..6b2726761fd164acded86da7fa844643f79c33d2 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonAbsent.php
@@ -72,7 +72,7 @@ class AssertAddToCartButtonAbsent extends AbstractConstraint
     protected $catalogProductView;
 
     /**
-     * Assert that "Add to cart" button is not display on page.
+     * Assert that "Add to cart" button is not display on page
      *
      * @param CmsIndex $cmsIndex
      * @param CatalogCategoryView $catalogCategoryView
@@ -127,7 +127,7 @@ class AssertAddToCartButtonAbsent extends AbstractConstraint
         $this->catalogCategoryView->getListProductBlock()->openProductViewPage($this->product->getName());
         \PHPUnit_Framework_Assert::assertFalse(
             $this->catalogProductView->getViewBlock()->checkAddToCardButton(),
-            "Button 'Add to Card' is present on Product page"
+            "Button 'Add to Card' is present on 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
index 2cca302e251376a35c932c12f2f04674fbe65b8b..f4ac24bc1c39d48ee8ae343699a4fdd64d520110 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertAddToCartButtonPresent.php
@@ -72,7 +72,7 @@ class AssertAddToCartButtonPresent extends AbstractConstraint
     protected $catalogProductView;
 
     /**
-     * Assert that "Add to cart" button is present on page.
+     * Assert that "Add to cart" button is present on page
      *
      * @param CmsIndex $cmsIndex
      * @param CatalogCategoryView $catalogCategoryView
@@ -109,7 +109,7 @@ class AssertAddToCartButtonPresent extends AbstractConstraint
         );
         \PHPUnit_Framework_Assert::assertTrue(
             $this->catalogCategoryView->getListProductBlock()->checkAddToCardButton(),
-            "Button 'Add to Card' is absent on Category page"
+            "Button 'Add to Card' is absent on Category page."
         );
     }
 
@@ -127,7 +127,7 @@ class AssertAddToCartButtonPresent extends AbstractConstraint
         $this->catalogCategoryView->getListProductBlock()->openProductViewPage($this->product->getName());
         \PHPUnit_Framework_Assert::assertTrue(
             $this->catalogProductView->getViewBlock()->checkAddToCardButton(),
-            "Button 'Add to Card' is absent on Product page"
+            "Button 'Add to Card' is absent on Product 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
index 49c2917a8fef1131ddb2c558480b56501d080219..95e1ef295df99e7d3e467ede042777b58d11947f 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCustomOptionsOnProductPage.php
@@ -30,8 +30,6 @@ use Magento\Catalog\Test\Page\Product\CatalogProductView;
 
 /**
  * Class AssertCustomOptionsOnProductPage
- *
- * @package Magento\Catalog\Test\Constraint
  */
 class AssertCustomOptionsOnProductPage extends AbstractConstraint
 {
@@ -63,47 +61,30 @@ class AssertCustomOptionsOnProductPage extends AbstractConstraint
         // Open product view page
         $catalogProductView->init($this->product);
         $catalogProductView->open();
+        // Prepare data
         $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);
+        foreach ($customOptions as &$option) {
+            unset($option['value']);
         }
+        unset($option);
+        $compareOptions = $this->prepareOptionArray($this->product->getCustomOptions());
+        $customOptions = $this->dataSortByKey($customOptions);
+        $compareOptions = $this->dataSortByKey($compareOptions);
 
-        \PHPUnit_Framework_Assert::assertTrue(
-            $noError,
+        \PHPUnit_Framework_Assert::assertEquals(
+            $customOptions,
+            $compareOptions,
             '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)
+    protected function dataSortByKey(array $data)
     {
-        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;
-            }
+        foreach ($data as &$item) {
+            ksort($item);
         }
-
-        return true;
+        unset($item);
+        return $data;
     }
 
     /**
@@ -116,12 +97,13 @@ class AssertCustomOptionsOnProductPage extends AbstractConstraint
     {
         $result = [];
         $productPrice = $this->product->hasData('group_price')
-            ? $this->product->getPrice()
-            : $this->product->getGroupPrice()[0]['price'];
+            ? $this->product->getGroupPrice()[0]['price']
+            : $this->product->getPrice();
 
         $placeholder = ['Yes' => true, 'No' => false];
         foreach ($options as $option) {
             $result[$option['title']]['is_require'] = $placeholder[$option['is_require']];
+            $result[$option['title']]['title'] = $option['title'];
             $result[$option['title']]['price'] = [];
             foreach ($option['options'] as $optionValue) {
                 if ($optionValue['price_type'] === 'Percent') {
@@ -135,7 +117,7 @@ class AssertCustomOptionsOnProductPage extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * Returns a string representation of the object
      *
      * @return string
      */
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
index f6b68f85742cd858c1a4c4130ecf15af9c4c52d2..0e364e2975f53b7a04153550b4974f2afbf98207 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertGroupedPriceOnProductPage.php
@@ -53,8 +53,10 @@ class AssertGroupedPriceOnProductPage extends AbstractConstraint
         $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'])) {
+        $groupPrice = isset($groupPrice['price_special_price'])
+            ? $groupPrice['price_special_price']
+            : null;
+        if (isset($fields['group_price'])) {
             foreach ($fields['group_price'] as $itemGroupPrice) {
                 \PHPUnit_Framework_Assert::assertEquals(
                     $itemGroupPrice['price'],
@@ -66,7 +68,7 @@ class AssertGroupedPriceOnProductPage extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * Returns a string representation of the object
      *
      * @return string
      */
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
index d02f71f0fbbe74c8df40059b3adee3bb8b35a76e..414472c7caa75acc435cbb510db70ca3643b5527 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductForm.php
@@ -86,7 +86,7 @@ class AssertProductForm extends AbstractConstraint
         $errors = $this->compareArray($fixtureData, $formData);
         \PHPUnit_Framework_Assert::assertTrue(
             empty($errors),
-            "These data must be equal to each other:\n" . implode("\n - ", $errors)
+            "These data must be equal to each other:\n" . implode("\n", $errors)
         );
     }
 
@@ -115,7 +115,6 @@ class AssertProductForm extends AbstractConstraint
             },
             $this->formattingOptions
         );
-        unset($compareData['url_key']);
 
         return $compareData;
     }
@@ -132,7 +131,7 @@ class AssertProductForm extends AbstractConstraint
         $errors = [];
         $keysDiff = array_diff(array_keys($fixtureData), array_keys($formData));
         if (!empty($keysDiff)) {
-            return ['fixture data do not correspond to form data in composition'];
+            return ['- fixture data do not correspond to form data in composition.'];
         }
 
         foreach ($fixtureData as $key => $value) {
@@ -156,7 +155,7 @@ class AssertProductForm extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * Returns a string representation of the object
      *
      * @return string
      */
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 9ea5b041805185337ddf80218b2665c15d337b0a..e72639796d61a7cff6513069a27b51d67c355689 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
@@ -54,7 +54,7 @@ class AssertProductInCart extends AbstractConstraint
         FixtureInterface $product,
         CheckoutCart $checkoutCart
     ) {
-        //Add product to cart
+        // Add product to cart
         $catalogProductView->init($product);
         $catalogProductView->open();
         $productOptions = $product->getCustomOptions();
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 477d4a5195735fa8317094b1269df72d4feaec9a..5dd30e4ca1c04044ce7e6532b89fa4301461b89d 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
@@ -57,7 +57,7 @@ class AssertProductInCategory extends AbstractConstraint
         FixtureInterface $product,
         CatalogCategoryEntity $category
     ) {
-        //Open category view page and check visible product
+        // Open category view page and check visible product
         $cmsIndex->open();
         $cmsIndex->getTopmenu()->selectCategoryByName($category->getName());
 
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 0b069ffcaff421e3f03344b5c964f882c346fa56..7b1a718a69e5e1f70dac0b435ebcc356cd72c58f 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
@@ -58,7 +58,7 @@ class AssertProductInGrid extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * Returns a string representation of the object
      *
      * @return string
      */
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 ebfff102de1dc69f6fac10dc3c98cdac0d8001cb..88af87b1409a5472d81a1832f7330bb4ff731029 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
@@ -65,7 +65,7 @@ class AssertProductInStock extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * Returns a string representation of the object
      *
      * @return string
      */
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php
index 7776d97ccdb2d4ef2aa4a7cf1ff514248d545350..5efd08e691efe7979ba360442cd71194166c81fb 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php
@@ -76,13 +76,13 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint
 
         if ($titleBlock->getTitle() !== self::NOT_FOUND_MESSAGE) {
             $errors[] = '- the headline on the page does not match, the text should be -> "'
-                . self::NOT_FOUND_MESSAGE . '"';
+                . self::NOT_FOUND_MESSAGE . '".';
         }
 
         $cmsIndex->open();
         $cmsIndex->getSearchBlock()->search($product->getSku());
         if ($catalogSearchResult->getListProductBlock()->isProductVisible($product->getName())) {
-            $errors[] = '- successful product search';
+            $errors[] = '- successful product search.';
         }
 
         $cmsIndex->open();
@@ -93,7 +93,7 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint
         }
 
         if ($isProductVisible) {
-            $errors[] = '- product found in this category';
+            $errors[] = '- product found in this category.';
         }
 
         \PHPUnit_Framework_Assert::assertTrue(
@@ -104,7 +104,7 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * 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 bda4162dc0647a9b685565b33e4bbe525216e043..7d340ceddbce8c86d3c1660b1a1da49da816235c 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
@@ -46,7 +46,7 @@ class AssertProductOutOfStock extends AbstractConstraint
     const STOCK_AVAILABILITY = 'Out of stock';
 
     /**
-     * Assert  that Out of Stock status is displayed on product page
+     * Assert that Out of Stock status is displayed on product page
      *
      * @param CatalogProductView $catalogProductView
      * @param FixtureInterface $product
@@ -64,7 +64,7 @@ class AssertProductOutOfStock extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * 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
index 90d03847b8e8ee5f0cfa7565cbae88f10d8f0b94..52f18eade7d156322bfce35e6c581ffa7288c7b7 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductPage.php
@@ -143,7 +143,7 @@ class AssertProductPage extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * Returns a string representation of the object
      *
      * @return string
      */
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 630fad6e5bfad817745a1e3cd1df038cc1e6cd13..7316ea2c1e39b7be3c5645189a79572453b05111 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
@@ -53,10 +53,10 @@ class AssertProductSearchableBySku extends AbstractConstraint
      *
      * @var string
      */
-    protected $successfulMessage = 'Product successfully found by SKU';
+    protected $successfulMessage = 'Product successfully found by SKU.';
 
     /**
-     * Assert that product can be searched via Quick Search using searchable product attributes (Search by SKU).
+     * Assert that product can be searched via Quick Search using searchable product attributes (Search by SKU)
      *
      * @param CatalogsearchResult $catalogSearchResult
      * @param CmsIndex $cmsIndex
@@ -73,8 +73,8 @@ class AssertProductSearchableBySku extends AbstractConstraint
 
         if ($product->getVisibility() === 'Catalog' || $product->getQuantityAndStockStatus() === 'Out of Stock') {
             $isVisible = !($catalogSearchResult->getListProductBlock()->isProductVisible($product->getName()));
-            $this->errorMessage = 'Product successfully found by SKU';
-            $this->successfulMessage = 'The product has not been found by SKU';
+            $this->errorMessage = 'Product successfully found by SKU.';
+            $this->successfulMessage = 'The product has not been found by SKU.';
         } else {
             $isVisible = $catalogSearchResult->getListProductBlock()->isProductVisible($product->getName());
         }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSkuAutoGenerated.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSkuAutoGenerated.php
index c8e30f4c41e4862c5c12a0d7942699e87593116c..f43094d78dcf3720bed06fe12e721264d08aa673 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSkuAutoGenerated.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSkuAutoGenerated.php
@@ -58,12 +58,12 @@ class AssertProductSkuAutoGenerated extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * Returns a string representation of the object
      *
      * @return string
      */
     public function toString()
     {
-        return 'Sku successfully generated';
+        return 'Sku successfully generated.';
     }
 }
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 de868e8d8a941ba278ac6ef4031fc53cff404f71..36268f5db5f3a40451e4f83fd68f148dcc2d661a 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
@@ -82,8 +82,8 @@ class AssertProductVisibleInCategory extends AbstractConstraint
 
         if ($product->getVisibility() === 'Search' || $product->getQuantityAndStockStatus() === 'Out of Stock') {
             $isProductVisible = !$isProductVisible;
-            $this->errorMessage = 'Product found in this category';
-            $this->successfulMessage = 'Asserts that the product could not be found in this category';
+            $this->errorMessage = 'Product found in this category.';
+            $this->successfulMessage = 'Asserts that the product could not be found in this category.';
         }
 
         \PHPUnit_Framework_Assert::assertTrue(
@@ -93,7 +93,7 @@ class AssertProductVisibleInCategory extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * 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
index 3bdec2b01e2bfa13d740cfcc112f2fc57b4f2b05..aa17ed49c67a0efc500eac2e9e2e31805e54a29d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertSpecialPriceOnProductPage.php
@@ -53,8 +53,10 @@ class AssertSpecialPriceOnProductPage extends AbstractConstraint
         $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'])) {
+        $specialPrice = (isset($specialPrice['price_special_price']))
+            ? $specialPrice['price_special_price']
+            : null;
+        if (isset($fields['special_price'])) {
             \PHPUnit_Framework_Assert::assertEquals(
                 $fields['special_price'],
                 $specialPrice,
@@ -64,12 +66,12 @@ class AssertSpecialPriceOnProductPage extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * 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";
+        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
index a7642631be0b996add74cedaa7206c56b4b82a45..221acb64db489e4548def865d77c4c0ead4aca1a 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertTierPriceOnProductPage.php
@@ -92,12 +92,12 @@ class AssertTierPriceOnProductPage extends AbstractConstraint
     }
 
     /**
-     * Returns a string representation of the object.
+     * Returns a string representation of the object
      *
      * @return string
      */
     public function toString()
     {
-        return 'Tier price is displayed on the product page';
+        return 'Tier price is displayed on the product page.';
     }
 }
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 65bbb63233883c51a8c8f6706dc7742c77445083..e4422708a4ecbc623a18450166376b8ea27a363d 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
@@ -92,9 +92,11 @@ class CatalogProductSimple extends InjectableFixture
     protected $defaultDataSet = [
         'name' => 'Test simple product %isolation%',
         'sku' => 'test_simple_sku_%isolation%',
+        'attribute_set_id' => 'Default',
         'price' => ['value' => 100.00],
         'weight' => 12.0000,
-        'qty' => 10
+        'qty' => 10,
+        'quantity_and_stock_status' => 'In Stock',
     ];
 
     protected $category_ids = [
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 b1aec4809ba0c59c7f3ea5d79b81aaec6c2cf571..3750cbc12c754d4cd63b34c9531836e3c6a662fb 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
@@ -216,6 +216,62 @@ class CustomOptions implements FixtureInterface
                         ]
                     ]
                 ]
+            ],
+            'default' => [
+                [
+                    'title' => 'custom option drop down',
+                    'is_require' => 'Yes',
+                    'type' => 'Drop-down',
+                    'options' => [
+                        [
+                            'title' => '10 percent',
+                            'price' => 10,
+                            'price_type' => 'Percent',
+                            'sku' => 'sku_drop_down_row_1'
+                        ]
+                    ]
+                ],
+                [
+                    'title' => 'custom option drop down2',
+                    'is_require' => 'Yes',
+                    'type' => 'Drop-down',
+                    'options' => [
+                        [
+                            'title' => '20 percent',
+                            'price' => 20,
+                            'price_type' => 'Percent',
+                            'sku' => 'sku_drop_down_row_2'
+                        ]
+                    ]
+                ]
+            ],
+            'two_options' => [
+                [
+                    'title' => 'custom option drop down',
+                    'is_require' => 'Yes',
+                    'type' => 'Drop-down',
+                    'options' => [
+                        [
+                            'title' => '10 percent',
+                            'price' => 10,
+                            'price_type' => 'Percent',
+                            'sku' => 'sku_drop_down_row_1'
+                        ]
+                    ]
+                ],
+                [
+                    'title' => 'custom option drop down2',
+                    'is_require' => 'Yes',
+                    'type' => 'Drop-down',
+                    'options' => [
+                        [
+                            'title' => '20 percent',
+                            'price' => 20,
+                            'price_type' => 'Percent',
+                            'sku' => 'sku_drop_down_row_2'
+                        ]
+                    ]
+                ]
             ]
         ];
         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 38d0010f5228d3bbc826c7a092dfcb91012263b2..0964f7e4330ed53772fee4d532a8e8a361b2e763 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
@@ -105,6 +105,13 @@ class GroupPriceOptions implements FixtureInterface
                     'website' => 'All Websites [USD]',
                     'customer_group' => 'NOT LOGGED IN'
                 ]
+            ],
+            'default' => [
+                [
+                    'price' => 20,
+                    'website' => 'All Websites [USD]',
+                    'customer_group' => 'NOT LOGGED IN'
+                ]
             ]
         ];
         if (!isset($presets[$name])) {
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 7bcaacf689eb8fde6dab8f8173162775432a8fc0..b01de338626790f963e8d0956312d40513221f93 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
@@ -38,11 +38,54 @@ use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
  */
 class Curl extends AbstractCurl implements CatalogProductSimpleInterface
 {
+    /**
+     * Placeholder for data sent Curl
+     *
+     * @var array
+     */
+    protected $placeholderData = [
+        'manage_stock' => [
+            'Yes' => 1,
+            'No' => 0
+        ],
+        'is_virtual' => [
+            'Yes' => 1
+        ],
+        'inventory_manage_stock' => [
+            'Yes' => 1,
+            'No' => 0
+        ],
+        'quantity_and_stock_status' => [
+            'In Stock' => 1,
+            'Out of Stock' => 0
+        ],
+        'visibility' => [
+            'Not Visible Individually' => 1,
+            'Catalog' => 2,
+            'Search' => 3,
+            'Catalog, Search' => 4
+        ],
+        'tax_class_id' => [
+            'None' => 0,
+            'Taxable Goods' => 2
+        ],
+        'website_ids' => [
+            'Main Website' => 1
+        ],
+        'status' => [
+            'Product offline' => 2,
+            'Product online' => 1
+        ],
+        'attribute_set_id' => [
+            'Default' => 4
+        ]
+    ];
+
     /**
      * Post request for creating simple product
      *
      * @param FixtureInterface $fixture [optional]
-     * @return mixed|string
+     * @return array
      * @throws \Exception
      */
     public function persist(FixtureInterface $fixture = null)
@@ -52,6 +95,17 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
         // @todo remove "if" when fixtures refactored
         if ($fixture instanceof InjectableFixture) {
             $fields = $fixture->getData();
+            // Apply a placeholder for data
+            array_walk_recursive(
+                $fields,
+                function (&$item, $key, $placeholder) {
+                    $item = isset($placeholder[$key][$item]) ? $placeholder[$key][$item] : $item;
+                },
+                $this->placeholderData
+            );
+
+            $fields = $this->prepareStockData($fields);
+
             if ($prefix) {
                 $data[$prefix] = $fields;
             } else {
@@ -79,6 +133,54 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
         return ['id' => $id];
     }
 
+    /**
+     * Preparation of stock data
+     *
+     * @param array $fields
+     * @return array
+     */
+    protected function prepareStockData(array $fields)
+    {
+        $fields['stock_data']['manage_stock'] = 0;
+
+        if (empty($fields['stock_data']['is_in_stock'])) {
+            $fields['stock_data']['is_in_stock'] = isset($fields['quantity_and_stock_status'])
+                ? $fields['quantity_and_stock_status']
+                : (isset($fields['inventory_manage_stock']) ? $fields['inventory_manage_stock'] : null);
+        }
+        if (empty($fields['stock_data']['qty'])) {
+            $fields['stock_data']['qty'] = isset($fields['qty']) ? $fields['qty'] : null;
+        }
+        if (!empty($fields['stock_data']['qty']) || !empty($fields['stock_data']['is_in_stock'])) {
+            $fields['stock_data']['manage_stock'] = 1;
+        }
+
+        $fields['quantity_and_stock_status'] = [
+            'qty' => $fields['stock_data']['qty'],
+            'is_in_stock' => $fields['stock_data']['is_in_stock']
+        ];
+
+        return $this->filter($fields);
+    }
+
+    /**
+     * Remove items from a null
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function filter(array $data)
+    {
+        foreach ($data as $key => $value) {
+            if ($value === null) {
+                unset($data[$key]);
+            } elseif (is_array($data[$key])) {
+                $data[$key] = $this->filter($data[$key]);
+            }
+        }
+        return $data;
+    }
+
     /**
      * Prepare POST data for creating product request
      *
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 d0376a8e0f048e35d5e0a2856aa64136f30d561a..825424bcce1c449eb72dc7356360a4ce18f36a97 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
@@ -58,7 +58,7 @@ class CatalogCategoryView extends FrontendPage
             'class' => 'Magento\Catalog\Test\Block\Product\ProductList\Toolbar',
             'locator' => '.pages .items',
             'strategy' => 'css selector',
-        ],
+        ]
     ];
 
     /**
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 0b047f6fae11bc458f9081f45d275385e4d460ac..8e0b3d43f38f94de3fb6b4c8347648fc5155a350 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
@@ -29,10 +29,14 @@ use Mtf\Fixture\FixtureInterface;
 
 /**
  * Class CatalogProductView
+ *
  * Frontend product view page
  */
 class CatalogProductView extends FrontendPage
 {
+    /**
+     * URL for catalog product grid
+     */
     const MCA = 'catalog/product/view';
 
     protected $_blocks = [
@@ -90,12 +94,6 @@ class CatalogProductView extends FrontendPage
             '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',
@@ -105,15 +103,13 @@ class CatalogProductView extends FrontendPage
         'titleBlock' => [
             'name' => 'titleBlock',
             'class' => 'Magento\Theme\Test\Block\Html\Title',
-            'locator' => '.page.title h1.title',
+            'locator' => '.page.title',
             'strategy' => 'css selector',
         ]
     ];
 
     /**
      * Custom constructor
-     *
-     * @return void
      */
     protected function _init()
     {
@@ -132,6 +128,8 @@ class CatalogProductView extends FrontendPage
     }
 
     /**
+     * Get product view block
+     *
      * @return \Magento\Catalog\Test\Block\Product\View
      */
     public function getViewBlock()
@@ -140,6 +138,8 @@ class CatalogProductView extends FrontendPage
     }
 
     /**
+     * Get product options block
+     *
      * @return \Magento\Catalog\Test\Block\Product\View\CustomOptions
      */
     public function getCustomOptionsBlock()
@@ -203,14 +203,6 @@ class CatalogProductView extends FrontendPage
         return $this->getBlockInstance('crosssellBlock');
     }
 
-    /**
-     * @return \Magento\Downloadable\Test\Block\Catalog\Product\Links
-     */
-    public function getDownloadableLinksBlock()
-    {
-        return $this->getBlockInstance('downloadableLinksBlock');
-    }
-
     /**
      * @return \Magento\Catalog\Test\Block\Product\Price
      */
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 5e506ad74a314c13325cfe29c49b6927dfa3692d..a80d41a60332fcc4e9a595139a72e1b6b4cf75c9 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
@@ -72,13 +72,15 @@ class CatalogProductSimple extends AbstractRepository
             'category_ids' => ['presets' => 'default_subcategory']
         ];
 
-        $this->_data['product_without_category'] = [
-            'sku' => 'simple_product_without_category_%isolation%',
-            'name' => 'Simple product without category %isolation%',
+        $this->_data['default'] = [
             'type_id' => 'simple',
-            'attribute_set_id' => '4',
-            'price' => ['value' => 100, 'preset' => '-'],
-            'category_ids' => ['presets' => null]
+            'attribute_set_id' => 'Default',
+            'name' => 'Simple Product %isolation%',
+            'sku' => 'sku_simple_product_%isolation%',
+            'weight' => 1,
+            'quantity_and_stock_status' => 'In Stock',
+            'qty' => 25,
+            'price' => ['value' => 560, 'preset' => '-'],
         ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateProductSimpleEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php
similarity index 90%
rename from dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateProductSimpleEntityTest.php
rename to dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php
index b69d1115890bde211de8ee383a63b237bb290a3a..471371161634150e0dd3d8700c28d32e58020b2d 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateProductSimpleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest.php
@@ -38,7 +38,7 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
  *
  * Precondition:
  * Category is created.
- * Product is created.
+ * Product is created and assigned to created category.
  *
  * Steps:
  * 1. Login to backend.
@@ -46,12 +46,12 @@ use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
  * 3. Select a product in the grid.
  * 4. Edit test value(s) according to dataset.
  * 5. Click "Save".
- * 6. Perform asserts
+ * 6. Perform asserts.
  *
  * @group Products_(CS)
  * @ZephyrId MAGETWO-23544
  */
-class UpdateProductSimpleEntityTest extends Injectable
+class UpdateSimpleProductEntityTest extends Injectable
 {
     /**
      * Simple product fixture
@@ -75,32 +75,41 @@ class UpdateProductSimpleEntityTest extends Injectable
     protected $editProductPage;
 
     /**
-     * Category fixture
+     * Prepare data
      *
-     * @var CatalogCategoryEntity
+     * @param CatalogCategoryEntity $category
+     * @return array
      */
-    protected $category;
+    public function __prepare(CatalogCategoryEntity $category)
+    {
+        $category->persist();
+        return [
+            'category' => $category
+        ];
+    }
 
     /**
      * Injection data
      *
      * @param CatalogProductIndex $productGrid
      * @param CatalogProductEdit $editProductPage
+     * @param CatalogCategoryEntity $category
      * @param FixtureFactory $fixtureFactory
      * @return array
      */
     public function __inject(
         CatalogProductIndex $productGrid,
         CatalogProductEdit $editProductPage,
+        CatalogCategoryEntity $category,
         FixtureFactory $fixtureFactory
     ) {
         $this->product = $fixtureFactory->createByCode(
             'catalogProductSimple',
             [
-                'dataSet' => 'product_without_category',
+                'dataSet' => 'default',
                 'data' => [
                     'category_ids' => [
-                        'category' => $this->category
+                        'category' => $category
                     ]
                 ]
             ]
@@ -111,21 +120,6 @@ class UpdateProductSimpleEntityTest extends Injectable
         $this->editProductPage = $editProductPage;
     }
 
-    /**
-     * Prepare data
-     *
-     * @param CatalogCategoryEntity $category
-     * @return array
-     */
-    public function __prepare(CatalogCategoryEntity $category)
-    {
-        $category->persist();
-        $this->category = $category;
-        return [
-            'category' => $category
-        ];
-    }
-
     /**
      * Run update product simple entity test
      *
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateProductSimpleEntityTest/testUpdate.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest/testUpdate.csv
similarity index 100%
rename from dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateProductSimpleEntityTest/testUpdate.csv
rename to dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest/testUpdate.csv
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 58b83ca973f797e5200fd12b06e9122aba669a40..a197598be462d87171a5dfc1aa68bc5156e8fa84 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
@@ -56,7 +56,7 @@
         <require>
             <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
             <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <category class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
+            <category class="Magento\Catalog\Test\Fixture\CatalogCategoryEntity" />
             <product class="Mtf\Fixture\FixtureInterface" />
         </require>
     </assertProductVisibleInCategory>
@@ -74,7 +74,7 @@
             <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
             <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
             <product class="Mtf\Fixture\FixtureInterface" />
-            <category class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
+            <category class="Magento\Catalog\Test\Fixture\CatalogCategoryEntity" />
         </require>
     </assertProductInCategory>
     <assertProductInCart module="Magento_Catalog">
@@ -141,7 +141,7 @@
             <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
             <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
             <product class="Mtf\Fixture\FixtureInterface" />
-            <category class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
+            <category class="Magento\Catalog\Test\Fixture\CatalogCategoryEntity" />
             <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
             <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult" />
         </require>
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSuggestSearchingResult.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSuggestSearchingResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..b59049d3cd94bb2dd783c88fab7f1b1a0a36a743
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertSuggestSearchingResult.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\CatalogSearch\Test\Constraint;
+
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
+
+/**
+ * Class AssertSuggestSearchingResult
+ */
+class AssertSuggestSearchingResult extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Check that after input some text(e.g. product name) into search field, drop-down window is appeared.
+     * Window contains requested entity and number of quantity.
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CatalogSearchQuery $catalogSearch
+     * @return void
+     */
+    public function processAssert(CmsIndex $cmsIndex, CatalogSearchQuery $catalogSearch)
+    {
+        $cmsIndex->open();
+        $searchBlock = $cmsIndex->getSearchBlock();
+
+        $queryText = $catalogSearch->getQueryText();
+        $searchBlock->fillSearch($queryText);
+
+        if ($amount = $catalogSearch->getNumResults()) {
+            $isVisible = $searchBlock->isSuggestSearchVisible($queryText, $amount);
+        } else {
+            $isVisible = $searchBlock->isSuggestSearchVisible($queryText);
+        }
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            $isVisible,
+            'Block "Suggest Search" when searching was not found'
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Asserts window contains requested entity and quantity';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.php
new file mode 100644
index 0000000000000000000000000000000000000000..324f898ee20d7f178888857620e56c850a33b833
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogSearch\Test\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class CatalogSearchQuery
+ */
+class CatalogSearchQuery extends InjectableFixture
+{
+    /**
+     * @var string
+     */
+    protected $repositoryClass = 'Magento\CatalogSearch\Test\Repository\CatalogSearchQuery';
+
+    /**
+     * @var string
+     */
+    protected $handlerInterface = 'Magento\CatalogSearch\Test\Handler\CatalogSearchQuery\CatalogSearchQueryInterface';
+
+    protected $defaultDataSet = [
+        'display_in_terms' => null,
+        'is_active' => null,
+        'updated_at' => null,
+    ];
+
+    protected $query_id = [
+        'attribute_code' => 'query_id',
+        'backend_type' => 'int',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $query_text = [
+        'attribute_code' => 'query_text',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+        'source' => 'Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery\SearchData',
+    ];
+
+    protected $num_results = [
+        'attribute_code' => 'num_results',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $popularity = [
+        'attribute_code' => 'popularity',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $redirect = [
+        'attribute_code' => 'redirect',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $synonym_for = [
+        'attribute_code' => 'synonym_for',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $store_id = [
+        'attribute_code' => 'store_id',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $display_in_terms = [
+        'attribute_code' => 'display_in_terms',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '1',
+        'input' => '',
+    ];
+
+    protected $is_active = [
+        'attribute_code' => 'is_active',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '1',
+        'input' => '',
+    ];
+
+    protected $is_processed = [
+        'attribute_code' => 'is_processed',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $updated_at = [
+        'attribute_code' => 'updated_at',
+        'backend_type' => 'timestamp',
+        'is_required' => '',
+        'default_value' => 'CURRENT_TIMESTAMP',
+        'input' => '',
+    ];
+
+    public function getQueryId()
+    {
+        return $this->getData('query_id');
+    }
+
+    public function getQueryText()
+    {
+        return $this->getData('query_text');
+    }
+
+    public function getNumResults()
+    {
+        return $this->getData('num_results');
+    }
+
+    public function getPopularity()
+    {
+        return $this->getData('popularity');
+    }
+
+    public function getRedirect()
+    {
+        return $this->getData('redirect');
+    }
+
+    public function getSynonymFor()
+    {
+        return $this->getData('synonym_for');
+    }
+
+    public function getStoreId()
+    {
+        return $this->getData('store_id');
+    }
+
+    public function getDisplayInTerms()
+    {
+        return $this->getData('display_in_terms');
+    }
+
+    public function getIsActive()
+    {
+        return $this->getData('is_active');
+    }
+
+    public function getIsProcessed()
+    {
+        return $this->getData('is_processed');
+    }
+
+    public function getUpdatedAt()
+    {
+        return $this->getData('updated_at');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4d8cbd51fec8a05412453fab54ee13b84ff8e9a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery.xml
@@ -0,0 +1,113 @@
+<?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\CatalogSearch\Test\Fixture\CatalogSearchQuery">
+    <module>Magento_CatalogSearch</module>
+    <type>flat</type>
+    <entity_type>catalogsearch_query</entity_type>
+    <collection>Magento\CatalogSearch\Model\Resource\Query\Collection</collection>
+    <fields>
+        <query_id>
+            <attribute_code>query_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input></input>
+        </query_id>
+        <query_text>
+            <attribute_code>query_text</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+            <source>Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery\SearchData</source>
+        </query_text>
+        <num_results>
+            <attribute_code>num_results</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </num_results>
+        <popularity>
+            <attribute_code>popularity</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </popularity>
+        <redirect>
+            <attribute_code>redirect</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </redirect>
+        <synonym_for>
+            <attribute_code>synonym_for</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </synonym_for>
+        <store_id>
+            <attribute_code>store_id</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </store_id>
+        <display_in_terms>
+            <attribute_code>display_in_terms</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>1</default_value>
+            <input></input>
+        </display_in_terms>
+        <is_active>
+            <attribute_code>is_active</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>1</default_value>
+            <input></input>
+        </is_active>
+        <is_processed>
+            <attribute_code>is_processed</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </is_processed>
+        <updated_at>
+            <attribute_code>updated_at</attribute_code>
+            <backend_type>timestamp</backend_type>
+            <is_required></is_required>
+            <default_value>CURRENT_TIMESTAMP</default_value>
+            <input></input>
+        </updated_at>
+    </fields>
+    <repository_class>Magento\CatalogSearch\Test\Repository\CatalogSearchQuery</repository_class>
+    <handler_interface>Magento\CatalogSearch\Test\Handler\CatalogSearchQuery\CatalogSearchQueryInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/SearchData.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/SearchData.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d1f9eedeca68adb3b3aa047751ef26d22e134df
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Fixture/CatalogSearchQuery/SearchData.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+
+/**
+ * Class SearchData
+ * Data to search for
+ */
+class SearchData implements FixtureInterface
+{
+    /**
+     * Resource data
+     *
+     * @var string
+     */
+    protected $data;
+
+    /**
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
+    {
+        $this->params = $params;
+        $explodeValue = explode('::', $data['value']);
+        if (!empty($explodeValue) && count($explodeValue) > 1) {
+            /** @var FixtureInterface $fixture */
+            $fixture = $fixtureFactory->createByCode($explodeValue[0]);
+            $fixture->persist();
+            $this->data = $fixture->$explodeValue[1]();
+        } else {
+            $this->data = strval($data['value']);
+        }
+    }
+
+    /**
+     * Persist custom selections products
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data
+     *
+     * @param string|null $key
+     * @return string
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return array
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ab76bc8d2eee94007a5e879a97c33fc930456af
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogSearch\Test\TestCase;
+
+use Mtf\TestCase\Injectable;
+use Magento\Cms\Test\Page\CmsIndex;
+use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
+
+/**
+ * Cover Suggest Searching Result (SearchEntity)
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Two "default" test simple products is created.
+ * 2. Navigate to frontend.
+ * 3. Input in "Search" field(top-right part of the index page, near cart icon) 'Simple' and press "Enter" key.
+ *
+ * Steps:
+ * 1. Go to frontend on index page.
+ * 2. Input in "Search" field test data.
+ * 3. Perform asserts.
+ *
+ * @group Search_Frontend_(CS)
+ * @ZephyrId MAGETWO-24671
+ */
+class SuggestSearchingResultEntityTest extends Injectable
+{
+    /**
+     * Run suggest searching result test
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CatalogSearchQuery $catalogSearch
+     * @return void
+     */
+    public function testSearch(CmsIndex $cmsIndex, CatalogSearchQuery $catalogSearch)
+    {
+        $cmsIndex->open();
+        $cmsIndex->getSearchBlock()->search($catalogSearch->getQueryText());
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest/testSearch.csv b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest/testSearch.csv
new file mode 100644
index 0000000000000000000000000000000000000000..2843f836b276b7fea1c7f38e2c123f88dc6e690c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/TestCase/SuggestSearchingResultEntityTest/testSearch.csv
@@ -0,0 +1,3 @@
+"catalogSearch/data/query_text/value";"catalogSearch/data/num_results";"constraint"
+"catalogProductSimple::getName";"-";"assertSuggestSearchingResult"
+"catalogProductSimple::getSku";"1";"assertSuggestSearchingResult"
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml
new file mode 100644
index 0000000000000000000000000000000000000000..123ca419303da3588964be0377b66def506822ee
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<constraint>
+    <assertSuggestSearchingResult module="Magento_CatalogSearch">
+        <severeness>high</severeness>
+        <require>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
+            <catalogSearch class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" />
+        </require>
+    </assertSuggestSearchingResult>
+</constraint>
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/fixture.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0ca4f481f402b732108b0ac08634cc94ab3e7518
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/fixture.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture>
+    <catalogSearchQuery module="Magento_CatalogSearch">
+        <type>flat</type>
+        <entity_type>catalogsearch_query</entity_type>
+        <collection>Magento\CatalogSearch\Model\Resource\Query\Collection</collection>
+    </catalogSearchQuery>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerNotInGrid.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerNotInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1cfd78cab5c3622ef6ec67f7f8923afe1cd0013
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerNotInGrid.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\Customer\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Customer\Test\Page\Adminhtml\CustomerIndex;
+
+/**
+ * Class AssertCustomerNotInGrid
+ */
+class AssertCustomerNotInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'middle';
+
+    /**
+     * Asserts that customer is not in customer's grid
+     *
+     * @param CustomerInjectable $initialCustomer
+     * @param CustomerIndex $pageCustomerIndex
+     * @return void
+     */
+    public function processAssert(CustomerInjectable $customer, CustomerIndex $customerIndexPage)
+    {
+        $filter = [
+            'email' => $customer->getEmail()
+        ];
+
+        $customerIndexPage->open();
+        \PHPUnit_Framework_Assert::assertFalse(
+            $customerIndexPage->getCustomerGridBlock()->isRowVisible($filter),
+            "Customer with email {$filter['email']} is present in Customer grid."
+        );
+    }
+
+    /**
+     * Success message if Customer not in grid
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Customer is absent in Customer grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessDeleteMessage.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessDeleteMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..977b903f0aa3e2a6b8563e28d82f35f242973224
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerSuccessDeleteMessage.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 Mtf\Constraint\AbstractConstraint;
+use Magento\Customer\Test\Page\Adminhtml\CustomerIndex;
+
+/**
+ * Class AssertCustomerSuccessDeleteMessage
+ */
+class AssertCustomerSuccessDeleteMessage extends AbstractConstraint
+{
+    const DELETE_MESSAGE = 'You deleted the customer.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that actual delete message equals expected
+     *
+     * @param CustomerIndex $pageCustomerIndex
+     * @return void
+     */
+    public function processAssert(CustomerIndex $customerIndexPage)
+    {
+        $actualMessage = $customerIndexPage->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::DELETE_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::DELETE_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Text success delete message is displayed
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Assert that success delete message is displayed.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..02b14d07ae771f5cd1099143e15a1162fe3bef87
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest.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\CustomerInjectable;
+
+/**
+ * Test creation for DeleteCustomerBackendEntity
+ *
+ * Test Flow:
+ * Preconditions:
+ * 1. Create customer on the backend
+ *
+ * Steps:
+ * 1. Open backend
+ * 2. Go to  Customers - All Customers
+ * 3. Search and open created customer according to dataset
+ * 4. Fill in data according to dataset
+ * 5. Perform all assertions according to dataset
+ *
+ * @group Customers_(CS)
+ * @ZephyrId MAGETWO-24764
+ */
+class DeleteCustomerBackendEntityTest extends Injectable
+{
+    /**
+     * @var CustomerIndex
+     */
+    protected $customerIndexPage;
+
+    /**
+     * @var CustomerIndexEdit
+     */
+    protected $customerIndexEditPage;
+
+    /**
+     * Preparing pages for test
+     *
+     * @param CustomerIndex $customerIndexPage
+     * @param CustomerIndexEdit $customerIndexEditPage
+     * @return void
+     */
+    public function __inject(
+        CustomerIndex $customerIndexPage,
+        CustomerIndexEdit $customerIndexEditPage
+    ) {
+        $this->customerIndexPage = $customerIndexPage;
+        $this->customerIndexEditPage = $customerIndexEditPage;
+    }
+
+    /**
+     * Runs Delete Customer Backend Entity test
+     *
+     * @param CustomerInjectable $initialCustomer
+     * @return void
+     */
+    public function testDeleteCustomerBackendEntity(CustomerInjectable $customer)
+    {
+        // Preconditions:
+        $customer->persist();
+
+        // Steps:
+        $filter = ['email' => $customer->getEmail()];
+        $this->customerIndexPage->open();
+        $this->customerIndexPage->getCustomerGridBlock()->searchAndOpen($filter);
+        $this->customerIndexEditPage->getPageActionsBlock()->delete();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest/testDeleteCustomerBackendEntity.csv b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest/testDeleteCustomerBackendEntity.csv
new file mode 100644
index 0000000000000000000000000000000000000000..20581464f19ca1c7bc263515fd287cb30493fc13
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/TestCase/DeleteCustomerBackendEntityTest/testDeleteCustomerBackendEntity.csv
@@ -0,0 +1,2 @@
+"customer/dataSet";"constraint"
+"default";"assertCustomerSuccessDeleteMessage, assertCustomerNotInGrid"
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 68b0d80fe8be6557fbe23ec8513fc568eb647ef4..7e62e8457fe491bda5a5e94bb0574bb3fb3dfaff 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
@@ -30,6 +30,12 @@
             <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" />
         </require>
     </assertCustomerSuccessSaveMessage>
+    <assertCustomerSuccessDeleteMessage module="Magento_Customer">
+        <severeness>low</severeness>
+        <require>
+            <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" />
+        </require>
+    </assertCustomerSuccessDeleteMessage>
     <assertCustomerSuccessRegisterMessage module="Magento_Customer">
         <severeness>low</severeness>
         <require>
@@ -43,14 +49,13 @@
             <pageCustomerIndex class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" />
         </require>
     </assertCustomerInGrid>
-    <assertUpdateCustomerInGrid module="Magento_Customer">
+    <assertCustomerNotInGrid 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" />
+            <customerIndexPage class="Magento\Customer\Test\Page\Adminhtml\CustomerIndex" />
         </require>
-    </assertUpdateCustomerInGrid>
+    </assertCustomerNotInGrid>
     <assertCustomerForm module="Magento_Customer">
         <severeness>middle</severeness>
         <require>
@@ -59,15 +64,6 @@
             <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>
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 5272ddc9cb88fa81a02911714d93de1c82670b1f..add2d50717a770ef59b8b298c1509134270fb54b 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
@@ -25,14 +25,13 @@
 namespace Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab;
 
 use Mtf\Client\Element;
-use Mtf\Factory\Factory;
-use Mtf\Client\Driver\Selenium\Element as RootElement;
 use Magento\Backend\Test\Block\Widget\Tab;
-use Magento\Bundle\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option;
+use Mtf\Client\Element\Locator;
 
 /**
  * Class Downloadable
  *
+ * Product downloadable tab
  */
 class Downloadable extends Tab
 {
@@ -43,6 +42,54 @@ class Downloadable extends Tab
      */
     protected $addNewRow = '[data-action=add-link]';
 
+    /**
+     * Downloadable block
+     *
+     * @var string
+     */
+    protected $downloadableBlock = '//dl[@id="tab_content_downloadableInfo"]';
+
+    /**
+     * Get Downloadable block
+     *
+     * @param string $type
+     * @param Element $element
+     * @return \Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable\Samples |
+     *         \Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable\Links
+     */
+    public function getDownloadableBlock($type, Element $element = null)
+    {
+        $element = $element ? : $this->_rootElement;
+        return $this->blockFactory->create(
+            'Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable\\' . $type,
+            ['element' => $element->find($this->downloadableBlock, Locator::SELECTOR_XPATH)]
+        );
+    }
+
+    /**
+     * Get data to fields on downloadable tab
+     *
+     * @param array|null $fields
+     * @param Element|null $element
+     * @return array
+     */
+    public function getDataFormTab($fields = null, Element $element = null)
+    {
+        $newFields = [];
+        if (isset($fields['downloadable_sample']['value'])) {
+            $newFields['downloadable_sample'] = $this->getDownloadableBlock('Samples')->getDataSamples(
+                $fields['downloadable_sample']['value']
+            );
+        }
+        if (isset($fields['downloadable_links']['value'])) {
+            $newFields['downloadable_links'] = $this->getDownloadableBlock('Links')->getDataLinks(
+                $fields['downloadable_links']['value']
+            );
+        }
+
+        return $newFields;
+    }
+
     /**
      * Fill downloadable information
      *
@@ -52,13 +99,12 @@ class Downloadable extends Tab
      */
     public function fillFormTab(array $fields, Element $element = null)
     {
-        if (isset($fields['downloadable'])) {
-            foreach ($fields['downloadable']['link'] as $index => $link) {
-                $element->find($this->addNewRow)->click();
-                $linkRowBlock = Factory::getBlockFactory()
-                    ->getMagentoDownloadableAdminhtmlCatalogProductEditTabDownloadableLinkRow($element);
-                $linkRowBlock->fill($index, $link);
-            }
+        if (isset($fields['downloadable_sample']['value'])) {
+            $this->getDownloadableBlock('Samples')->fillSamples($fields['downloadable_sample']['value']);
+        }
+
+        if (isset($fields['downloadable_links']['value'])) {
+            $this->getDownloadableBlock('Links')->fillLinks($fields['downloadable_links']['value']);
         }
 
         return $this;
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php
index 8e493e267a6b42d7c2486bdec096c3cd7d45f506..d6cde4fe846bc1d27c30e107d1dad97295003a41 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.php
@@ -23,40 +23,36 @@
  */
 namespace Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable;
 
-use Mtf\Block\Block;
-use Mtf\Client\Element\Locator;
+use Mtf\Block\Form;
 
-class LinkRow extends Block
+/**
+ * Class LinkRow
+ *
+ * Form item links
+ */
+class LinkRow extends Form
 {
     /**
-     * Example: name="downloadable[link][1][price]"
+     * Fill item link
      *
-     * @var string
+     * @param array $fields
+     * @return void
      */
-    protected $fieldSelectorTemplate = '[name="downloadable[link][%d][%s]"]';
+    public function fillLinkRow(array $fields)
+    {
+        $mapping = $this->dataMapping($fields);
+        $this->_fill($mapping);
+    }
 
     /**
-     * @param int $rowIndex
-     * @param array $rowData
+     * Get data item link
+     *
+     * @param array $fields
+     * @return array
      */
-    public function fill($rowIndex, $rowData)
+    public function getDataLinkRow(array $fields)
     {
-        foreach ([
-            'title', 'price', 'number_of_downloads', 'is_unlimited',
-            'is_shareable', 'sample][type', 'sample][url', 'type', 'link_url', 'sort_order'
-        ] as $field) {
-            if (isset($rowData[$field]['value'])) {
-                $fieldSelector = sprintf($this->fieldSelectorTemplate, $rowIndex, $field);
-                /* @TODO replace with typified radio element */
-                $type = isset($rowData[$field]['input']) ? $rowData[$field]['input'] : null;
-                if ($type == 'radio') {
-                    $type = 'checkbox';
-                    $fieldSelector .= sprintf('[value=%s]', $rowData[$field]['value']);
-                    $rowData[$field]['value'] = 'Yes';
-                }
-                $this->_rootElement->find($fieldSelector, Locator::SELECTOR_CSS, $type)
-                    ->setValue($rowData[$field]['value']);
-            }
-        }
+        $mapping = $this->dataMapping($fields);
+        return $this->_getData($mapping);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0d9f64e628c1f63e4eec41da5acf3ac29b3a3ed3
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/LinkRow.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @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>[name$='[title]']</selector>
+            <strategy>css selector</strategy>
+        </title>
+        <price>
+            <selector>[name$='[price]']</selector>
+            <strategy>css selector</strategy>
+        </price>
+        <number_of_downloads>
+            <selector>[name$='[number_of_downloads]']</selector>
+            <strategy>css selector</strategy>
+        </number_of_downloads>
+        <is_unlimited>
+            <selector>[name$='[is_unlimited]']</selector>
+            <strategy>css selector</strategy>
+            <input>checkbox</input>
+        </is_unlimited>
+        <is_shareable>
+            <selector>[name$='[is_shareable]']</selector>
+            <strategy>css selector</strategy>
+            <input>select</input>
+        </is_shareable>
+        <sample composite="1">
+            <sample_type_url>
+                <selector>[value='url'][name$='[sample][type]']</selector>
+                <strategy>css selector</strategy>
+                <input>checkbox</input>
+            </sample_type_url>
+            <sample_type_file>
+                <selector>[value='file'][name$='[sample][type]']</selector>
+                <strategy>css selector</strategy>
+                <input>checkbox</input>
+            </sample_type_file>
+            <sample_url>
+                <selector>[name$='[sample][url]']</selector>
+                <strategy>css selector</strategy>
+            </sample_url>
+        </sample>
+        <file_type_url>
+            <selector>[value='url'][name*='[type]']:not([name*='[sample]'])</selector>
+            <strategy>css selector</strategy>
+            <input>checkbox</input>
+        </file_type_url>
+        <file_type_file>
+            <selector>[value='file'][name*='[type]']:not([name*='[sample]'])</selector>
+            <strategy>css selector</strategy>
+            <input>checkbox</input>
+        </file_type_file>
+        <file_link_url>
+            <selector>[name$='[link_url]']</selector>
+            <strategy>css selector</strategy>
+        </file_link_url>
+        <sort_order>
+            <selector>[name$='[sort_order]']</selector>
+            <strategy>css selector</strategy>
+        </sort_order>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf65d7ffc3b47618550bde969c7002c8d40b1ffc
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable;
+
+use Mtf\Block\Form;
+use Mtf\Client\Element;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Class Links
+ *
+ * Link Form of downloadable product
+ */
+class Links extends Form
+{
+    /**
+     * 'Show Links block' button
+     *
+     * @var string
+     */
+    protected $showLinks = '//*[@id="dt-links"]/a';
+
+    /**
+     * 'Add New Row for links' button
+     *
+     * @var string
+     */
+    protected $addNewLinkRow = '//button[@id="add_link_item"]';
+
+    /**
+     * Downloadable link item block
+     *
+     * @var string
+     */
+    protected $rowBlock = '//*[@id="link_items_body"]/tr[%d]';
+
+    /**
+     * Downloadable link title block
+     *
+     * @var string
+     */
+    protected $title = "//*[@id='downloadable_links_title']";
+
+    /**
+     * Get Downloadable link item block
+     *
+     * @param int $index
+     * @param Element $element
+     * @return LinkRow
+     */
+    public function getRowBlock($index, Element $element = null)
+    {
+        $element = $element ? : $this->_rootElement;
+        return $this->blockFactory->create(
+            'Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable\LinkRow',
+            ['element' => $element->find(sprintf($this->rowBlock, ++$index), Locator::SELECTOR_XPATH)]
+        );
+    }
+
+    /**
+     * Fill links block
+     *
+     * @param array $fields
+     * @param Element $element
+     * @return void
+     */
+    public function fillLinks(array $fields, Element $element = null)
+    {
+        $element = $element ? : $this->_rootElement;
+        if (!$element->find($this->title, Locator::SELECTOR_XPATH)->isVisible()) {
+            $element->find($this->showLinks, Locator::SELECTOR_XPATH)->click();
+        }
+        $mapping = $this->dataMapping(
+            ['title' => $fields['title'], 'links_purchased_separately' => $fields['links_purchased_separately']]
+        );
+        $this->_fill($mapping);
+        foreach ($fields['downloadable']['link'] as $index => $link) {
+            $element->find($this->addNewLinkRow, Locator::SELECTOR_XPATH)->click();
+            $this->getRowBlock($index, $element)->fillLinkRow($link);
+        }
+    }
+
+    /**
+     * Get data links block
+     *
+     * @param array|null $fields
+     * @param Element|null $element
+     * @return array
+     */
+    public function getDataLinks(array $fields = null, Element $element = null)
+    {
+        $element = $element ? : $this->_rootElement;
+        if (!$element->find($this->title, Locator::SELECTOR_XPATH)->isVisible()) {
+            $element->find($this->showLinks, Locator::SELECTOR_XPATH)->click();
+        }
+        $mapping = $this->dataMapping(
+            ['title' => $fields['title'], 'links_purchased_separately' => $fields['links_purchased_separately']]
+        );
+        $newFields = $this->_getData($mapping);
+        foreach ($fields['downloadable']['link'] as $index => $link) {
+            $newFields['downloadable']['link'][$index] = $this->getRowBlock($index, $element)
+                ->getDataLinkRow($link);
+        }
+        return $newFields;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.xml
new file mode 100644
index 0000000000000000000000000000000000000000..64a6ef172a1e1f701ff020e617b02221e226f959
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Links.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <title>
+            <selector>[name="product[links_title]"]</selector>
+            <strategy>css selector</strategy>
+        </title>
+        <links_purchased_separately>
+            <selector>[name="product[links_purchased_separately]"]</selector>
+            <strategy>css selector</strategy>
+            <input>select</input>
+        </links_purchased_separately>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SampleRow.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SampleRow.php
new file mode 100644
index 0000000000000000000000000000000000000000..4133fa8844586ea8ce21aef9ad7bcf723b671220
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SampleRow.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\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable;
+
+use Mtf\Block\Form;
+
+/**
+ * Class SampleRow
+ * Form item samples
+ */
+class SampleRow extends Form
+{
+    /**
+     * Fill item sample
+     *
+     * @param array $fields
+     * @return void
+     */
+    public function fillSampleRow(array $fields)
+    {
+        $mapping = $this->dataMapping($fields);
+        $this->_fill($mapping);
+    }
+
+    /**
+     * Get data item sample
+     *
+     * @param array $fields
+     * @return array
+     */
+    public function getDataSampleRow(array $fields)
+    {
+        $mapping = $this->dataMapping($fields);
+        return $this->_getData($mapping);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SampleRow.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SampleRow.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d417faa2a63363aac2a9628bf2d64a57f8505da3
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/SampleRow.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)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <title>
+            <selector>[name$='[title]']</selector>
+            <strategy>css selector</strategy>
+        </title>
+        <sample_type_file>
+            <selector>[value='file'][name$='[type]']</selector>
+            <strategy>css selector</strategy>
+            <input>checkbox</input>
+        </sample_type_file>
+        <sample_type_url>
+            <selector>[value='url'][name$='[type]']</selector>
+            <strategy>css selector</strategy>
+            <input>checkbox</input>
+        </sample_type_url>
+        <sample_url>
+            <selector>[name$='[sample_url]']</selector>
+            <strategy>css selector</strategy>
+        </sample_url>
+        <sort_order>
+            <selector>[name$='[sort_order]']</selector>
+            <strategy>css selector</strategy>
+        </sort_order>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e11d2fdf678e0d3186da01fa72d773157c7a8f8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable;
+
+use Mtf\Block\Form;
+use Mtf\Client\Element;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Class SampleRow
+ *
+ * Sample Form of downloadable product
+ */
+class Samples extends Form
+{
+    /**
+     * 'Add New Row for samples' button
+     *
+     * @var string
+     */
+    protected $addNewSampleRow = '//button[@id="add_sample_item"]';
+
+    /**
+     * 'Show Sample block' button
+     *
+     * @var string
+     */
+    protected $showSample = '//dt[@id="dt-samples"]/a';
+
+    /**
+     * Sample title block
+     *
+     * @var string
+     */
+    protected $samplesTitle = '//input[@name="product[samples_title]"]';
+
+    /**
+     * Downloadable sample item block
+     *
+     * @var string
+     */
+    protected $rowBlock = '//*[@id="sample_items_body"]/tr[%d]';
+
+    /**
+     * Get Downloadable sample item block
+     *
+     * @param int $index
+     * @param Element $element
+     * @return SampleRow
+     */
+    public function getRowBlock($index, Element $element = null)
+    {
+        $element = $element ? : $this->_rootElement;
+        return $this->blockFactory->create(
+            'Magento\Downloadable\Test\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable\SampleRow',
+            ['element' => $element->find(sprintf($this->rowBlock, ++$index), Locator::SELECTOR_XPATH)]
+        );
+    }
+
+    /**
+     * Fill samples block
+     *
+     * @param array|null $fields
+     * @param Element $element
+     * @return void
+     */
+    public function fillSamples(array $fields = null, Element $element = null)
+    {
+        $element = $element ? : $this->_rootElement;
+        if (!$element->find($this->samplesTitle, Locator::SELECTOR_XPATH)->isVisible()) {
+            $element->find($this->showSample, Locator::SELECTOR_XPATH)->click();
+        }
+        $mapping = $this->dataMapping(['title' => $fields['title']]);
+        $this->_fill($mapping);
+        foreach ($fields['downloadable']['sample'] as $index => $sample) {
+            $element->find($this->addNewSampleRow, Locator::SELECTOR_XPATH)->click();
+            $this->getRowBlock($index, $element)->fillSampleRow($sample);
+        }
+    }
+
+    /**
+     * Get data samples block
+     *
+     * @param array|null $fields
+     * @param Element|null $element
+     * @return array
+     */
+    public function getDataSamples(array $fields = null, Element $element = null)
+    {
+        $element = $element ? : $this->_rootElement;
+        if (!$element->find($this->samplesTitle, Locator::SELECTOR_XPATH)->isVisible()) {
+            $element->find($this->showSample, Locator::SELECTOR_XPATH)->click();
+        }
+        $mapping = $this->dataMapping(['title' => $fields['title']]);
+        $newFields = $this->_getData($mapping);
+        foreach ($fields['downloadable']['sample'] as $index => $sample) {
+            $newFields['downloadable']['sample'][$index] = $this->getRowBlock($index, $element)
+                ->getDataSampleRow($sample);
+        }
+        return $newFields;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7e693a04c8d4e4b2cc03edb9d578fa48092b1997
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Downloadable/Samples.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)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <title>
+            <selector>[name="product[samples_title]"]</selector>
+            <strategy>css selector</strategy>
+        </title>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Backend/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Form.xml
similarity index 100%
rename from dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Backend/ProductForm.xml
rename to dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Adminhtml/Product/Form.xml
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..e00adf945ce1fa70ea2756afa758ffa4a362190a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Downloadable\Test\Block\Catalog\Product;
+
+use Mtf\Client\Element\Locator;
+use Magento\Catalog\Test\Block\Product\View as ParentView;
+
+/**
+ * Class View
+ * Downloadable product view block on the product page
+ */
+class View extends ParentView
+{
+    /**
+     * Block Downloadable links
+     *
+     * @var string
+     */
+    protected $blockDownloadableLinks = '//div[contains(@class,"field downloads")]';
+
+    /**
+     * Block Downloadable samples
+     *
+     * @var string
+     */
+    protected $blockDownloadableSamples = '//dl[contains(@class,"downloadable samples")]';
+
+    /**
+     * Get downloadable link block
+     *
+     * @return \Magento\Downloadable\Test\Block\Catalog\Product\View\Links
+     */
+    public function getDownloadableLinksBlock()
+    {
+        return $this->blockFactory->create(
+            'Magento\Downloadable\Test\Block\Catalog\Product\View\Links',
+            [
+                'element' => $this->_rootElement->find($this->blockDownloadableLinks, Locator::SELECTOR_XPATH)
+            ]
+        );
+    }
+
+    /**
+     * Get downloadable samples block
+     *
+     * @return \Magento\Downloadable\Test\Block\Catalog\Product\View\Samples
+     */
+    public function getDownloadableSamplesBlock()
+    {
+        return $this->blockFactory->create(
+            'Magento\Downloadable\Test\Block\Catalog\Product\View\Samples',
+            [
+                'element' => $this->_rootElement->find($this->blockDownloadableSamples, Locator::SELECTOR_XPATH)
+            ]
+        );
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Links.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Links.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0ca52627e921b8a13661935de42489e5112ff5a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Links.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Block\Catalog\Product\View;
+
+use Mtf\Block\Block;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Class Links
+ *
+ * Downloadable links blocks on frontend
+ */
+class Links extends Block
+{
+    /**
+     * Selector title for for links
+     *
+     * @var string
+     */
+    protected $titleForLink = '//div[contains(@class,"field downloads")]/label[@class="label"]/span';
+
+    /**
+     * Format for downloadable links list selector
+     *
+     * @var string
+     */
+    protected $linksListSelector = '//*[@id="downloadable-links-list"]/div[%d]/';
+
+    /**
+     * Title selector item links
+     *
+     * @var string
+     */
+    protected $titleForList = "label[@class='label']/span[1]";
+
+    /**
+     * Price selector item links
+     *
+     * @var string
+     */
+    protected $priceForList = 'label/span[contains(@class,"price-container")]//span[@class="price"]';
+
+    /**
+     * Checkbox selector item links
+     *
+     * @var string
+     */
+    protected $separatelyForList = "input[@type='checkbox']";
+
+    /**
+     * Change format downloadable links list
+     *
+     * @param int $index
+     * @return string
+     */
+    protected function formatIndex($index)
+    {
+        return sprintf($this->linksListSelector, $index);
+    }
+
+    /**
+     * Get title for links block
+     *
+     * @return string
+     */
+    public function getTitleForLinkBlock()
+    {
+        return $this->_rootElement->find($this->titleForLink, Locator::SELECTOR_XPATH)->getText();
+    }
+
+    /**
+     * Get title for item link on data list
+     *
+     * @param int $index
+     * @return string
+     */
+    public function getItemTitle($index)
+    {
+        return $this->_rootElement->find($this->formatIndex($index) . $this->titleForList, Locator::SELECTOR_XPATH)
+            ->getText();
+    }
+
+    /**
+     * Visible checkbox for item link on data list
+     *
+     * @param int $index
+     * @return bool
+     */
+    public function isVisibleItemCheckbox($index)
+    {
+        return $this->_rootElement->find($this->formatIndex($index) . $this->separatelyForList, Locator::SELECTOR_XPATH)
+            ->isVisible();
+    }
+
+    /**
+     * Get price for item link on data list
+     *
+     * @param int $index
+     * @return string
+     */
+    public function getItemPrice($index)
+    {
+        return $this->_rootElement->find($this->formatIndex($index) . $this->priceForList, Locator::SELECTOR_XPATH)
+            ->getText();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Samples.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Samples.php
new file mode 100644
index 0000000000000000000000000000000000000000..65ea689e839df236ab2db65af9b3c5fbc98bf38b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Block/Catalog/Product/View/Samples.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\Downloadable\Test\Block\Catalog\Product\View;
+
+use Mtf\Block\Block;
+use Mtf\Client\Element\Locator;
+
+/**
+ * Class Samples
+ *
+ * Downloadable samples blocks on frontend
+ */
+class Samples extends Block
+{
+    /**
+     * Title selector for samples block
+     *
+     * @var string
+     */
+    protected $titleForSampleBlock = '//dt[contains(@class,"samples title")]';
+
+    /**
+     * Title selector item sample
+     *
+     * @var string
+     */
+    protected $titleForList = '//dd[contains(@class,"sample item")][%d]/a';
+
+    /**
+     * Get title for Samples block
+     *
+     * @return string
+     */
+    public function getTitleForSampleBlock()
+    {
+        return $this->_rootElement->find($this->titleForSampleBlock, Locator::SELECTOR_XPATH)->getText();
+    }
+
+    /**
+     * Get title for item sample on data list
+     *
+     * @param int $index
+     * @return string
+     */
+    public function getItemTitle($index)
+    {
+        $formatTitle = sprintf($this->titleForList, $index);
+        return $this->_rootElement->find($formatTitle, Locator::SELECTOR_XPATH)->getText();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableLinks.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableLinks.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f77fa13534c3d9db8be6ba04495122d3c894d73
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableLinks.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Downloadable\Test\Page\Product\CatalogProductView;
+use Magento\Downloadable\Test\Fixture\CatalogProductDownloadable;
+
+/**
+ * Class AssertDownloadableLinks
+ *
+ * Assert that Link block for downloadable product on front-end
+ */
+class AssertDownloadableLinks extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert Link block for downloadable product on front-end
+     *
+     * @param CatalogProductView $downloadableProductView
+     * @param CatalogProductDownloadable $product
+     * @return void
+     */
+    public function processAssert(CatalogProductView $downloadableProductView, CatalogProductDownloadable $product)
+    {
+        $downloadableProductView->init($product);
+        $downloadableProductView->open();
+        $linksBlock = $downloadableProductView->getDownloadableViewBlock()->getDownloadableLinksBlock();
+        $fields = $product->getData();
+        // Title for for Link block
+        \PHPUnit_Framework_Assert::assertEquals(
+            $linksBlock->getTitleForLinkBlock(),
+            $fields['downloadable_links']['title'],
+            'Title for for Link block for downloadable product on front-end is not correct.'
+        );
+
+        $this->sortDownloadableArray($fields['downloadable_links']['downloadable']['link']);
+
+        foreach ($fields['downloadable_links']['downloadable']['link'] as $index => $link) {
+            $index++;
+            // Titles for each links
+            // Links are displaying according to Sort Order
+            \PHPUnit_Framework_Assert::assertEquals(
+                $linksBlock->getItemTitle($index),
+                $link['title'],
+                'Link item ' . $index . ' with title "' . $link['title'] . '" is not visible.'
+            );
+
+            // If Links can be Purchase Separately, check-nob is presented near each link
+            // If Links CANNOT be Purchase Separately, check-nob is not presented near each link
+            if ($fields['downloadable_links']['links_purchased_separately'] == "Yes") {
+                \PHPUnit_Framework_Assert::assertTrue(
+                    $linksBlock->isVisibleItemCheckbox($index),
+                    'Item ' . $index . ' link block CANNOT be Purchase Separately.'
+                );
+                // Price is equals passed according to fixture
+                $link['price'] = sprintf('$%1.2f', $link['price']);
+                \PHPUnit_Framework_Assert::assertEquals(
+                    $linksBlock->getItemPrice($index),
+                    $link['price'],
+                    'Link item ' . $index . ' price is not visible.'
+                );
+            } elseif ($fields['downloadable_links']['links_purchased_separately'] == "No") {
+                \PHPUnit_Framework_Assert::assertFalse(
+                    $linksBlock->isVisibleItemCheckbox($index),
+                    'Item ' . $index . ' link block can be Purchase Separately.'
+                );
+            }
+        }
+    }
+
+    /**
+     * Sort downloadable links array
+     *
+     * @param array $fields
+     * @return array
+     */
+    protected function sortDownloadableArray(&$fields)
+    {
+        usort(
+            $fields,
+            function ($a, $b) {
+                if ($a['sort_order'] == $b['sort_order']) {
+                    return 0;
+                }
+                return ($a['sort_order'] < $b['sort_order']) ? -1 : 1;
+            }
+        );
+    }
+
+    /**
+     * Text of Visible in downloadable assert for link block
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Link block for downloadable product on front-end is visible.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableProductForm.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableProductForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..55fc50f6b2e9b28810487c136012f4c5765b5235
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableProductForm.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Downloadable\Test\Constraint;
+
+use Magento\Catalog\Test\Constraint\AssertProductForm;
+use Mtf\Fixture\InjectableFixture;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew;
+
+/**
+ * Class AssertDownloadableProductForm
+ */
+class AssertDownloadableProductForm extends AssertProductForm
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that downloadable product data on edit page equals to passed from fixture
+     *
+     * @param InjectableFixture $product
+     * @param CatalogProductIndex $productGrid
+     * @param CatalogProductNew $productPage
+     * @return void
+     */
+    public function processAssert(
+        InjectableFixture $product,
+        CatalogProductIndex $productGrid,
+        CatalogProductNew $productPage
+    ) {
+        $filter = ['sku' => $product->getData('sku')];
+        $productGrid->open()->getProductGrid()->searchAndOpen($filter);
+
+        $fields = $this->prepareFixtureData($product);
+        $fields = $this->convertDownloadableArray($fields);
+
+        $fieldsForm = $productPage->getForm()->getData($product);
+        \PHPUnit_Framework_Assert::assertEquals($fields, $fieldsForm, 'Form data not equals fixture data.');
+    }
+
+    /**
+     * Sort downloadable array
+     *
+     * @param array $fields
+     * @return array
+     */
+    protected function sortDownloadableArray(&$fields)
+    {
+        usort(
+            $fields,
+            function ($a, $b) {
+                return $a['sort_order'] - $b['sort_order'];
+            }
+        );
+    }
+
+    /**
+     * Convert fixture array
+     *
+     * @param array $fields
+     * @return array
+     */
+    protected function convertDownloadableArray(array $fields)
+    {
+        if (isset($fields['downloadable_links']['downloadable']['link'])) {
+            $this->sortDownloadableArray(
+                $fields['downloadable_links']['downloadable']['link']
+            );
+        }
+        if (isset($fields['downloadable_sample']['downloadable']['sample'])) {
+            $this->sortDownloadableArray(
+                $fields['downloadable_sample']['downloadable']['sample']
+            );
+        }
+
+        foreach ($fields as $key => $value) {
+            if (is_array($value)) {
+                $fields[$key] = $this->convertDownloadableArray($value);
+            } else {
+                if ($key == "special_price") {
+                    $fields[$key] = [$key => $fields[$key]];
+                }
+            }
+        }
+        return $fields;
+    }
+
+    /**
+     * Text of Visible in product form assert
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Form data equal the fixture data.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableSamplesData.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableSamplesData.php
new file mode 100644
index 0000000000000000000000000000000000000000..8beb8b74196c84ae8b38eae47215318b8653f736
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Constraint/AssertDownloadableSamplesData.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Downloadable\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Downloadable\Test\Page\Product\CatalogProductView;
+use Magento\Downloadable\Test\Fixture\CatalogProductDownloadable;
+
+/**
+ * Class AssertDownloadableSamplesData
+ *
+ * Assert that Sample block for downloadable product on front-end
+ */
+class AssertDownloadableSamplesData extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert Sample block for downloadable product on front-end
+     *
+     * @param CatalogProductView $productView
+     * @param CatalogProductDownloadable $product
+     * @return void
+     */
+    public function processAssert(CatalogProductView $productView, CatalogProductDownloadable $product)
+    {
+        $productView->init($product);
+        $productView->open();
+        $sampleBlock = $productView->getDownloadableViewBlock()->getDownloadableSamplesBlock();
+        $fields = $product->getData();
+
+        // Title for for sample block
+        \PHPUnit_Framework_Assert::assertEquals(
+            $sampleBlock->getTitleForSampleBlock(),
+            $fields['downloadable_sample']['title'],
+            'Title for for Samples block for downloadable product on front-end is not correct.'
+        );
+
+        $this->sortDownloadableArray($fields['downloadable_sample']['downloadable']['sample']);
+
+        foreach ($fields['downloadable_sample']['downloadable']['sample'] as $index => $sample) {
+            // Titles for each sample
+            // Samples are displaying according to Sort Order
+            \PHPUnit_Framework_Assert::assertEquals(
+                $sampleBlock->getItemTitle(++$index),
+                $sample['title'],
+                'Sample item ' . $index . ' with title "' . $sample['title'] . '" is not visible.'
+            );
+        }
+    }
+
+    /**
+     * Sort downloadable sample array
+     *
+     * @param array $fields
+     * @return array
+     */
+    protected function sortDownloadableArray(&$fields)
+    {
+        usort(
+            $fields,
+            function ($a, $b) {
+                if ($a['sort_order'] == $b['sort_order']) {
+                    return 0;
+                }
+                return ($a['sort_order'] < $b['sort_order']) ? -1 : 1;
+            }
+        );
+    }
+
+    /**
+     * Text of Visible in downloadable assert for sample block
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Sample block for downloadable product on front-end is visible.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b9904168278a47f4f73e200de05132af3c726b5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php
@@ -0,0 +1,939 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+use Mtf\System\Config;
+use Mtf\Handler\HandlerFactory;
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Repository\RepositoryFactory;
+
+/**
+ * Class CatalogProductDownloadable
+ * Fixture for Downloadable product
+ */
+class CatalogProductDownloadable extends InjectableFixture
+{
+    /**
+     * @var string
+     */
+    protected $repositoryClass = 'Magento\Downloadable\Test\Repository\DownloadableProduct';
+
+    /**
+     * @var string
+     */
+    protected $handlerInterface = 'Magento\Downloadable\Test\Handler\Curl\CreateDownloadable';
+
+    /**
+     * Constructor
+     *
+     * @constructor
+     * @param Config $configuration
+     * @param RepositoryFactory $repositoryFactory
+     * @param FixtureFactory $fixtureFactory
+     * @param HandlerFactory $handlerFactory
+     * @param array $data
+     * @param string $dataSet
+     * @param bool $persist
+     */
+    public function __construct(
+        Config $configuration,
+        RepositoryFactory $repositoryFactory,
+        FixtureFactory $fixtureFactory,
+        HandlerFactory $handlerFactory,
+        array $data = [],
+        $dataSet = '',
+        $persist = false
+    ) {
+        parent::__construct(
+            $configuration,
+            $repositoryFactory,
+            $fixtureFactory,
+            $handlerFactory,
+            $data,
+            $dataSet,
+            $persist
+        );
+
+        if (!isset($this->data['url_key']) && isset($this->data['name'])) {
+            $this->data['url_key'] = trim(strtolower(preg_replace('#[^0-9a-z%]+#i', '-', $this->data['name'])), '-');
+        }
+
+    }
+
+    protected $dataConfig = [
+        'create_url_params' => [
+            'type' => 'downloadable',
+            'set' => '4',
+        ],
+        'input_prefix' => 'product',
+    ];
+
+    protected $defaultDataSet = [
+        'name' => 'DownloadableProduct_%isolation%',
+        'sku' => 'DownloadableProduct_%isolation%',
+        'price' => '100',
+        'tax_class' => 'Taxable Goods',
+        'description' => 'This is description for downloadable product',
+        'short_description' => 'This is short description for downloadable product',
+        'quantity_and_stock_status_qty' => '1',
+        'quantity_and_stock_status' => 'In Stock',
+        'is_virtual' => 'Yes',
+        'downloadable_links' => ['preset' => 'default'],
+    ];
+
+    protected $category_ids = [
+        'attribute_code' => 'category_ids',
+        'backend_type' => 'static',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+        'fixture' => 'Magento\Catalog\Test\Fixture\CategoryIds'
+    ];
+
+    protected $cost = [
+        'attribute_code' => 'cost',
+        'backend_type' => 'decimal',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'price',
+    ];
+
+    protected $created_at = [
+        'attribute_code' => 'created_at',
+        'backend_type' => 'static',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $custom_design = [
+        'attribute_code' => 'custom_design',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'select',
+    ];
+
+    protected $custom_design_from = [
+        'attribute_code' => 'custom_design_from',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $custom_design_to = [
+        'attribute_code' => 'custom_design_to',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $custom_layout_update = [
+        'attribute_code' => 'custom_layout_update',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'textarea',
+    ];
+
+    protected $description = [
+        'attribute_code' => 'description',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => 'This is description for downloadable product',
+        'input' => 'textarea',
+        'group' => 'product-details'
+    ];
+
+    protected $gallery = [
+        'attribute_code' => 'gallery',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'gallery',
+    ];
+
+    protected $gift_message_available = [
+        'attribute_code' => 'gift_message_available',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'select',
+    ];
+
+    protected $group_price = [
+        'attribute_code' => 'group_price',
+        'backend_type' => 'decimal',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+        'group' => 'advanced-pricing',
+        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions'
+    ];
+
+    protected $has_options = [
+        'attribute_code' => 'has_options',
+        'backend_type' => 'static',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $image = [
+        'attribute_code' => 'image',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'media_image',
+    ];
+
+    protected $image_label = [
+        'attribute_code' => 'image_label',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $is_returnable = [
+        'attribute_code' => 'is_returnable',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '2',
+        'input' => 'select',
+    ];
+
+    protected $links_exist = [
+        'attribute_code' => 'links_exist',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $links_purchased_separately = [
+        'attribute_code' => 'links_purchased_separately',
+        'backend_type' => 'int',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $links_title = [
+        'attribute_code' => 'links_title',
+        'backend_type' => 'varchar',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $media_gallery = [
+        'attribute_code' => 'media_gallery',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'gallery',
+    ];
+
+    protected $meta_description = [
+        'attribute_code' => 'meta_description',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'textarea',
+    ];
+
+    protected $meta_keyword = [
+        'attribute_code' => 'meta_keyword',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'textarea',
+    ];
+
+    protected $meta_title = [
+        'attribute_code' => 'meta_title',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $minimal_price = [
+        'attribute_code' => 'minimal_price',
+        'backend_type' => 'decimal',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'price',
+    ];
+
+    protected $msrp = [
+        'attribute_code' => 'msrp',
+        'backend_type' => 'decimal',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'price',
+    ];
+
+    protected $msrp_display_actual_price_type = [
+        'attribute_code' => 'msrp_display_actual_price_type',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '4',
+        'input' => 'select',
+    ];
+
+    protected $msrp_enabled = [
+        'attribute_code' => 'msrp_enabled',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '2',
+        'input' => 'select',
+    ];
+
+    protected $name = [
+        'attribute_code' => 'name',
+        'backend_type' => 'varchar',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+        'group' => 'product-details',
+    ];
+
+    protected $news_from_date = [
+        'attribute_code' => 'news_from_date',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $news_to_date = [
+        'attribute_code' => 'news_to_date',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $old_id = [
+        'attribute_code' => 'old_id',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $options_container = [
+        'attribute_code' => 'options_container',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => 'container2',
+        'input' => 'select',
+    ];
+
+    protected $page_layout = [
+        'attribute_code' => 'page_layout',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'select',
+    ];
+
+    protected $price = [
+        'attribute_code' => 'price',
+        'backend_type' => 'decimal',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'price',
+        'group' => 'product-details'
+    ];
+
+    protected $inventory_manage_stock = [
+        'attribute_code' => 'inventory_manage_stock',
+        'input' => 'select',
+        'group' => 'advanced-inventory',
+    ];
+
+    protected $stock_data_min_qty= [
+        'attribute_code' => 'stock_data_min_qty',
+        'input' => 'text',
+        'group' => 'advanced-inventory',
+    ];
+
+    protected $stock_data_use_config_min_qty = [
+        'attribute_code' => 'stock_data_use_config_min_qty',
+        'input' => 'checkbox',
+        'group' => 'advanced-inventory'
+    ];
+
+    protected $inventory_qty = [
+        'attribute_code' => 'inventory_qty',
+        'input' => 'text',
+        'group' => 'advanced-inventory',
+    ];
+
+    protected $quantity_and_stock_status = [
+        'attribute_code' => 'quantity_and_stock_status',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '1',
+        'input' => 'select',
+        'group' => 'product-details',
+    ];
+
+    protected $qty = [
+        'attribute_code' => 'qty',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '1',
+        'input' => 'text',
+        'group' => 'product-details',
+    ];
+
+    protected $related_tgtr_position_behavior = [
+        'attribute_code' => 'related_tgtr_position_behavior',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $related_tgtr_position_limit = [
+        'attribute_code' => 'related_tgtr_position_limit',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $required_options = [
+        'attribute_code' => 'required_options',
+        'backend_type' => 'static',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $samples_title = [
+        'attribute_code' => 'samples_title',
+        'backend_type' => 'varchar',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $short_description = [
+        'attribute_code' => 'short_description',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => 'This is short description for downloadable product',
+        'input' => 'textarea',
+        'group' => 'autosettings'
+    ];
+
+    protected $downloadable_links = [
+        'attribute_code' => 'downloadable_items',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => 'dafault',
+        'input' => 'text',
+        'group' => 'downloadable_information',
+        'fixture' => 'Magento\Downloadable\Test\Fixture\CatalogProductDownloadable\Links'
+
+    ];
+
+    protected $downloadable_sample = [
+        'attribute_code' => 'downloadable_sample',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => 'dafault',
+        'input' => 'text',
+        'group' => 'downloadable_information',
+        'fixture' => 'Magento\Downloadable\Test\Fixture\CatalogProductDownloadable\Samples'
+
+    ];
+
+    protected $sku = [
+        'attribute_code' => 'sku',
+        'backend_type' => 'static',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+        'group' => 'product-details',
+    ];
+
+    protected $small_image = [
+        'attribute_code' => 'small_image',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'media_image',
+    ];
+
+    protected $small_image_label = [
+        'attribute_code' => 'small_image_label',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $special_from_date = [
+        'attribute_code' => 'special_from_date',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $special_price = [
+        'attribute_code' => 'special_price',
+        'backend_type' => 'decimal',
+        'is_required' => '0',
+        'default_value' => '10',
+        'group' => 'advanced-pricing'
+    ];
+
+    protected $special_to_date = [
+        'attribute_code' => 'special_to_date',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $status = [
+        'attribute_code' => 'status',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '1',
+        'input' => 'select',
+    ];
+
+    protected $tax_class_id = [
+        'attribute_code' => 'tax_class_id',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '2',
+        'input' => 'select',
+        'group' => 'product-details'
+    ];
+
+    protected $thumbnail = [
+        'attribute_code' => 'thumbnail',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'media_image',
+    ];
+
+    protected $thumbnail_label = [
+        'attribute_code' => 'thumbnail_label',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $tier_price = [
+        'attribute_code' => 'tier_price',
+        'backend_type' => 'decimal',
+        'is_required' => '0',
+        'default_value' => 'default',
+        'input' => 'text',
+        'group' => 'advanced-pricing',
+        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions'
+    ];
+
+    protected $updated_at = [
+        'attribute_code' => 'updated_at',
+        'backend_type' => 'static',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $upsell_tgtr_position_behavior = [
+        'attribute_code' => 'upsell_tgtr_position_behavior',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $upsell_tgtr_position_limit = [
+        'attribute_code' => 'upsell_tgtr_position_limit',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $url_key = [
+        'attribute_code' => 'url_key',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+        'group' => 'autosettings'
+    ];
+
+    protected $url_path = [
+        'attribute_code' => 'url_path',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $visibility = [
+        'attribute_code' => 'visibility',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '4',
+        'input' => 'select',
+    ];
+
+    protected $weight = [
+        'attribute_code' => 'weight',
+        'backend_type' => 'decimal',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'weight',
+    ];
+
+    protected $custom_options = [
+        'attribute_code' => 'custom_options',
+        'backend_type' => 'virtual',
+        'is_required' => '0',
+        'default_value' => 'default',
+        'group' => 'customer-options',
+        'fixture' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
+    ];
+
+    protected $id = [
+        'attribute_code' => 'id',
+        'backend_type' => 'virtual',
+    ];
+
+    public function getCategoryIds()
+    {
+        return $this->getData('category_ids');
+    }
+
+    public function getCost()
+    {
+        return $this->getData('cost');
+    }
+
+    public function getCreatedAt()
+    {
+        return $this->getData('created_at');
+    }
+
+    public function getCustomDesign()
+    {
+        return $this->getData('custom_design');
+    }
+
+    public function getCustomDesignFrom()
+    {
+        return $this->getData('custom_design_from');
+    }
+
+    public function getCustomDesignTo()
+    {
+        return $this->getData('custom_design_to');
+    }
+
+    public function getCustomLayoutUpdate()
+    {
+        return $this->getData('custom_layout_update');
+    }
+
+    public function getDescription()
+    {
+        return $this->getData('description');
+    }
+
+    public function getGallery()
+    {
+        return $this->getData('gallery');
+    }
+
+    public function getGiftMessageAvailable()
+    {
+        return $this->getData('gift_message_available');
+    }
+
+    public function getGroupPrice()
+    {
+        return $this->getData('group_price');
+    }
+
+    public function getHasOptions()
+    {
+        return $this->getData('has_options');
+    }
+
+    public function getImage()
+    {
+        return $this->getData('image');
+    }
+
+    public function getImageLabel()
+    {
+        return $this->getData('image_label');
+    }
+
+    public function getIsReturnable()
+    {
+        return $this->getData('is_returnable');
+    }
+
+    public function getLinksExist()
+    {
+        return $this->getData('links_exist');
+    }
+
+    public function getLinksPurchasedSeparately()
+    {
+        return $this->getData('links_purchased_separately');
+    }
+
+    public function getLinksTitle()
+    {
+        return $this->getData('links_title');
+    }
+
+    public function getMediaGallery()
+    {
+        return $this->getData('media_gallery');
+    }
+
+    public function getMetaDescription()
+    {
+        return $this->getData('meta_description');
+    }
+
+    public function getMetaKeyword()
+    {
+        return $this->getData('meta_keyword');
+    }
+
+    public function getMetaTitle()
+    {
+        return $this->getData('meta_title');
+    }
+
+    public function getMinimalPrice()
+    {
+        return $this->getData('minimal_price');
+    }
+
+    public function getMsrp()
+    {
+        return $this->getData('msrp');
+    }
+
+    public function getMsrpDisplayActualPriceType()
+    {
+        return $this->getData('msrp_display_actual_price_type');
+    }
+
+    public function getMsrpEnabled()
+    {
+        return $this->getData('msrp_enabled');
+    }
+
+    public function getName()
+    {
+        return $this->getData('name');
+    }
+
+    public function getNewsFromDate()
+    {
+        return $this->getData('news_from_date');
+    }
+
+    public function getNewsToDate()
+    {
+        return $this->getData('news_to_date');
+    }
+
+    public function getOldId()
+    {
+        return $this->getData('old_id');
+    }
+
+    public function getOptionsContainer()
+    {
+        return $this->getData('options_container');
+    }
+
+    public function getPageLayout()
+    {
+        return $this->getData('page_layout');
+    }
+
+    public function getPrice()
+    {
+        return $this->getData('price');
+    }
+
+    public function getQuantityAndStockStatus()
+    {
+        return $this->getData('quantity_and_stock_status');
+    }
+
+    public function getRelatedTgtrPositionBehavior()
+    {
+        return $this->getData('related_tgtr_position_behavior');
+    }
+
+    public function getRelatedTgtrPositionLimit()
+    {
+        return $this->getData('related_tgtr_position_limit');
+    }
+
+    public function getRequiredOptions()
+    {
+        return $this->getData('required_options');
+    }
+
+    public function getSamplesTitle()
+    {
+        return $this->getData('samples_title');
+    }
+
+    public function getShortDescription()
+    {
+        return $this->getData('short_description');
+    }
+
+    public function getSku()
+    {
+        return $this->getData('sku');
+    }
+
+    public function getSmallImage()
+    {
+        return $this->getData('small_image');
+    }
+
+    public function getSmallImageLabel()
+    {
+        return $this->getData('small_image_label');
+    }
+
+    public function getSpecialFromDate()
+    {
+        return $this->getData('special_from_date');
+    }
+
+    public function getSpecialPrice()
+    {
+        return $this->getData('special_price');
+    }
+
+    public function getSpecialToDate()
+    {
+        return $this->getData('special_to_date');
+    }
+
+    public function getStatus()
+    {
+        return $this->getData('status');
+    }
+
+    public function getTaxClassId()
+    {
+        return $this->getData('tax_class_id');
+    }
+
+    public function getThumbnail()
+    {
+        return $this->getData('thumbnail');
+    }
+
+    public function getThumbnailLabel()
+    {
+        return $this->getData('thumbnail_label');
+    }
+
+    public function getTierPrice()
+    {
+        return $this->getData('tier_price');
+    }
+
+    public function getUpdatedAt()
+    {
+        return $this->getData('updated_at');
+    }
+
+    public function getUpsellTgtrPositionBehavior()
+    {
+        return $this->getData('upsell_tgtr_position_behavior');
+    }
+
+    public function getUpsellTgtrPositionLimit()
+    {
+        return $this->getData('upsell_tgtr_position_limit');
+    }
+
+    public function getUrlKey()
+    {
+        return $this->getData('url_key');
+    }
+
+    public function getUrlPath()
+    {
+        return $this->getData('url_path');
+    }
+
+    public function getVisibility()
+    {
+        return $this->getData('visibility');
+    }
+
+    public function getWeight()
+    {
+        return $this->getData('weight');
+    }
+
+    public function getId()
+    {
+        return $this->getData('id');
+    }
+
+    public function getCustomOptions()
+    {
+        return $this->getData('custom_options');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bf08f36eef6985833150be34836355ebce953652
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml
@@ -0,0 +1,479 @@
+<?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\Downloadable\Test\Fixture\CatalogProductDownloadable">
+    <module>Magento_Downloadable</module>
+    <type>eav</type>
+    <entity_type>catalog_product</entity_type>
+    <product_type>downloadable</product_type>
+    <collection>Magento\Catalog\Model\Resource\Product\Collection</collection>
+    <identifier>sku</identifier>
+    <fields>
+        <category_ids>
+            <attribute_code>category_ids</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </category_ids>
+        <cost>
+            <attribute_code>cost</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>price</input>
+        </cost>
+        <created_at>
+            <attribute_code>created_at</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </created_at>
+        <custom_design>
+            <attribute_code>custom_design</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>select</input>
+        </custom_design>
+        <custom_design_from>
+            <attribute_code>custom_design_from</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </custom_design_from>
+        <custom_design_to>
+            <attribute_code>custom_design_to</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </custom_design_to>
+        <custom_layout_update>
+            <attribute_code>custom_layout_update</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </custom_layout_update>
+        <description>
+            <attribute_code>description</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </description>
+        <gallery>
+            <attribute_code>gallery</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>gallery</input>
+        </gallery>
+        <gift_message_available>
+            <attribute_code>gift_message_available</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>select</input>
+        </gift_message_available>
+        <group_price>
+            <attribute_code>group_price</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </group_price>
+        <has_options>
+            <attribute_code>has_options</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </has_options>
+        <image>
+            <attribute_code>image</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>media_image</input>
+        </image>
+        <image_label>
+            <attribute_code>image_label</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </image_label>
+        <is_returnable>
+            <attribute_code>is_returnable</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value>2</default_value>
+            <input>select</input>
+        </is_returnable>
+        <links_exist>
+            <attribute_code>links_exist</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </links_exist>
+        <links_purchased_separately>
+            <attribute_code>links_purchased_separately</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input></input>
+        </links_purchased_separately>
+        <links_title>
+            <attribute_code>links_title</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input></input>
+        </links_title>
+        <media_gallery>
+            <attribute_code>media_gallery</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>gallery</input>
+        </media_gallery>
+        <meta_description>
+            <attribute_code>meta_description</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </meta_description>
+        <meta_keyword>
+            <attribute_code>meta_keyword</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </meta_keyword>
+        <meta_title>
+            <attribute_code>meta_title</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </meta_title>
+        <minimal_price>
+            <attribute_code>minimal_price</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>price</input>
+        </minimal_price>
+        <msrp>
+            <attribute_code>msrp</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>price</input>
+        </msrp>
+        <msrp_display_actual_price_type>
+            <attribute_code>msrp_display_actual_price_type</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value>4</default_value>
+            <input>select</input>
+        </msrp_display_actual_price_type>
+        <msrp_enabled>
+            <attribute_code>msrp_enabled</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value>2</default_value>
+            <input>select</input>
+        </msrp_enabled>
+        <name>
+            <attribute_code>name</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </name>
+        <news_from_date>
+            <attribute_code>news_from_date</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </news_from_date>
+        <news_to_date>
+            <attribute_code>news_to_date</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </news_to_date>
+        <old_id>
+            <attribute_code>old_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </old_id>
+        <options_container>
+            <attribute_code>options_container</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value>container2</default_value>
+            <input>select</input>
+        </options_container>
+        <page_layout>
+            <attribute_code>page_layout</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>select</input>
+        </page_layout>
+        <price>
+            <attribute_code>price</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input>price</input>
+        </price>
+        <qty>
+            <attribute_code>quantity_and_stock_status][qty</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value>1</default_value>
+            <input>select</input>
+        </qty>
+        <related_tgtr_position_behavior>
+            <attribute_code>related_tgtr_position_behavior</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </related_tgtr_position_behavior>
+        <related_tgtr_position_limit>
+            <attribute_code>related_tgtr_position_limit</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </related_tgtr_position_limit>
+        <required_options>
+            <attribute_code>required_options</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </required_options>
+        <samples_title>
+            <attribute_code>samples_title</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input></input>
+        </samples_title>
+        <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>
+        </sku>
+        <small_image>
+            <attribute_code>small_image</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>media_image</input>
+        </small_image>
+        <small_image_label>
+            <attribute_code>small_image_label</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </small_image_label>
+        <special_from_date>
+            <attribute_code>special_from_date</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </special_from_date>
+        <special_price>
+            <attribute_code>special_price</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+        </special_price>
+        <special_to_date>
+            <attribute_code>special_to_date</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </special_to_date>
+        <status>
+            <attribute_code>status</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value>1</default_value>
+            <input>select</input>
+        </status>
+        <tax_class_id>
+            <attribute_code>tax_class_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value>2</default_value>
+            <input>select</input>
+        </tax_class_id>
+        <thumbnail>
+            <attribute_code>thumbnail</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>media_image</input>
+        </thumbnail>
+        <thumbnail_label>
+            <attribute_code>thumbnail_label</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </thumbnail_label>
+        <tier_price>
+            <attribute_code>tier_price</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </tier_price>
+        <updated_at>
+            <attribute_code>updated_at</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </updated_at>
+        <upsell_tgtr_position_behavior>
+            <attribute_code>upsell_tgtr_position_behavior</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </upsell_tgtr_position_behavior>
+        <upsell_tgtr_position_limit>
+            <attribute_code>upsell_tgtr_position_limit</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </upsell_tgtr_position_limit>
+        <url_key>
+            <attribute_code>url_key</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </url_key>
+        <url_path>
+            <attribute_code>url_path</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </url_path>
+        <visibility>
+            <attribute_code>visibility</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value>4</default_value>
+            <input>select</input>
+        </visibility>
+        <weight>
+            <attribute_code>weight</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>weight</input>
+        </weight>
+        <id>
+            <attribute_code>id</attribute_code>
+            <backend_type>virtual</backend_type>
+        </id>
+        <inventory_manage_stock>
+            <attribute_code>inventory_manage_stock</attribute_code>
+            <input>select</input>
+        </inventory_manage_stock>
+        <quantity_and_stock_status>
+            <attribute_code>quantity_and_stock_status</attribute_code>
+            <input>select</input>
+        </quantity_and_stock_status>
+        <inventory_qty>
+            <attribute_code>inventory_qty</attribute_code>
+            <input>text</input>
+        </inventory_qty>
+        <stock_data_use_config_min_qty>
+            <attribute_code>stock_data_use_config_min_qty</attribute_code>
+            <input>checkbox</input>
+        </stock_data_use_config_min_qty>
+        <stock_data_min_qty>
+            <attribute_code>stock_data_min_qty</attribute_code>
+            <input>text</input>
+        </stock_data_min_qty>
+    </fields>
+    <data_set>
+        <sku></sku>
+        <name></name>
+        <short_description></short_description>
+        <description></description>
+        <tax_class_id></tax_class_id>
+        <links_purchased_separately></links_purchased_separately>
+        <samples_title></samples_title>
+        <links_title></links_title>
+        <links_exist></links_exist>
+    </data_set>
+    <data_config>
+        <create_url_params>
+            <type>downloadable</type>
+            <set>4</set>
+        </create_url_params>
+        <input_prefix>product</input_prefix>
+    </data_config>
+    <repository_class>Magento\Downloadable\Test\Repository\CatalogProductDownloadable</repository_class>
+    <handler_interface>
+        Magento\Downloadable\Test\Handler\CatalogProductDownloadable\CatalogProductDownloadableInterface
+    </handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Links.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Links.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fdcb311173e00927db289c2faa9094b836ed884
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Links.php
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Fixture\CatalogProductDownloadable;
+
+use Mtf\Fixture\FixtureInterface;
+
+/**
+ * Class Links
+ *
+ * Preset for link block
+ */
+class Links implements FixtureInterface
+{
+    /**
+     * Construct for class
+     *
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(array $params, array $data = [])
+    {
+        $this->params = $params;
+        if (isset($data['preset'])) {
+            $this->data = $this->getPreset($data['preset']);
+        }
+    }
+
+    /**
+     * Persist group price
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param string $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;
+    }
+
+    /**
+     * Preset array for downloadable links
+     *
+     * @param string $name
+     * @return array|null
+     */
+    protected function getPreset($name)
+    {
+        $presets = [
+            'default' => [
+                'title' => 'Links%isolation%',
+                'links_purchased_separately' => 'Yes',
+                'downloadable' => [
+                    'link' => [
+                        [
+                            'title' => 'link1%isolation%',
+                            'price' => 2.43,
+                            'number_of_downloads' => 2,
+                            'sample' => [
+                                'sample_type_url' => 'Yes',
+                                'sample_url' => 'http://example.com'
+                            ],
+                            'file_type_url' => 'Yes',
+                            'file_link_url' => 'http://example.com',
+                            'is_shareable' => 'No',
+                            'sort_order' => 1
+                        ],
+                        [
+                            'title' => 'link2%isolation%',
+                            'price' => 3,
+                            'number_of_downloads' => 3,
+                            'sample' => [
+                                'sample_type_url' => 'Yes',
+                                'sample_url' => 'http://example3.com'
+                            ],
+                            'file_type_url' => 'Yes',
+                            'file_link_url' => 'http://example3.com',
+                            'is_shareable' => 'Yes',
+                            'sort_order' => 0
+                        ],
+                    ]
+                ]
+            ],
+            'with_three_links' => [
+                'title' => 'Links%isolation%',
+                'links_purchased_separately' => 'Yes',
+                'downloadable' => [
+                    'link' => [
+                        [
+                            'title' => 'link1%isolation%',
+                            'price' => 2.43,
+                            'number_of_downloads' => 2,
+                            'sample' => [
+                                'sample_type_url' => 'Yes',
+                                'sample_url' => 'http://example.com'
+                            ],
+                            'file_type_url' => 'Yes',
+                            'file_link_url' => 'http://example.com',
+                            'is_shareable' => 'No',
+                            'sort_order' => 0
+                        ],
+                        [
+                            'title' => 'link2%isolation%',
+                            'price' => 3,
+                            'number_of_downloads' => 3,
+                            'sample' => [
+                                'sample_type_url' => 'Yes',
+                                'sample_url' => 'http://example3.com'
+                            ],
+                            'file_type_url' => 'Yes',
+                            'file_link_url' => 'http://example3.com',
+                            'is_shareable' => 'Yes',
+                            'sort_order' => 1
+                        ],
+                        [
+                            'title' => 'link3%isolation%',
+                            'price' => 5.43,
+                            'number_of_downloads' => 5,
+                            'sample' => [
+                                'sample_type_url' => 'Yes',
+                                'sample_url' => 'http://example3.com'
+                            ],
+                            'file_type_url' => 'Yes',
+                            'file_link_url' => 'http://example3.com',
+                            'is_shareable' => 'Yes',
+                            'sort_order' => 2
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        if (!isset($presets[$name])) {
+            return null;
+        }
+        return $presets[$name];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Samples.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Samples.php
new file mode 100644
index 0000000000000000000000000000000000000000..cff42de45c75024e2347b36484ab4f3e927c6296
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Samples.php
@@ -0,0 +1,140 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Fixture\CatalogProductDownloadable;
+
+use Mtf\Fixture\FixtureInterface;
+
+/**
+ * Class Samples
+ *
+ * Preset for sample block
+ */
+class Samples implements FixtureInterface
+{
+    /**
+     * Construct for class
+     *
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(array $params, array $data = [])
+    {
+        $this->params = $params;
+        if (isset($data['preset'])) {
+            $this->data = $this->getPreset($data['preset']);
+        }
+    }
+
+    /**
+     * Persist group price
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param string $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;
+    }
+
+    /**
+     * Preset array for downloadable samples
+     *
+     * @param string $name
+     * @return array|null
+     */
+    protected function getPreset($name)
+    {
+        $presets = [
+            'default' => [
+                'title' => 'Samples%isolation%',
+                'downloadable' => [
+                    'sample' => [
+                        [
+                            'title' => 'sample1%isolation%',
+                            'sample_type_url' => 'Yes',
+                            'sample_url' => 'http://example.com',
+                            'sort_order' => 0
+                        ],
+                        [
+                            'title' => 'sample2%isolation%',
+                            'sample_type_url' => 'Yes',
+                            'sample_url' => 'http://example2.com',
+                            'sort_order' => 1
+                        ]
+                    ]
+                ]
+            ],
+            'with_three_samples' => [
+                'title' => 'Samples%isolation%',
+                'downloadable' => [
+                    'sample' => [
+                        [
+                            'title' => 'sample1%isolation%',
+                            'sample_type_url' => 'Yes',
+                            'sample_url' => 'http://example.com',
+                            'sort_order' => 0
+                        ],
+                        [
+                            'title' => 'sample2%isolation%',
+                            'sample_type_url' => 'Yes',
+                            'sample_url' => 'http://example2.com',
+                            'sort_order' => 1
+                        ],
+                        [
+                            'title' => 'sample3%isolation%',
+                            'sample_type_url' => 'Yes',
+                            'sample_url' => 'http://example3.com',
+                            'sort_order' => 2
+                        ]
+                    ]
+                ]
+            ]
+        ];
+        if (!isset($presets[$name])) {
+            return null;
+        }
+        return $presets[$name];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.php
index 0540fe6e0779d91381c734084a83ff7b219c2a22..2cf30517f9034c5632773127c6470e14d125294b 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct.php
@@ -26,6 +26,10 @@ namespace Magento\Downloadable\Test\Fixture;
 use Mtf\Factory\Factory;
 use Magento\Catalog\Test\Fixture\Product;
 
+/**
+ * Class DownloadableProduct
+ * Fixture for Downloadable product
+ */
 class DownloadableProduct extends Product
 {
     const GROUP = 'downloadable_information';
@@ -55,14 +59,7 @@ class DownloadableProduct extends Product
             'price' => [
                 'value' => '1',
                 'group' => static::GROUP_PRODUCT_DETAILS
-            ],
-            'downloadable_link_purchase_type' => [
-                'value' => 'Yes',
-                'input_value' => '1',
-                'group' => static::GROUP,
-                'input' => 'select',
-                'input_name' => 'links_purchased_separately'
-            ],
+            ]
         );
 
         $this->_data['fields'] = $data + $this->_data['fields'];
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct/LinksNotPurchasedSeparately.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct/LinksNotPurchasedSeparately.php
index cf7c630a14f54086d028e17c712176f7bd35cfe1..cdaebcff139fd8630665970e697108385671ea4d 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct/LinksNotPurchasedSeparately.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct/LinksNotPurchasedSeparately.php
@@ -26,10 +26,14 @@ namespace Magento\Downloadable\Test\Fixture\DownloadableProduct;
 use Mtf\Factory\Factory;
 use Magento\Downloadable\Test\Fixture\DownloadableProduct;
 
+/**
+ * Class LinksNotPurchasedSeparately
+ * Init downloadable data not purchased separately
+ */
 class LinksNotPurchasedSeparately extends LinksPurchasedSeparately
 {
     /**
-     * {inheritdoc}
+     * Init downloadable data
      */
     protected function _initData()
     {
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct/LinksPurchasedSeparately.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct/LinksPurchasedSeparately.php
index 1bc600cf159ddf223ca407c303a8675f924d1736..b8b9ac44a1c2e1b36d0b6e38a094ba68b1473cc7 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct/LinksPurchasedSeparately.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/DownloadableProduct/LinksPurchasedSeparately.php
@@ -26,10 +26,15 @@ namespace Magento\Downloadable\Test\Fixture\DownloadableProduct;
 use Mtf\Factory\Factory;
 use Magento\Downloadable\Test\Fixture\DownloadableProduct;
 
+/**
+ * Class LinksPurchasedSeparately
+ *
+ * Init downloadable data purchased separately
+ */
 class LinksPurchasedSeparately extends DownloadableProduct
 {
     /**
-     * {inheritdoc}
+     * Init downloadable data
      */
     protected function _initData()
     {
@@ -38,28 +43,30 @@ class LinksPurchasedSeparately extends DownloadableProduct
             $this->_data,
             [
                 'fields' => [
-                    'downloadable_link_purchase_type' => [
-                        'value' => 'Yes',
-                        'input_value' => '1',
-                    ],
-                    'downloadable' => [
-                        'link' => [
-                            [
-                                'title' => ['value' => 'row1'],
-                                'price' => ['value' => 2],
-                                'number_of_downloads' => ['value' => 2],
-                                'sample][type' => ['value' => 'url', 'input' => 'radio'],
-                                'sample][url' => ['value' => 'http://example.com'],
-                                'type' => ['value' => 'url', 'input' => 'radio'],
-                                'link_url' => ['value' => 'http://example.com'],
-                                'is_shareable' => [ // needed explicit default value for CURL handler
-                                    'input' => 'select',
-                                    'input_value' => static::LINK_IS_SHAREABLE_USE_CONFIG_VALUE,
+                    'downloadable_links' => [
+                        'value' => [
+                            'title' => 'Links%isolation%',
+                            'links_purchased_separately' => 'Yes',
+                            'downloadable' => [
+                                'link' => [
+                                    [
+                                        'title' => 'row1%isolation%',
+                                        'price' => 2.43,
+                                        'number_of_downloads' => 2,
+                                        'sample' => [
+                                            'sample_type_url' => 'Yes',
+                                            'sample_url' => 'http://example.com'
+                                        ],
+                                        'file_type_url' => 'Yes',
+                                        'file_link_url' => 'http://example.com',
+                                        'is_shareable' => 'No',
+                                        'sort_order' => 0
+                                    ]
                                 ],
                             ]
                         ],
                         'group' => static::GROUP
-                    ]
+                    ],
                 ]
             ]
         );
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/Curl/CreateDownloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/Curl/CreateDownloadable.php
index d458fe081b53be0e7cb3bd7736374c9c7445a305..b7c2d936812dbaed31dc3d0d196be6218efc3d43 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/Curl/CreateDownloadable.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/Curl/CreateDownloadable.php
@@ -78,6 +78,8 @@ class CreateDownloadable extends Curl
     }
 
     /**
+     * Prepare downloadable data
+     *
      * @param string $key
      * @param string|array $value
      * @return array
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Page/Product/CatalogProductView.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Page/Product/CatalogProductView.php
new file mode 100644
index 0000000000000000000000000000000000000000..729bf7c8c47a1e58743024a912fcbc50ef17fcf8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Page/Product/CatalogProductView.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Downloadable\Test\Page\Product;
+
+use Magento\Catalog\Test\Page\Product\CatalogProductView as ParentCatalogProductView;
+
+/**
+ * Class CatalogProductView
+ *
+ * Frontend downloadable product view page
+ */
+class CatalogProductView extends ParentCatalogProductView
+{
+    const MCA = 'downloadable/catalog/product/view';
+
+    /**
+     * Custom constructor
+     *
+     * @return void
+     */
+    protected function _init()
+    {
+        $this->_blocks['downloadableViewBlock'] = [
+            'name' => 'downloadableViewBlock',
+            'class' => 'Magento\Downloadable\Test\Block\Catalog\Product\View',
+            'locator' => '.product.info.main',
+            'strategy' => 'css selector',
+        ];
+        parent::_init();
+    }
+
+    /**
+     * @return \Magento\Downloadable\Test\Block\Catalog\Product\View
+     */
+    public function getDownloadableViewBlock()
+    {
+        return $this->getBlockInstance('downloadableViewBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Page/Product/CatalogProductView.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Page/Product/CatalogProductView.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2f62dab457f35ed6b1909a04a908fdbe69c12ba8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Page/Product/CatalogProductView.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)
+ */
+-->
+<page mca="catalog/product/view">
+    <block>
+        <name>downloadableViewBlock</name>
+        <class>Magento\Downloadable\Test\Block\Catalog\Product\View</class>
+        <locator>.product.info.main</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
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 274e3a47850a2a249a5022854902a4a807bffd05..a26211d4dd74c5c712e178f2db8439744ae976e2 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
@@ -45,7 +45,6 @@ class LinksPurchasedSeparatelyTest extends Functional
         $this->product = Factory::getFixtureFactory()
             ->getMagentoDownloadableDownloadableProductLinksPurchasedSeparately();
         $this->product->switchData('downloadable');
-
         Factory::getApp()->magentoBackendLoginUser();
     }
 
@@ -57,15 +56,17 @@ class LinksPurchasedSeparatelyTest extends Functional
      */
     public function test()
     {
-        $createProductPage = Factory::getPageFactory()->getCatalogProductNew();
-        $createProductPage->init($this->product);
-        $productForm = $createProductPage->getProductForm();
-
+        $createProductPage = Factory::getPageFactory()->getCatalogProductIndex();
         $createProductPage->open();
-        $productForm->fill($this->product);
-        $createProductPage->getFormAction()->save();
+        $createProductPage->getProductBlock()->addProduct('downloadable');
+
+        $createProductPageNew = Factory::getPageFactory()->getCatalogProductNew();
+        $productBlockForm = $createProductPageNew->getForm();
+
+        $productBlockForm->fillProduct($this->product);
+        $createProductPageNew->getFormAction()->save();
 
-        $createProductPage->getMessagesBlock()->assertSuccessMessage();
+        $createProductPageNew->getMessagesBlock()->assertSuccessMessage();
 
         $cachePage = Factory::getPageFactory()->getAdminCache();
         $cachePage->open();
@@ -99,7 +100,7 @@ class LinksPurchasedSeparatelyTest extends Functional
         $product = $this->product;
         $frontendHomePage = Factory::getPageFactory()->getCmsIndexIndex();
         $categoryPage = Factory::getPageFactory()->getCatalogCategoryView();
-        $productPage = Factory::getPageFactory()->getCatalogProductView();
+        $productPage = Factory::getPageFactory()->getDownloadableCatalogProductView();
 
         $frontendHomePage->open();
         $frontendHomePage->getTopmenu()->selectCategoryByName($product->getCategoryName());
@@ -108,18 +109,21 @@ class LinksPurchasedSeparatelyTest extends Functional
         $this->assertTrue($productListBlock->isProductVisible($product->getProductName()));
         $productListBlock->openProductViewPage($product->getProductName());
 
-        $productViewBlock = $productPage->getViewBlock();
+        $productViewBlock = $productPage->getDownloadableViewBlock();
         $this->assertEquals($product->getProductName(), $productViewBlock->getProductName());
-        $price = $productViewBlock->getProductPrice();
-        $this->assertEquals(number_format($product->getProductPrice(), 2), $price['price_regular_price']);
+        $this->assertEquals(
+            sprintf('%1.2f', $product->getProductPrice()),
+            $productViewBlock->getProductPrice()['price_regular_price']
+        );
 
-        $productPage->getDownloadableLinksBlock()
-            ->check([['title' => $product->getData('fields/downloadable/link/0/title/value')]]);
+        $this->assertEquals(
+            $productPage->getDownloadableViewBlock()->getDownloadableLinksBlock()->getItemTitle(1),
+            $product->getData('fields/downloadable_links/value/downloadable/link/0/title')
+        );
 
-        $price = $productViewBlock->getProductPrice();
         $this->assertEquals(
-            number_format($product->getProductPrice() + $product->getData('fields/downloadable/link/0/price/value'), 2),
-            $price['price_regular_price']
+            sprintf('$%1.2f', $product->getData('fields/downloadable_links/value/downloadable/link/0/price')),
+            $productPage->getDownloadableViewBlock()->getDownloadableLinksBlock()->getItemPrice(1)
         );
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a63ccb7a77364ad6037cea5f00d96677d5848dc4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Downloadable\Test\TestCase;
+
+use Mtf\TestCase\Injectable;
+use Magento\Catalog\Test\Fixture\CatalogCategoryEntity;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductNew;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+use Magento\Downloadable\Test\Fixture\CatalogProductDownloadable;
+
+/**
+ * Test Creation for Create DownloadableProductEntity
+ *
+ * Test Flow:
+ * 1. Log in to Backend.
+ * 2. Navigate to Products > Catalog.
+ * 3. Start to create new Downloadable product.
+ * 4. Fill in data according to data set.
+ * 5. Fill Downloadable Information tab according to data set.
+ * 6. Save product.
+ * 7. Verify created product.
+ *
+ * @group Downloadable_Product_(CS)
+ * @ZephyrId MAGETWO-23425
+ */
+class CreateDownloadableProductEntityTest extends Injectable
+{
+    /**
+     * Fixture category
+     *
+     * @var CatalogCategoryEntity
+     */
+    protected $category;
+
+    /**
+     * Product page with a grid
+     *
+     * @var CatalogProductIndex
+     */
+    protected $catalogProductIndex;
+
+    /**
+     * New product page on backend
+     *
+     * @var CatalogProductNew
+     */
+    protected $catalogProductNew;
+
+    /**
+     * Persist category
+     *
+     * @param CatalogCategoryEntity $category
+     * @return array
+     */
+    public function __prepare(CatalogCategoryEntity $category)
+    {
+        $category->persist();
+        return [
+            'category' => $category
+        ];
+    }
+
+    /**
+     * Filling objects of the class
+     *
+     * @param CatalogCategoryEntity $category
+     * @param CatalogProductIndex $catalogProductIndexNewPage
+     * @param CatalogProductNew $catalogProductNewPage
+     */
+    public function __inject(
+        CatalogCategoryEntity $category,
+        CatalogProductIndex $catalogProductIndexNewPage,
+        CatalogProductNew $catalogProductNewPage
+    ) {
+        $this->category = $category;
+        $this->catalogProductIndex = $catalogProductIndexNewPage;
+        $this->catalogProductNew = $catalogProductNewPage;
+    }
+
+    /**
+     * Test create downloadable product
+     *
+     * @param CatalogProductDownloadable $product
+     * @param CatalogCategoryEntity $category
+     */
+    public function testCreateDownloadableProduct(CatalogProductDownloadable $product, CatalogCategoryEntity $category)
+    {
+        $this->catalogProductIndex->open();
+        $this->catalogProductIndex->getProductBlock()->addProduct('downloadable');
+        $productBlockForm = $this->catalogProductNew->getForm();
+        $productBlockForm->fillProduct($product, $category);
+        $this->catalogProductNew->getFormAction()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv
new file mode 100644
index 0000000000000000000000000000000000000000..bd7bc3f326ba6bed2e246ec8f556861eaeb19c74
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv
@@ -0,0 +1,15 @@
+product/data/name;product/data/sku;product/data/price;product/data/tax_class;product/data/qty;product/data/quantity_and_stock_status;product/data/is_virtual;product/data/category;product/data/description;product/data/short_description;product/data/inventory_manage_stock;product/data/inventory_qty;product/data/stock_data_use_config_min_qty;product/data/stock_data_min_qty;product/data/downloadable_sample/preset;product/data/downloadable_links/preset;product/data/custom_options/preset;product/data/special_price;product/data/group_price/preset;product/data/tier_price/preset;constraint
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;100;Taxable Goods;1;In Stock;Yes;Default Category;-;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage, assertProductInStock
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;1;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;default;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertDownloadableSamplesData, assertDownloadableLinks
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;33;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;default;default;-;-;-;assertProductSaveMessage, assertDownloadableProductForm, assertCustomOptionsOnProductPage, assertProductVisibleInCategory, assertProductPage, assertDownloadableLinks
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;55;Taxable Goods;10;In Stock;Yes;-;-;-;-;-;-;-;with_three_samples;with_three_links;two_options;-;-;-;assertProductSaveMessage, assertCustomOptionsOnProductPage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage, assertDownloadableLinks, assertProductInStock, assertProductSearchableBySku
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;100;Taxable Goods;50;Out of Stock;Yes;Default Category;-;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertProductOutOfStock, assertProductInGrid, assertDownloadableProductForm
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;9999;Taxable Goods;-;-;Yes;Default Category;-;-;Yes;123;No;123;-;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductOutOfStock
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;98;None;5;In Stock;Yes;Default Category;This is description for downloadable product;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;57;Taxable Goods;10;In Stock;Yes;category %isolation%;-;This is short description for downloadable product;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertCustomOptionsOnProductPage, assertDownloadableSamplesData, assertDownloadableLinks
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;65;Taxable Goods;11;In Stock;Yes;category %isolation%;This is description for downloadable product;This is short description for downloadable product;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductPage, assertProductInGrid, assertDownloadableProductForm, assertCustomOptionsOnProductPage, assertDownloadableSamplesData, assertDownloadableLinks
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;65;Taxable Goods;11;In Stock;Yes;category %isolation%;-;-;-;-;-;-;default;with_three_links;default;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertDownloadableLinks, assertCustomOptionsOnProductPage
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;100;Taxable Goods;-;-;Yes;Default Category;-;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;10;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;5;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertSpecialPriceOnProductPage
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;365;Taxable Goods;23;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;-;default;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertGroupedPriceOnProductPage
+DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;250;Taxable Goods;65;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;-;-;-;-;default;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertTierPriceOnProductPage
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/etc/global/constraint.xml
new file mode 100644
index 0000000000000000000000000000000000000000..113ed007c23533cb7fb6c3b6d8a7b030efbc7623
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/etc/global/constraint.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<constraint>
+    <assertDownloadableSamplesData module="Magento_Downloadable">
+        <severeness>low</severeness>
+    </assertDownloadableSamplesData>
+    <assertDownloadableLinks module="Magento_Downloadable">
+        <severeness>low</severeness>
+    </assertDownloadableLinks>
+    <assertDownloadableProductForm module="Magento_Downloadable">
+        <severeness>low</severeness>
+    </assertDownloadableProductForm>
+</constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/Form.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..531eccf27ba355654fe3c5e6e813c777e57fb459
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/Form.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Block\Adminhtml\Rate\Edit;
+
+use Mtf\Block\Form as FormInterface;
+
+/**
+ * Class Form
+ * Form for tax rate creation
+ */
+class Form extends FormInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/Form.xml
new file mode 100644
index 0000000000000000000000000000000000000000..870d48b5988eb33af65e283acc957f7bc9c5987f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/Form.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>
+        <code />
+        <rate />
+        <zip_is_range>
+            <input>checkbox</input>
+        </zip_is_range>
+        <tax_postcode />
+        <zip_from />
+        <zip_to />
+        <tax_country_id>
+            <input>select</input>
+        </tax_country_id>
+        <tax_region_id>
+            <input>select</input>
+        </tax_region_id>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/FormPageActions.php
new file mode 100644
index 0000000000000000000000000000000000000000..01f0c1fc60f8343606c5cb533c047676ca3e4045
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Edit/FormPageActions.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Block\Adminhtml\Rate\Edit;
+
+use Magento\Backend\Test\Block\FormPageActions as FormPageActionsInterface;
+
+/**
+ * Class FormPageActions
+ * Form page actions block in Tax Rate new/edit page
+ */
+class FormPageActions extends FormPageActionsInterface
+{
+    /**
+     * "Save Rate" button
+     *
+     * @var string
+     */
+    protected $saveButton = '.save-rate';
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Grid.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc8241419861f7a6e38bed7bce349ae8c47d0232
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Block/Adminhtml/Rate/Grid.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Block\Adminhtml\Rate;
+
+use Magento\Backend\Test\Block\Widget\Grid as GridInterface;
+
+/**
+ * Class Grid
+ * Adminhtml Tax Rates management grid
+ */
+class Grid extends GridInterface
+{
+    /**
+     * Locator value for opening needed row
+     *
+     * @var string
+     */
+    protected $editLink = 'td[class*=col-code]';
+
+    /**
+     * Initialize block elements
+     *
+     * @var array
+     */
+    protected $filters = [
+        'code' => [
+            'selector' => '#tax_rate_grid_filter_code',
+        ],
+        'tax_country_id' => [
+            'selector' => '#tax_rate_grid_filter_tax_country_id',
+            'input' => 'select',
+        ],
+        'tax_postcode' => [
+            'selector' => '#tax_rate_grid_filter_tax_postcode',
+        ],
+    ];
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateForm.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e7fa32068bfb9123aed780fabded52de590fe1b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateForm.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Tax\Test\Page\Adminhtml\TaxRateIndex;
+use Magento\Tax\Test\Page\Adminhtml\TaxRateNew;
+use Magento\Tax\Test\Fixture\TaxRate;
+
+/**
+ * Class AssertTaxRateForm
+ */
+class AssertTaxRateForm extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert that tax rate form filled correctly
+     *
+     * @param TaxRateIndex $taxRateIndexPage
+     * @param TaxRateNew $taxRateNewPage
+     * @param TaxRate $taxRate
+     * @param TaxRate $initialTaxRate
+     * @return void
+     */
+    public function processAssert(
+        TaxRateIndex $taxRateIndexPage,
+        TaxRateNew $taxRateNewPage,
+        TaxRate $taxRate,
+        TaxRate $initialTaxRate = null
+    ) {
+        $data = ($initialTaxRate !== null)
+            ? array_merge($initialTaxRate->getData(), $taxRate->getData())
+            : $taxRate->getData();
+        $data = $this->prepareData($data);
+        $filter = [
+            'code' => $data['code'],
+        ];
+
+        $taxRateIndexPage->open();
+        $taxRateIndexPage->getTaxRateGrid()->searchAndOpen($filter);
+        $formData = $taxRateNewPage->getTaxRateForm()->getData($taxRate);
+        $dataDiff = $this->verifyForm($formData, $data);
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($dataDiff),
+            'Tax Rate form was filled incorrectly.'
+            . "\nLog:\n" . implode(";\n", $dataDiff)
+        );
+    }
+
+    /**
+     * Preparing data for verification
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function prepareData(array $data)
+    {
+        if ($data['zip_is_range'] === 'Yes') {
+            unset($data['tax_postcode']);
+        } else {
+            unset($data['zip_from'], $data['zip_to']);
+        }
+        $data['rate'] = number_format($data['rate'], 4);
+
+        return $data;
+    }
+
+    /**
+     * Verifying that form is filled correctly
+     *
+     * @param array $formData
+     * @param array $fixtureData
+     * @return array $errorMessages
+     */
+    protected function verifyForm(array $formData, array $fixtureData)
+    {
+        $errorMessages = [];
+
+        foreach ($fixtureData as $key => $value) {
+            if ($key === 'id') {
+                continue;
+            }
+            if ($value !== $formData[$key]) {
+                $errorMessages[] = "Data in " . $key . " field not equal."
+                    . "\nExpected: " . $value
+                    . "\nActual: " . $formData[$key];
+            }
+        }
+
+        return $errorMessages;
+    }
+
+    /**
+     * Text that form was filled correctly
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Tax Rate form was filled correctly.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateInGrid.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6314af8ad899cb552a7345a630ca2380452061b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateInGrid.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\Tax\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Tax\Test\Page\Adminhtml\TaxRateIndex;
+use Magento\Tax\Test\Fixture\TaxRate;
+
+/**
+ * Class AssertTaxRateInGrid
+ */
+class AssertTaxRateInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert tax rule availability in Tax Rate grid
+     *
+     * @param TaxRateIndex $taxRateIndexPage
+     * @param TaxRate $taxRate
+     * @param TaxRate $initialTaxRate
+     * @return void
+     */
+    public function processAssert(
+        TaxRateIndex $taxRateIndexPage,
+        TaxRate $taxRate,
+        TaxRate $initialTaxRate = null
+    ) {
+        $data = ($initialTaxRate === null)
+            ? $taxRate->getData()
+            : array_merge($initialTaxRate->getData(), $taxRate->getData());
+        $filter = [
+            'code' => $data['code'],
+            'tax_country_id' => $data['tax_country_id'],
+        ];
+        $filter['tax_postcode'] = ($data['zip_is_range'] === 'No')
+            ? $data['tax_postcode']
+            : $data['zip_from'] . '-' . $data['zip_to'];
+
+        $taxRateIndexPage->open();
+        \PHPUnit_Framework_Assert::assertTrue(
+            $taxRateIndexPage->getTaxRateGrid()->isRowVisible($filter),
+            'Tax Rate \'' . $filter['code'] . '\' is absent in Tax Rate grid.'
+        );
+    }
+
+    /**
+     * Text of Tax Rate in grid assert
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Tax rate is present in grid.';
+    }
+}
diff --git a/app/code/Magento/OfflinePayments/Model/Ccsave.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateIsInCorrectRange.php
similarity index 70%
rename from app/code/Magento/OfflinePayments/Model/Ccsave.php
rename to dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateIsInCorrectRange.php
index 2ba4606708d016822ce914ebc6e193c7c7030a79..c940134113f1eb910e3a211c346f432aab9ac163 100644
--- a/app/code/Magento/OfflinePayments/Model/Ccsave.php
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateIsInCorrectRange.php
@@ -21,27 +21,36 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\OfflinePayments\Model;
 
-class Ccsave extends \Magento\Payment\Model\Method\Cc
+namespace Magento\Tax\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertTaxRateIsInCorrectRange
+ */
+class AssertTaxRateIsInCorrectRange extends AbstractConstraint
 {
     /**
+     * Constraint severeness
+     *
      * @var string
      */
-    protected $_code = 'ccsave';
+    protected $severeness = 'low';
 
     /**
-     * @var bool
+     * @return void
      */
-    protected $_canSaveCc = true;
+    public function processAssert()
+    {
+        //
+    }
 
     /**
-     * @var string
-     */
-    protected $_formBlockType = 'Magento\OfflinePayments\Block\Form\Ccsave';
-
-    /**
-     * @var string
+     * @return string
      */
-    protected $_infoBlockType = 'Magento\OfflinePayments\Block\Info\Ccsave';
+    public function toString()
+    {
+        //
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateSuccessSaveMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..9826d5ab2fea1f27ca7cf3ee42473179eb0a9861
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRateSuccessSaveMessage.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 Mtf\Constraint\AbstractConstraint;
+use Magento\Tax\Test\Page\Adminhtml\TaxRateIndex;
+
+/**
+ * Class AssertTaxRateSuccessSaveMessage
+ */
+class AssertTaxRateSuccessSaveMessage extends AbstractConstraint
+{
+    const SUCCESS_MESSAGE = 'The tax rate has been saved.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert that success message is displayed after tax rate saved
+     *
+     * @param TaxRateIndex $taxRateIndexPage
+     * @return void
+     */
+    public function processAssert(TaxRateIndex $taxRateIndexPage)
+    {
+        $actualMessage = $taxRateIndexPage->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 Rate Success Message assert
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Tax rate success create message is present.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleIsApplied.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleIsApplied.php
new file mode 100644
index 0000000000000000000000000000000000000000..94f6c54145f4f224341b61fc00511287ff9a1f02
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleIsApplied.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Constraint;
+
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Checkout\Test\Page\CheckoutCart;
+use Magento\Customer\Test\Fixture\AddressInjectable;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Customer\Test\Page\CustomerAccountLogin;
+use Magento\Customer\Test\Page\CustomerAccountLogout;
+use Magento\Tax\Test\Fixture\TaxRule;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertTaxRuleIsApplied
+ */
+class AssertTaxRuleIsApplied extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert that tax rule is applied on product in shopping cart.
+     *
+     * @param TaxRule $taxRule
+     * @param CustomerAccountLogin $customerAccountLogin
+     * @param CustomerAccountLogout $customerAccountLogout
+     * @param CustomerInjectable $customer
+     * @param CatalogProductView $catalogProductView
+     * @param CatalogProductSimple $productSimple
+     * @param CheckoutCart $checkoutCart
+     * @param AddressInjectable $address
+     * @param array $shipping
+     * @return void
+     */
+    public function processAssert(
+        TaxRule $taxRule,
+        CustomerAccountLogin $customerAccountLogin,
+        CustomerAccountLogout $customerAccountLogout,
+        CustomerInjectable $customer,
+        CatalogProductView $catalogProductView,
+        CatalogProductSimple $productSimple,
+        CheckoutCart $checkoutCart,
+        AddressInjectable $address,
+        array $shipping
+    ) {
+        $errorMessages = [];
+        // Customer login
+        $customerAccountLogout->open();
+        $customerAccountLogin->open();
+        $customerAccountLogin->getLoginBlock()->login($customer);
+        // Clearing shopping cart and adding product to shopping cart
+        $checkoutCart->open()->getCartBlock()->clearShoppingCart();
+        $catalogProductView->init($productSimple);
+        $catalogProductView->open();
+        $catalogProductView->getViewBlock()->clickAddToCart();
+        // Estimate Shipping and Tax
+        $checkoutCart->getShippingBlock()->openEstimateShippingAndTax();
+        $checkoutCart->getShippingBlock()->fill($address);
+        $checkoutCart->getShippingBlock()->clickGetQuote();
+        $checkoutCart->getShippingBlock()->selectShippingMethod($shipping);
+        // Preparing data to compare
+        $taxRate = $taxRule->getDataFieldConfig('tax_rate')['source']->getFixture()[0]->getRate();
+        $expectedGrandTotal = $productSimple->getPrice() + $taxRate + $shipping['price'];
+        $expectedGrandTotal = number_format($expectedGrandTotal, 2);
+        $actualGrandTotal = $checkoutCart->getTotalsBlock()->getGrandTotal();
+
+        if ($checkoutCart->getTotalsBlock()->isTaxVisible()) {
+            $expectedTax = number_format($taxRate, 2);
+            $actualTax = $checkoutCart->getTotalsBlock()->getTax();
+            if ($expectedTax !== $actualTax) {
+                $errorMessages[] = 'Tax is not correct.'
+                    . "\nExpected: " . $expectedTax
+                    . "\nActual: " . $actualTax;
+            }
+        }
+        if ($expectedGrandTotal !== $actualGrandTotal) {
+            $errorMessages[] = 'Grand Total is not correct.'
+                . "\nExpected: " . $expectedGrandTotal
+                . "\nActual: " . $actualGrandTotal;
+        }
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($errorMessages),
+            implode(";\n", $errorMessages)
+        );
+    }
+
+    /**
+     * Text of Tax Rule is applied on product in shopping cart.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Tax rule applied on product in shopping cart.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleIsNotApplied.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleIsNotApplied.php
new file mode 100644
index 0000000000000000000000000000000000000000..c80b20ad4fd768fbe33115cbd4637e8b897461a7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Constraint/AssertTaxRuleIsNotApplied.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\Constraint;
+
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Checkout\Test\Page\CheckoutCart;
+use Magento\Customer\Test\Fixture\AddressInjectable;
+use Magento\Customer\Test\Fixture\CustomerInjectable;
+use Magento\Customer\Test\Page\CustomerAccountLogin;
+use Magento\Customer\Test\Page\CustomerAccountLogout;
+use Magento\Tax\Test\Fixture\TaxRule;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertTaxRuleIsNotApplied
+ */
+class AssertTaxRuleIsNotApplied extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert that tax rule is not applied on product in shopping cart.
+     *
+     * @param TaxRule $taxRule
+     * @param CustomerAccountLogin $customerAccountLogin
+     * @param CustomerAccountLogout $customerAccountLogout
+     * @param CustomerInjectable $customer
+     * @param CatalogProductView $catalogProductView
+     * @param CatalogProductSimple $productSimple
+     * @param CheckoutCart $checkoutCart
+     * @param AddressInjectable $address
+     * @param array $shipping
+     * @param TaxRule $initialTaxRule
+     * @return void
+     */
+    public function processAssert(
+        TaxRule $taxRule,
+        CustomerAccountLogin $customerAccountLogin,
+        CustomerAccountLogout $customerAccountLogout,
+        CustomerInjectable $customer,
+        CatalogProductView $catalogProductView,
+        CatalogProductSimple $productSimple,
+        CheckoutCart $checkoutCart,
+        AddressInjectable $address,
+        array $shipping,
+        TaxRule $initialTaxRule = null
+    ) {
+        $errorMessages = [];
+        if ($initialTaxRule !== null) {
+            $taxRuleCode = ($taxRule->hasData('code')) ? $taxRule->getCode() : $initialTaxRule->getCode();
+        } else {
+            $taxRuleCode = $taxRule->getCode();
+        }
+        // Customer login
+        $customerAccountLogout->open();
+        $customerAccountLogin->open();
+        $customerAccountLogin->getLoginBlock()->login($customer);
+        // Clearing shopping cart and adding product to shopping cart
+        $checkoutCart->open()->getCartBlock()->clearShoppingCart();
+        $catalogProductView->init($productSimple);
+        $catalogProductView->open();
+        $catalogProductView->getViewBlock()->clickAddToCart();
+        // Estimate Shipping and Tax
+        $checkoutCart->getShippingBlock()->openEstimateShippingAndTax();
+        $checkoutCart->getShippingBlock()->fill($address);
+        $checkoutCart->getShippingBlock()->clickGetQuote();
+        $checkoutCart->getShippingBlock()->selectShippingMethod($shipping);
+        // Preparing data to compare
+        $expectedGrandTotal = $productSimple->getPrice() + $shipping['price'];
+        $expectedGrandTotal = number_format($expectedGrandTotal, 2);
+        $actualGrandTotal = $checkoutCart->getTotalsBlock()->getGrandTotal();
+
+        if ($checkoutCart->getTotalsBlock()->isTaxVisible()) {
+            $errorMessages[] = 'Tax Rule \'' . $taxRuleCode . '\' present in shopping cart.';
+        }
+        if ($expectedGrandTotal !== $actualGrandTotal) {
+            $errorMessages[] = 'Grand Total is not correct.'
+                . "\nExpected: " . $expectedGrandTotal
+                . "\nActual: " . $actualGrandTotal;
+        }
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($errorMessages),
+            implode(";\n", $errorMessages)
+        );
+    }
+
+    /**
+     * Text of Tax Rule is not applied on product in shopping cart.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Tax rule was not applied on product in shopping cart.";
+    }
+}
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 a71e5f2953b5561e4cea804e3ec965c487edbf23..7a25175cd950b388ca15b4421fea371456145f12 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
@@ -46,7 +46,7 @@ class TaxRate extends InjectableFixture
         'rate' => '10',
         'tax_country_id' => 'United States',
         'tax_postcode' => '*',
-        'tax_region_id' => '0',
+        'tax_region_id' => 'California',
     ];
 
     protected $tax_calculation_rate_id = [
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateIndex.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d7384ad5fa1bc38b5837437ccec0e6dc958b9d7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateIndex.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 TaxRateIndex
+ */
+class TaxRateIndex extends BackendPage
+{
+    const MCA = 'tax/rate/index';
+
+    protected $_blocks = [
+        'gridPageActions' => [
+            'name' => 'gridPageActions',
+            'class' => 'Magento\Backend\Test\Block\GridPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'taxRateGrid' => [
+            'name' => 'taxRateGrid',
+            'class' => 'Magento\Tax\Test\Block\Adminhtml\Rate\Grid',
+            'locator' => '#tax_rate_grid',
+            '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\Rate\Grid
+     */
+    public function getTaxRateGrid()
+    {
+        return $this->getBlockInstance('taxRateGrid');
+    }
+
+    /**
+     * @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/TaxRateIndex.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6de779d910f0cc5dd857139b8d89d27e445754be
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateIndex.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/rate/index" >
+    <block>
+        <name>gridPageActions</name>
+        <class>Magento\Backend\Test\Block\GridPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>taxRateGrid</name>
+        <class>Magento\Tax\Test\Block\Adminhtml\Rate\Grid</class>
+        <locator>#tax_rate_grid</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/TaxRateNew.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateNew.php
new file mode 100644
index 0000000000000000000000000000000000000000..50e57e8bdc4a05756f8fb02c5f777fad83e00dea
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateNew.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 TaxRateNew
+ */
+class TaxRateNew extends BackendPage
+{
+    const MCA = 'tax/rate/add';
+
+    protected $_blocks = [
+        'formPageActions' => [
+            'name' => 'formPageActions',
+            'class' => 'Magento\Tax\Test\Block\Adminhtml\Rate\Edit\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'taxRateForm' => [
+            'name' => 'taxRateForm',
+            'class' => 'Magento\Tax\Test\Block\Adminhtml\Rate\Edit\Form',
+            'locator' => '#rate-form',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Tax\Test\Block\Adminhtml\Rate\Edit\FormPageActions
+     */
+    public function getFormPageActions()
+    {
+        return $this->getBlockInstance('formPageActions');
+    }
+
+    /**
+     * @return \Magento\Tax\Test\Block\Adminhtml\Rate\Edit\Form
+     */
+    public function getTaxRateForm()
+    {
+        return $this->getBlockInstance('taxRateForm');
+    }
+
+    /**
+     * @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/TaxRateNew.xml b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateNew.xml
new file mode 100644
index 0000000000000000000000000000000000000000..276f7f8a4d3c9caefa8344a0216cc3e4f7c37035
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/Page/Adminhtml/TaxRateNew.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/rate/add" >
+    <block>
+        <name>formPageActions</name>
+        <class>Magento\Tax\Test\Block\Adminhtml\Rate\Edit\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>taxRateForm</name>
+        <class>Magento\Tax\Test\Block\Adminhtml\Rate\Edit\Form</class>
+        <locator>#rate-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/Repository/TaxRate.php b/dev/tests/functional/tests/app/Magento/Tax/Test/Repository/TaxRate.php
index 958373b4dc044d829b717addd416448cfa5a7914..7f220dafe5cb0c560a4f7616d17c1fcd6d535522 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
@@ -93,7 +93,7 @@ class TaxRate extends AbstractRepository
 
         $this->_data['uk_full_tax_rate'] = [
             'code' => 'Tax Rate %isolation%',
-            'rate' => '10',
+            'rate' => '20',
             'tax_country_id' => 'United Kingdom',
             'tax_postcode' => '*',
         ];
@@ -114,5 +114,21 @@ class TaxRate extends AbstractRepository
             'tax_region_id' => 'California',
             'rate' => '15.5'
         ];
+
+        $this->_data['withFixedZip'] = [
+            'code' => 'TaxIdentifier%isolation%',
+            'tax_postcode' => '*',
+            'tax_country_id' => 'United States',
+            'tax_region_id' => 'Texas',
+            'rate' => '20'
+        ];
+
+        $this->_data['us_ut_fixed_zip_rate_20'] = [
+            'code' => 'TaxIdentifier%isolation%',
+            'tax_postcode' => '84001',
+            'tax_country_id' => 'United States',
+            'tax_region_id' => 'Utah',
+            'rate' => '20'
+        ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..48b97c21b3ac357ad63a251e156017db578b649b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\TestCase;
+
+use Magento\Tax\Test\Fixture\TaxRate;
+use Magento\Tax\Test\Page\Adminhtml\TaxRateIndex;
+use Magento\Tax\Test\Page\Adminhtml\TaxRateNew;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for UpdateTaxRateEntity
+ *
+ * Test Flow:
+ * Preconditions:
+ * 1. Create Tax Rate.
+ *
+ * Steps:
+ * 1. Login to backend.
+ * 2. Navigate to Stores -> Taxes -> Tax Zones and Rates.
+ * 3. Search tax rate in grid by given data.
+ * 4. Open this tax rate by clicking.
+ * 5. Edit test value(s) according to dataset.
+ * 6. Click 'Save Rate' button.
+ * 7. Perform asserts.
+ *
+ * @group Tax_(CS)
+ * @ZephyrId MAGETWO-23299
+ */
+class UpdateTaxRateEntityTest extends Injectable
+{
+    /**
+     * Tax Rate grid page
+     *
+     * @var TaxRateIndex
+     */
+    protected $taxRateIndex;
+
+    /**
+     * Tax Rate new/edit page
+     *
+     * @var TaxRateNew
+     */
+    protected $taxRateNew;
+
+    /**
+     * Injection data
+     *
+     * @param TaxRateIndex $taxRateIndex
+     * @param TaxRateNew $taxRateNew
+     * @return void
+     */
+    public function __inject(
+        TaxRateIndex $taxRateIndex,
+        TaxRateNew $taxRateNew
+    ) {
+        $this->taxRateIndex = $taxRateIndex;
+        $this->taxRateNew = $taxRateNew;
+    }
+
+    /**
+     * Update Tax Rate Entity test
+     *
+     * @param TaxRate $initialTaxRate
+     * @param TaxRate $taxRate
+     * @return void
+     */
+    public function testUpdateTaxRate(
+        TaxRate $initialTaxRate,
+        TaxRate $taxRate
+    ) {
+        // Precondition
+        $initialTaxRate->persist();
+
+        // Steps
+        $filter = [
+            'code' => $initialTaxRate->getCode(),
+        ];
+        $this->taxRateIndex->open();
+        $this->taxRateIndex->getTaxRateGrid()->searchAndOpen($filter);
+        $this->taxRateNew->getTaxRateForm()->fill($taxRate);
+        $this->taxRateNew->getFormPageActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest/testUpdateTaxRate.csv b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest/testUpdateTaxRate.csv
new file mode 100644
index 0000000000000000000000000000000000000000..a2d457148db738336649ed85fd5c6ee4a9e9133a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRateEntityTest/testUpdateTaxRate.csv
@@ -0,0 +1,7 @@
+"initialTaxRate/dataSet";"taxRate/data/code";"taxRate/data/zip_is_range";"taxRate/data/zip_from";"taxRate/data/zip_to";"taxRate/data/tax_postcode";"taxRate/data/tax_country_id";"taxRate/data/tax_region_id";"taxRate/data/rate";"constraint"
+"default";"TaxIdentifier%isolation%";"No";"-";"-";"90001";"United States";"California";"100";"assertTaxRateSuccessSaveMessage, assertTaxRateInGrid, assertTaxRateForm"
+"default";"TaxIdentifier%isolation%";"Yes";"90001";"96162";"-";"United States";"California";"15.05";"assertTaxRateSuccessSaveMessage, assertTaxRateInGrid, assertTaxRateForm"
+"default";"TaxIdentifier%isolation%";"No";"-";"-";"*";"United Kingdom";"*";"777";"assertTaxRateIsInCorrectRange"
+"withZipRange";"TaxIdentifier%isolation%";"No";"-";"-";"180";"Canada";"*";"25";"assertTaxRateSuccessSaveMessage, assertTaxRateInGrid, assertTaxRateForm"
+"withZipRange";"TaxIdentifier%isolation%";"Yes";"0";"7800935";"-";"United Kingdom";"*";"0";"assertTaxRateIsInCorrectRange"
+"withZipRange";"TaxIdentifier%isolation%";"No";"-";"-";"*";"France";"Val-d'Oise";"0.1";"assertTaxRateSuccessSaveMessage, assertTaxRateInGrid, assertTaxRateForm"
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f8e0b7b9bb461a440bddeaa5204db325d2d01c2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Test\TestCase;
+
+use Magento\Customer\Test\Fixture\AddressInjectable;
+use Mtf\TestCase\Injectable;
+use Mtf\Fixture\FixtureFactory;
+use Magento\Tax\Test\Fixture\TaxRule;
+use Magento\Tax\Test\Page\Adminhtml\TaxRuleNew;
+use Magento\Tax\Test\Page\Adminhtml\TaxRuleIndex;
+
+/**
+ * Test Creation for Update TaxRuleEntity
+ *
+ * Test Flow:
+ * Preconditions:
+ * 1. 1 simple product is created.
+ * 2. Tax Rule is created.
+ *
+ * Steps:
+ * 1. Login to backend
+ * 2. Navigate to Stores > Tax Rules
+ * 3. Click Tax Rule from grid
+ * 4. Edit test value(s) according to dataset.
+ * 5. Click 'Save' button.
+ * 6. Perform all asserts.
+ *
+ * @group Tax_(CS)
+ * @ZephyrId MAGETWO-20996
+ */
+class UpdateTaxRuleEntityTest extends Injectable
+{
+    /**
+     * Tax Rule grid page
+     *
+     * @var TaxRuleIndex
+     */
+    protected $taxRuleIndexPage;
+
+    /**
+     * Tax Rule new and edit page
+     *
+     * @var TaxRuleNew
+     */
+    protected $taxRuleNewPage;
+
+    /**
+     * Prepare data
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function __prepare(FixtureFactory $fixtureFactory)
+    {
+        $productSimple = $fixtureFactory->createByCode('catalogProductSimple', ['dataSet' => '100_dollar_product']);
+        $productSimple->persist();
+        $customer = $fixtureFactory->createByCode('customerInjectable', ['dataSet' => 'default']);
+        $customer->persist();
+
+        return [
+            'productSimple' => $productSimple,
+            'customer' => $customer,
+        ];
+    }
+
+    /**
+     * Injection data
+     *
+     * @param TaxRuleIndex $taxRuleIndexPage
+     * @param TaxRuleNew $taxRuleNewPage
+     * @return void
+     */
+    public function __inject(
+        TaxRuleIndex $taxRuleIndexPage,
+        TaxRuleNew $taxRuleNewPage
+    ) {
+        $this->taxRuleIndexPage = $taxRuleIndexPage;
+        $this->taxRuleNewPage = $taxRuleNewPage;
+    }
+
+    /**
+     * Update Tax Rule Entity test
+     *
+     * @param TaxRule $initialTaxRule
+     * @param TaxRule $taxRule
+     * @param AddressInjectable $address
+     * @param array $shipping
+     * @return void
+     */
+    public function testUpdateTaxRule(
+        TaxRule $initialTaxRule,
+        TaxRule $taxRule,
+        AddressInjectable $address,
+        array $shipping
+    ) {
+        // Precondition
+        $initialTaxRule->persist();
+
+        // Steps
+        $filters = [
+            'code' => $initialTaxRule->getCode(),
+        ];
+        $this->taxRuleIndexPage->open();
+        $this->taxRuleIndexPage->getTaxRuleGrid()->searchAndOpen($filters);
+        $this->taxRuleNewPage->getTaxRuleForm()->fill($taxRule);
+        $this->taxRuleNewPage->getFormPageActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest/testUpdateTaxRule.csv b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest/testUpdateTaxRule.csv
new file mode 100644
index 0000000000000000000000000000000000000000..b87c02bedf660e437cf2860a284bc6eeccba8672
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Tax/Test/TestCase/UpdateTaxRuleEntityTest/testUpdateTaxRule.csv
@@ -0,0 +1,5 @@
+"initialTaxRule/dataSet";"address/data/country_id";"address/data/region_id";"address/data/postcode";"shipping/carrier";"shipping/method";"shipping/price";"taxRule/data/code";"taxRule/data/tax_rate/dataSet/rate_0";"taxRule/data/tax_customer_class/dataSet/class_0";"taxRule/data/tax_product_class/dataSet/class_0";"taxRule/data/priority";"taxRule/data/position";"constraint"
+"tax_rule_default";"-";"-";"-";"-";"-";"-";"New Tax Rule name%isolation%";"default";"customer_tax_class";"product_tax_class";"2";"2";"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm"
+"tax_rule_with_custom_tax_classes";"-";"-";"-";"-";"-";"-";"-";"withZipRange";"Retail Customer";"Taxable Goods";"-";"-";"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm"
+"tax_rule_with_custom_tax_classes";"United States";"Utah";84001;"Flat Rate";"Fixed";5;"-";"us_ut_fixed_zip_rate_20";"-";"-";"-";"-";"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm, assertTaxRuleIsApplied"
+"tax_rule_with_custom_tax_classes";"United States";"Idaho";83201;"Flat Rate";"Fixed";5;"-";"withFixedZip";"-";"-";"-";"-";"assertTaxRuleSuccessSaveMessage, assertTaxRuleInGrid, assertTaxRuleForm, assertTaxRuleIsNotApplied"
\ No newline at end of file
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
index 54e405d8c0a07457dc17b36ff761b94e059b51c3..fa9046b598b7a62feca4c86f53e1afbc6c2bf3f7 100644
--- 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
@@ -45,4 +45,37 @@
             <taxRule class="Magento\Tax\Test\Fixture\TaxRule" />
         </require>
     </assertTaxRuleForm>
+    <assertTaxRateSuccessSaveMessage module="Magento_Tax">
+        <severeness>high</severeness>
+        <require>
+            <taxRateIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRateIndex" />
+        </require>
+    </assertTaxRateSuccessSaveMessage>
+    <assertTaxRateInGrid module="Magento_Tax">
+        <severeness>high</severeness>
+        <require>
+            <taxRateIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRateIndex" />
+            <taxRate class="Magento\Tax\Test\Fixture\TaxRate" />
+        </require>
+    </assertTaxRateInGrid>
+    <assertTaxRateForm module="Magento_Tax">
+        <severeness>high</severeness>
+        <require>
+            <taxRateIndex class="Magento\Tax\Test\Page\Adminhtml\TaxRateIndex" />
+            <taxRateNew class="Magento\Tax\Test\Page\Adminhtml\TaxRateNew" />
+            <taxRate class="Magento\Tax\Test\Fixture\TaxRate" />
+        </require>
+    </assertTaxRateForm>
+    <assertTaxRateIsInCorrectRange module="Magento_Tax">
+        <severeness>low</severeness>
+        <require/>
+    </assertTaxRateIsInCorrectRange>
+    <assertTaxRuleIsApplied module="Magento_Tax">
+        <severeness>high</severeness>
+        <require />
+    </assertTaxRuleIsApplied>
+    <assertTaxRuleIsNotApplied module="Magento_Tax">
+        <severeness>high</severeness>
+        <require />
+    </assertTaxRuleIsNotApplied>
 </constraint>
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
index ddde8e9355ca77bf82ac69f253bdb124a7418407..712eaffc63e0362c6d9883d893d46e249333fd9d 100644
--- 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
@@ -34,4 +34,14 @@
         <area>adminhtml</area>
         <class>Magento\Tax\Test\Page\Adminhtml\TaxRuleNew</class>
     </taxRuleNew>
+    <taxRateIndex>
+        <mca>tax/rate/index</mca>
+        <area>adminhtml</area>
+        <class>Magento\Tax\Test\Page\Adminhtml\TaxRateIndex</class>
+    </taxRateIndex>
+    <taxRateNew>
+        <mca>tax/rate/add</mca>
+        <area>adminhtml</area>
+        <class>Magento\Tax\Test\Page\Adminhtml\TaxRateNew</class>
+    </taxRateNew>
 </page>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertPageByUrlRewriteIsNotFound.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertPageByUrlRewriteIsNotFound.php
new file mode 100644
index 0000000000000000000000000000000000000000..bf78bda113e33918d0976f340166fc00d95cb139
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertPageByUrlRewriteIsNotFound.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\UrlRewrite\Test\Constraint;
+
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
+use Mtf\Client\Browser;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertPageByUrlRewriteIsNotFound
+ * Checking the server response 404 page on frontend
+ */
+class AssertPageByUrlRewriteIsNotFound extends AbstractConstraint
+{
+    /**
+     * Message on the product page 404
+     */
+    const NOT_FOUND_MESSAGE = 'Whoops, our bad...';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Checking the server response 404 page on frontend
+     *
+     * @param Browser $browser
+     * @param UrlRewrite $productRedirect
+     * @param CatalogProductView $catalogProductView
+     * @return void
+     */
+    public function processAssert(
+        Browser $browser,
+        CatalogProductView $catalogProductView,
+        UrlRewrite $productRedirect
+    ) {
+        $browser->open($_ENV['app_frontend_url'] . $productRedirect->getRequestPath());
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::NOT_FOUND_MESSAGE,
+            $catalogProductView->getTitleBlock()->getTitle(),
+            'Wrong page is displayed.'
+        );
+    }
+
+    /**
+     * Not found page is display
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Not found page is display.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteDeletedMessage.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteDeletedMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..287bf259b31fed1921c8194673d944521b027ba2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteDeletedMessage.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\UrlRewrite\Test\Constraint;
+
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertUrlRewriteDeletedMessage
+ * Assert that delete message is displayed
+ */
+class AssertUrlRewriteDeletedMessage extends AbstractConstraint
+{
+    /**
+     * Message that displayed after delete url rewrite
+     */
+    const SUCCESS_DELETE_MESSAGE = 'The URL Rewrite has been deleted.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that delete message is displayed
+     *
+     * @param UrlrewriteIndex $index
+     * @return void
+     */
+    public function processAssert(UrlrewriteIndex $index)
+    {
+        $actualMessage = $index->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_DELETE_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_DELETE_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Url rewrite delete message is displayed
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Url rewrite delete message is displayed.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteNotInGrid.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteNotInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..a47ff883bb89f532aae489bff3d92b4e80254c45
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteNotInGrid.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\UrlRewrite\Test\Constraint;
+
+use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertUrlRewriteNotInGrid
+ * Assert that url rewrite category not in grid
+ */
+class AssertUrlRewriteNotInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that url rewrite not in grid
+     *
+     * @param UrlrewriteIndex $urlRewriteIndex
+     * @param UrlRewrite $productRedirect
+     * @return void
+     */
+    public function processAssert(UrlrewriteIndex $urlRewriteIndex, UrlRewrite $productRedirect)
+    {
+        $urlRewriteIndex->open();
+        $filter = ['request_path' => $productRedirect->getRequestPath()];
+        \PHPUnit_Framework_Assert::assertFalse(
+            $urlRewriteIndex->getUrlRedirectGrid()->isRowVisible($filter),
+            'URL Redirect with request path \'' . $productRedirect->getRequestPath() . '\' is present in grid.'
+        );
+    }
+
+    /**
+     * URL rewrite category not present in grid
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'URL Redirect is not present in grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
index f62eab17ebcba10ab683964acf92eb0a83cbcf2e..9f84c5b500c45fb8b24017d10cfbc24ee589d2ac 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
@@ -31,6 +31,16 @@ use Mtf\Fixture\InjectableFixture;
  */
 class UrlRewrite extends InjectableFixture
 {
+    /**
+     * @var string
+     */
+    protected $repositoryClass = 'Magento\UrlRewrite\Test\Repository\UrlRewrite';
+
+    /**
+     * @var string
+     */
+    protected $handlerInterface = 'Magento\UrlRewrite\Test\Handler\UrlRewrite\UrlRewriteInterface';
+
     protected $defaultDataSet = [
         'store_id' => 'Default Store View',
         'request_path' => 'test_request%isolation%',
@@ -41,6 +51,11 @@ class UrlRewrite extends InjectableFixture
         'backend_type' => 'virtual',
     ];
 
+    protected $id_path = [
+        'attribute_code' => 'id_path',
+        'backend_type' => 'virtual',
+    ];
+
     protected $store_id = [
         'attribute_code' => 'store_id',
         'backend_type' => 'varchar',
@@ -76,6 +91,11 @@ class UrlRewrite extends InjectableFixture
         return $this->getData('id');
     }
 
+    public function getIdPath()
+    {
+        return $this->getData('id_path');
+    }
+
     public function getStoreId()
     {
         return $this->getData('store_id');
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
index 7f11744b1e78936bd03c0eaa985cfb5a65c4a43a..3e28df6a0c1ce1f1f8f08154ead7eb8fe66d52ab 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
@@ -34,6 +34,10 @@
             <attribute_code>id</attribute_code>
             <backend_type>virtual</backend_type>
         </id>
+        <id_path>
+            <attribute_code>id_path</attribute_code>
+            <backend_type>virtual</backend_type>
+        </id_path>
         <store_id>
             <attribute_code>store_id</attribute_code>
             <backend_type>varchar</backend_type>
@@ -61,4 +65,6 @@
             <input>text</input>
         </description>
     </fields>
+    <repository_class>Magento\UrlRewrite\Test\Repository\UrlRewrite</repository_class>
+    <handler_interface>Magento\UrlRewrite\Test\Handler\UrlRewrite</handler_interface>
 </fixture>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..49368c86669ca772984707cc21d8bba3eedf19ee
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/Curl.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\UrlRewrite\Test\Handler\UrlRewrite;
+
+use Mtf\Fixture\FixtureInterface;
+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
+ * Create url rewrite
+ */
+class Curl extends AbstractCurl implements UrlRewriteInterface
+{
+    /**
+     * Data mapping
+     *
+     * @var array
+     */
+    protected $dataMapping = [
+        'store_id' => ['Default Store View' => 1],
+        'options' => [
+            'Temporary (302)' => 'R',
+            'Temporary (301)' => 'RP',
+            'No' => ''
+        ]
+    ];
+
+    /**
+     * Url for save rewrite
+     *
+     * @var string
+     */
+    protected $url = 'admin/urlrewrite/save/';
+
+    /**
+     * Post request for creating url rewrite
+     *
+     * @param FixtureInterface $fixture
+     * @throws \Exception
+     * @return mixed|void
+     */
+    public function persist(FixtureInterface $fixture = null)
+    {
+        $url = $_ENV['app_backend_url'] . $this->url . $fixture->getData('id_path');
+        $data = $this->prepareData($fixture->getData());
+        $curl = new BackendDecorator(new CurlTransport(), new Config());
+        $curl->write(CurlInterface::POST, $url, '1.0', array(), $data);
+        $response = $curl->read();
+
+        if (!strpos($response, 'data-ui-id="messages-message-success"')) {
+            throw new \Exception("Product creation by curl handler was not successful! Response: $response");
+        }
+        $curl->close();
+    }
+
+    /**
+     * Prepare data
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function prepareData(array $data)
+    {
+        foreach ($data as $key => $value) {
+            if (isset($this->dataMapping[$key])) {
+                $data[$key] = $this->dataMapping[$key][$value];
+            }
+        }
+        return $data;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/UrlRewriteInterface.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/UrlRewriteInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..80dccd6f26f1940cc71994f85070f8bc20885565
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Handler/UrlRewrite/UrlRewriteInterface.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\UrlRewrite\Test\Handler\UrlRewrite;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface UrlRewriteInterface
+ */
+interface UrlRewriteInterface extends HandlerInterface
+{
+   //
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.php
new file mode 100644
index 0000000000000000000000000000000000000000..743f2fe3af793df1f937c1f74b293e8d1d81ae10
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Repository/UrlRewrite.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\UrlRewrite\Test\Repository;
+
+use Mtf\Repository\AbstractRepository;
+
+/**
+ * Class UrlRewrite
+ * Data for creation url rewrite
+ */
+class UrlRewrite extends AbstractRepository
+{
+    /**
+     * @param array $defaultConfig
+     * @param array $defaultData
+     */
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
+    {
+        $this->_data['default'] = [
+            'request_path' => 'test-test-test%isolation%.html',
+            'options' => 'No',
+            'store_id' => 'Default Store View'
+        ];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewritesEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewritesEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1a7b36911d1eb3f1cb24d07af4a68a00215715e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewritesEntityTest.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\UrlRewrite\Test\TestCase;
+
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+use Mtf\Fixture\FixtureFactory;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for DeleteProductUrlRewritesEntity
+ *
+ * Precondition:
+ * 1. Sub category is created.
+ * 2. Product is created.
+ * 3. Product url rewrites is created.
+ *
+ * Test Flow:
+ * 1. Login to backend.
+ * 2. Navigate to MARKETING > URL Redirects.
+ * 3. Click Redirect from grid.
+ * 4. Click 'Delete' button.
+ * 5. Perform asserts.
+ *
+ * @group URL_Rewrites_(PS)
+ * @ZephyrId  MAGETWO-23287
+ */
+class DeleteProductUrlRewritesEntityTest extends Injectable
+{
+    /**
+     * Url rewrite index page
+     *
+     * @var UrlrewriteIndex
+     */
+    protected $urlRewriteIndex;
+
+    /**
+     * Url rewrite edit page
+     *
+     * @var UrlrewriteEdit
+     */
+    protected $urlRewriteEdit;
+
+    /**
+     * Prepare dataSets and pages
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @param UrlrewriteIndex $urlRewriteIndex
+     * @param UrlrewriteEdit $urlRewriteEdit
+     * @return array
+     */
+    public function __inject(
+        FixtureFactory $fixtureFactory,
+        UrlrewriteIndex $urlRewriteIndex,
+        UrlrewriteEdit $urlRewriteEdit
+    ) {
+        /** @var CatalogProductSimple $product */
+        $product = $fixtureFactory->createByCode('catalogProductSimple', ['dataSet' => 'product_without_category']);
+        $product->persist();
+
+        /** @var UrlRewrite $productRedirect */
+        $productRedirect = $fixtureFactory->createByCode(
+            'urlRewrite',
+            [
+                'dataSet' => 'default',
+                'data' => ['id_path' => 'product/' . $product->getId()]
+            ]
+        );
+        $productRedirect->persist();
+
+        $this->urlRewriteIndex = $urlRewriteIndex;
+        $this->urlRewriteEdit = $urlRewriteEdit;
+        return ['productRedirect' => $productRedirect];
+    }
+
+    /**
+     * Delete product url rewrites entity
+     *
+     * @param UrlRewrite $productRedirect
+     * @return void
+     */
+    public function testDeleteProductUrlRewrites(UrlRewrite $productRedirect)
+    {
+        $this->urlRewriteIndex->open();
+        $filter = ['request_path' => $productRedirect->getRequestPath()];
+        $this->urlRewriteIndex->getUrlRedirectGrid()->searchAndOpen($filter);
+        $this->urlRewriteEdit->getPageMainActions()->delete();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewritesEntityTest/testDeleteProductUrlRewrites.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewritesEntityTest/testDeleteProductUrlRewrites.csv
new file mode 100644
index 0000000000000000000000000000000000000000..a0af0ee8456176c7a6ad3413c1c9f39546360b48
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/DeleteProductUrlRewritesEntityTest/testDeleteProductUrlRewrites.csv
@@ -0,0 +1,2 @@
+"constraint"
+"assertUrlRewriteDeletedMessage, assertUrlRewriteNotInGrid, assertPageByUrlRewriteIsNotFound"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/curl/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6dcbbc44a53c7d55bd51fb47e1faa86d646437d7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/curl/di.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="\Magento\UrlRewrite\Test\Handler\UrlRewrite\UrlRewriteInterface" type="\Magento\UrlRewrite\Test\Handler\UrlRewrite\Curl" />
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml
index 2ca992fbdc011809ae1cb06bc49192d5f078d377..a31770c30119601d784a187fe1e2842889865ec6 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml
@@ -37,4 +37,25 @@
     <assertUrlRewriteCategoryRedirect module="Magento_UrlRewrite">
         <severeness>low</severeness>
     </assertUrlRewriteCategoryRedirect>
+    <assertUrlRewriteDeletedMessage module="Magento_UrlRewrite">
+        <severeness>low</severeness>
+        <require>
+            <index class="Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex"/>
+        </require>
+    </assertUrlRewriteDeletedMessage>
+    <assertUrlRewriteNotInGrid module="Magento_UrlRewrite">
+        <severeness>low</severeness>
+        <require>
+            <urlRewriteIndex class="Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex"/>
+            <productRedirect class="Magento\UrlRewrite\Test\Fixture\UrlRewrite"/>
+        </require>
+    </assertUrlRewriteNotInGrid>
+    <assertPageByUrlRewriteIsNotFound module="Magento_UrlRewrite">
+        <severeness>low</severeness>
+        <require>
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <productRedirect class="Magento\UrlRewrite\Test\Fixture\UrlRewrite"/>
+            <browser class="Mtf\Client\Browser"/>
+        </require>
+    </assertPageByUrlRewriteIsNotFound>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/User/Edit/Form.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Edit/Form.php
similarity index 74%
rename from dev/tests/functional/tests/app/Magento/User/Test/Block/User/Edit/Form.php
rename to dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Edit/Form.php
index d5f27dd5da54471ab24d6481985de0cf40c5d4f1..d503dbb373467200fcc292361e345415a968072b 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Block/User/Edit/Form.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Edit/Form.php
@@ -22,17 +22,16 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\User\Test\Block\User\Edit;
+namespace Magento\User\Test\Block\Adminhtml\User\Edit;
 
-use Mtf\Fixture\FixtureInterface;
 use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
 use Magento\Backend\Test\Block\Widget\FormTabs;
+use Magento\User\Test\Block\Adminhtml\User\Edit\Tab\Roles;
 
 /**
  * Class Form
  * Form for User Edit/Create page
- *
  */
 class Form extends FormTabs
 {
@@ -45,9 +44,24 @@ class Form extends FormTabs
 
     /**
      * Open Role tab for User Edit page
+     *
+     * @return void
      */
     public function openRoleTab()
     {
         $this->_rootElement->find($this->roleTab, Locator::SELECTOR_ID)->click();
     }
+
+    /**
+     * Get roles grid on user edit page
+     *
+     * @return Roles
+     */
+    public function getRolesGrid()
+    {
+        return $this->blockFactory->create(
+            'Magento\User\Test\Block\Adminhtml\User\Edit\Tab\Roles',
+            ['element' => $this->_rootElement->find('#permissionsUserRolesGrid')]
+        );
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/User/Edit/Tab/Roles.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Edit/Tab/Roles.php
similarity index 82%
rename from dev/tests/functional/tests/app/Magento/User/Test/Block/User/Edit/Tab/Roles.php
rename to dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Edit/Tab/Roles.php
index ccf627df72298fe944b1c9a96d15dc0a81cf6113..18bf72dc38ce2c4988738daf780ff0d759fb4d90 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Block/User/Edit/Tab/Roles.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Edit/Tab/Roles.php
@@ -22,7 +22,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\User\Test\Block\User\Edit\Tab;
+namespace Magento\User\Test\Block\Adminhtml\User\Edit\Tab;
 
 use Mtf\Client\Element;
 use Mtf\Factory\Factory;
@@ -31,10 +31,23 @@ use Magento\Backend\Test\Block\Widget\Grid;
 /**
  * Class Roles
  * Grid on Roles Tab page for User
- *
  */
 class Roles extends Grid
 {
+    /**
+     * Locator value for link in action column
+     *
+     * @var string
+     */
+    protected $editLink = '.col-role_name';
+
+    /**
+     * An element locator which allows to select entities in grid
+     *
+     * @var string
+     */
+    protected $selectItem = 'tbody tr';
+
     /**
      * Filters Name for Roles Grid
      *
@@ -49,13 +62,4 @@ class Roles extends Grid
             'selector' => '#permissionsUserRolesGrid_filter_role_name'
         )
     );
-
-    /**
-     * Initialize grid elements
-     */
-    protected function _init()
-    {
-        parent::_init();
-        $this->selectItem = 'tbody tr';
-    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/UserGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/UserGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec9a46557561e8a84b1535ff92140558764333f8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/UserGrid.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\User\Test\Block\Adminhtml;
+
+use Magento\Backend\Test\Block\Widget\Grid;
+
+/**
+ * Class UserGrid
+ * User grid on User index page.
+ */
+class UserGrid extends Grid
+{
+    /**
+     * Grid filters' selectors
+     *
+     * @var array
+     */
+    protected $filters = [
+        'username' => [
+            'selector' => '#permissionsUserGrid_filter_username'
+        ],
+        'email' => [
+            'selector' => '#permissionsUserGrid_filter_email'
+        ]
+    ];
+
+    /**
+     * Locator value of td with username
+     *
+     * @var string
+     */
+    protected $editLink = '[data-column="username"]';
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Backend/UserGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Backend/UserGrid.php
deleted file mode 100644
index 55b32da488552e4463c353b4c0c55a273ecf7b73..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/User/Test/Block/Backend/UserGrid.php
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\User\Test\Block\Backend;
-
-use Mtf\Client\Element\Locator;
-use Magento\Backend\Test\Block\Widget\Grid;
-
-/**
- * Class UserGrid
- * Grid on System ->Permissions -> All Users page
- *
- */
-class UserGrid extends Grid
-{
-    /**
-     * Link to click on Email cell for user
-     *
-     * @var string
-     */
-    protected $editLink = 'td[data-column="email"]';
-
-    /**
-     * Filters Name for Permission User Grid
-     *
-     * @var array
-     */
-    protected $filters = array(
-        'id' => array(
-            'selector' => '#permissionsUserGrid_filter_user_id'
-        ),
-        'user_name' => array(
-            'selector' => '#permissionsUserGrid_filter_username'
-        ),
-        'first_name' => array(
-            'selector' => '#permissionsUserGrid_filter_firstname'
-        ),
-        'last_name' => array(
-            'selector' => '#permissionsUserGrid_filter_lastname'
-        ),
-        'email' => array(
-            'selector' => '#permissionsUserGrid_filter_email'
-        ),
-        'status' => array(
-            'selector' => '#permissionsUserGrid_filter_is_active',
-            'input' => 'select'
-        )
-    );
-
-    /**
-     * Initialize grid elements
-     */
-    protected function _init()
-    {
-        parent::_init();
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertImpossibleDeleteYourOwnAccount.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertImpossibleDeleteYourOwnAccount.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ade229966bdb6a8d770fa289fb640ac4c0e78f9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertImpossibleDeleteYourOwnAccount.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\UserEdit;
+
+/**
+ * Class AssertImpossibleDeleteYourOwnAccount
+ */
+class AssertImpossibleDeleteYourOwnAccount extends AbstractConstraint
+{
+    const ERROR_MESSAGE = 'You cannot delete your own account.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that error message equals to expected message.
+     *
+     * @param UserEdit $userEdit
+     * @return void
+     */
+    public function processAssert(UserEdit $userEdit)
+    {
+        $errorMessage = $userEdit->getMessagesBlock()->getErrorMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::ERROR_MESSAGE,
+            $errorMessage,
+            'Wrong error message is displayed.'
+            . "\nExpected: " . self::ERROR_MESSAGE
+            . "\nActual: " . $errorMessage
+        );
+    }
+
+    /**
+     * Returns message if equals to expected message.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return '"You cannot delete self-assigned roles." message on UserEdit page is correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b2c17f7fa576824129f11f775cdf8096b1d656e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInGrid.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 Magento\User\Test\Fixture\AdminUserInjectable;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\User\Test\Page\Adminhtml\UserIndex;
+
+/**
+ * Class AssertUserInGrid
+ */
+class AssertUserInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that user is present in User Grid.
+     *
+     * @param UserIndex $userIndex
+     * @param AdminUserInjectable $adminUser
+     * @return void
+     */
+    public function processAssert(
+        UserIndex $userIndex,
+        AdminUserInjectable $adminUser
+    ) {
+        $filter = ['username' => $adminUser->getUsername()];
+        $userIndex->open();
+        \PHPUnit_Framework_Assert::assertTrue(
+            $userIndex->getUserGrid()->isRowVisible($filter),
+            'User with name \'' . $adminUser->getUsername() . '\' is absent in User grid.'
+        );
+    }
+
+    /**
+     * Returns success message if assert true.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'User is present in Users grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserNotInGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserNotInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..19056cdf4c199620c9c9d24af902fac16378946c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserNotInGrid.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\Fixture\AdminUserInjectable;
+use Magento\User\Test\Page\Adminhtml\UserIndex;
+
+/**
+ * Class AssertUserNotInGrid
+ */
+class AssertUserNotInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that User is not present in User Grid.
+     *
+     * @param UserIndex $userIndex
+     * @param AdminUserInjectable $adminUser
+     * @return void
+     */
+    public function processAssert(
+        UserIndex $userIndex,
+        AdminUserInjectable $adminUser
+    ) {
+        $filter = ['username' => $adminUser->getUsername()];
+        $userIndex->open();
+        \PHPUnit_Framework_Assert::assertFalse(
+            $userIndex->getUserGrid()->isRowVisible($filter),
+            'User with name \'' . $adminUser->getUsername() . '\' is present in Users grid.'
+        );
+    }
+
+    /**
+     * Returns message if user not in grid.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'User is absent in Users grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessDeleteMessage.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessDeleteMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..089d70b510b2473f6dc03098f8f5181d4aa43875
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessDeleteMessage.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\UserIndex;
+
+/**
+ * Class AssertUserSuccessDeleteMessage
+ */
+class AssertUserSuccessDeleteMessage extends AbstractConstraint
+{
+    const SUCCESS_MESSAGE = 'You deleted the user.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that success delete message equals to expected message.
+     *
+     * @param UserIndex $userIndex
+     * @return void
+     */
+    public function processAssert(UserIndex $userIndex)
+    {
+        $successMessage = $userIndex->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $successMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_MESSAGE
+            . "\nActual: " . $successMessage
+        );
+    }
+
+    /**
+     * Returns message if success message equals to expected message.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Success delete message on users page is correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.php
index c45c17571bddf6ab4a405a1fb59f7c5f80be3ec8..0c6dd05ad1feaa251de174040781298e04822ccc 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.php
@@ -28,6 +28,7 @@ use Mtf\Fixture\InjectableFixture;
 
 /**
  * Class AdminUserInjectable
+ *
  */
 class AdminUserInjectable extends InjectableFixture
 {
@@ -42,12 +43,12 @@ class AdminUserInjectable extends InjectableFixture
     protected $handlerInterface = 'Magento\User\Test\Handler\AdminUser\AdminUserInterface';
 
     protected $defaultDataSet = [
-        'username' => 'customAdmin%isolation%',
+        'username' => 'AdminUser%isolation%',
         'firstname' => 'FirstName%isolation%',
         'lastname' => 'LastName%isolation%',
         'email' => 'email%isolation%@example.com',
         'password' => '123123q',
-        'password_confirmation' => '123123q',
+        'password_confirmation' => '123123q'
     ];
 
     protected $user_id = [
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/Curl.php b/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/Curl.php
index 33deba9d62617c63b0fea07dc5a2cb9569c8554b..13653bc9d2feac84db861318b7cc3ca08c4a7bab 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/Curl.php
@@ -30,7 +30,7 @@ use Mtf\Util\Protocol\CurlInterface;
 use Mtf\Util\Protocol\CurlTransport;
 use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
 use Mtf\System\Config;
-use Magento\Backend\Test\Handler\Pagination;
+use Magento\Backend\Test\Handler\Extractor;
 
 /**
  * Class Curl
@@ -65,8 +65,8 @@ class Curl extends AbstractCurl implements AdminUserInterface
         $url = 'admin/user/roleGrid/sort/user_id/dir/desc';
         $regExpPattern = '/class=\"\scol\-id col\-user_id\W*>\W+(\d+)\W+<\/td>\W+<td[\w\s\"=\-]*?>\W+?'
             . $data['username'] . '/siu';
-        $pagination = new Pagination($url, $regExpPattern);
+        $extractor = new Extractor($url, $regExpPattern);
 
-        return ['user_id' => $pagination->getId()];
+        return ['user_id' => $extractor->getData()[1]];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUserRole/Curl.php b/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUserRole/Curl.php
index 4abace1c4c32175b04ab1e43c95932121041f1bb..918d42c2c4b55b09112ebb26d0a44d076a53e07e 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUserRole/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUserRole/Curl.php
@@ -24,9 +24,7 @@
 
 namespace Magento\User\Test\Handler\AdminUserRole;
 
-use Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface;
-use Magento\Backend\Test\Handler\Pagination;
-use Magento\User\Test\Page\Adminhtml\UserRoleIndex;
+use Magento\Backend\Test\Handler\Extractor;
 use Mtf\Fixture\FixtureInterface;
 use Mtf\Handler\Curl as AbstractCurl;
 use Mtf\Util\Protocol\CurlInterface;
@@ -70,8 +68,8 @@ class Curl extends AbstractCurl implements AdminUserRoleInterface
         $regExpPattern = '/class=\"\scol\-id col\-role_id\W*>\W+(\d+)\W+<\/td>\W+<td[\w\s\"=\-]*?>\W+?'
             . $data['rolename'] . '/siu';
 
-        $pagination = new Pagination($url, $regExpPattern);
+        $extractor = new Extractor($url, $regExpPattern);
 
-        return ['role_id' => $pagination->getId()];
+        return ['role_id' => $extractor->getData()[1]];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserEdit.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserEdit.php
new file mode 100644
index 0000000000000000000000000000000000000000..d12315a867ccfea330a7a3a1448402c3b907c52c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserEdit.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\User\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class UserEdit
+ */
+class UserEdit extends BackendPage
+{
+    const MCA = 'admin/user/edit';
+
+    protected $_blocks = [
+        'pageActions' => [
+            'name' => 'pageActions',
+            'class' => 'Magento\Backend\Test\Block\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+        'userForm' => [
+            'name' => 'userForm',
+            'class' => 'Magento\User\Test\Block\Adminhtml\User\Edit\Form',
+            'locator' => '[id="page:main-container"]',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Backend\Test\Block\FormPageActions
+     */
+    public function getPageActions()
+    {
+        return $this->getBlockInstance('pageActions');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+
+    /**
+     * @return \Magento\User\Test\Block\Adminhtml\User\Edit\Form
+     */
+    public function getUserForm()
+    {
+        return $this->getBlockInstance('userForm');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserEdit.xml b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserEdit.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c5235586183e0b878534d24e53671aca56a9f5ee
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserEdit.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/edit">
+    <block>
+        <name>pageActions</name>
+        <class>Magento\Backend\Test\Block\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</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>userForm</name>
+        <class>Magento\User\Test\Block\Adminhtml\User\Edit\Form</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/UserIndex.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba6103d7096477733def574dd8c1aa9a016b819b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserIndex.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\User\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class UserIndex
+ */
+class UserIndex extends BackendPage
+{
+    const MCA = 'admin/user';
+
+    protected $_blocks = [
+        'pageActions' => [
+            'name' => 'pageActions',
+            'class' => 'Magento\Backend\Test\Block\GridPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'userGrid' => [
+            'name' => 'userGrid',
+            'class' => 'Magento\User\Test\Block\Adminhtml\UserGrid',
+            'locator' => '#permissionsUserGrid',
+            '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 getPageActions()
+    {
+        return $this->getBlockInstance('pageActions');
+    }
+
+    /**
+     * @return \Magento\User\Test\Block\Adminhtml\UserGrid
+     */
+    public function getUserGrid()
+    {
+        return $this->getBlockInstance('userGrid');
+    }
+
+    /**
+     * @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/UserIndex.xml b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1783a653f4172ca2ddba69fdc999a341629c3105
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserIndex.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">
+    <block>
+        <name>pageActions</name>
+        <class>Magento\Backend\Test\Block\GridPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>userGrid</name>
+        <class>Magento\User\Test\Block\Adminhtml\UserGrid</class>
+        <locator>#permissionsUserGrid</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/Page/Backend/UserEdit.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Backend/UserEdit.php
deleted file mode 100644
index fa736405c46db40d9fe77a85e2b832cc8f843d4c..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/User/Test/Page/Backend/UserEdit.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 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\Backend;
-
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
-use Mtf\Client\Element\Locator;
-
-/**
- * Class UserEdit
- *
- */
-class UserEdit extends Page
-{
-    /**
-     * URL for new admin user
-     */
-    const MCA = 'admin/user/edit/user_id/';
-
-    /**
-     * Form for admin user creation
-     *
-     * @var string
-     */
-    protected $editFormBlock = 'page:main-container';
-
-    /**
-     * Global messages block
-     *
-     * @var string
-     */
-    protected $messagesBlock = '#messages .messages';
-
-    /**
-     * Role Grid Block
-     * var @string
-     */
-    protected $roleGridBlock = 'permissionsUserRolesGrid';
-
-    /**
-     * 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 form for admin user creation/edit
-     *
-     * @return \Magento\User\Test\Block\User\Edit\Form
-     */
-    public function getEditFormBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoUserUserEditForm(
-            $this->_browser->find($this->editFormBlock, Locator::SELECTOR_ID)
-        );
-    }
-
-    /**
-     * Get global messages block
-     *
-     * @return \Magento\Core\Test\Block\Messages
-     */
-    public function getMessagesBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCoreMessages(
-            $this->_browser->find($this->messagesBlock)
-        );
-    }
-
-    /**
-     * Get Role grid
-     *
-     * @return \Magento\User\Test\Block\User\Edit\Tab\Roles
-     */
-    public function getRoleGridBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoUserUserEditTabRoles(
-            $this->_browser->find($this->roleGridBlock, Locator::SELECTOR_ID)
-        );
-    }
-
-    /**
-     * Get Grid page actions block
-     *
-     * @return \Magento\User\Test\Block\Backend\UserEditPageActions
-     */
-    public function getPageActionsBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoUserBackendUserEditPageActions(
-            $this->_browser->find($this->pageActionsBlock)
-        );
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Backend/UserIndex.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Backend/UserIndex.php
deleted file mode 100644
index 2ab29dd452b0dbcae5c2c0fd2816f7f805769af4..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/User/Test/Page/Backend/UserIndex.php
+++ /dev/null
@@ -1,105 +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\User\Test\Page\Backend;
-
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
-use Mtf\Client\Element\Locator;
-
-/**
- * Class UserIndex
- * System ->Permissions -> All Users page
- *
- */
-class UserIndex extends Page
-{
-    /**
-     * URL part for admin user page
-     */
-    const MCA = 'admin/user/';
-
-    /**
-     * Admin User Grid on backend
-     *
-     * @var string
-     */
-    protected $userGridBlock = 'permissionsUserGrid';
-
-    /**
-     * Message Block on page
-     *
-     * @var string
-     */
-    protected $messagesBlock = '#messages .messages';
-
-    /**
-     * Admin header Block
-     *
-     * @var string
-     */
-    protected $adminPanelHeaderBlock = 'page-header';
-
-    /**
-     * Constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_backend_url'] . self::MCA;
-    }
-
-    /**
-     * Get User Grid block
-     *
-     * @return \Magento\User\Test\Block\Backend\UserGrid
-     */
-    public function getUserGridBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoUserBackendUserGrid(
-            $this->_browser->find($this->userGridBlock, Locator::SELECTOR_ID)
-        );
-    }
-
-    /**
-     * Get global messages block
-     *
-     * @return \Magento\Core\Test\Block\Messages
-     */
-    public function getMessagesBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messagesBlock));
-    }
-
-    /**
-     * Get Admin Panel Header Block
-     *
-     * @return \Magento\Backend\Test\Block\Page\Header
-     */
-    public function getAdminPanelHeaderBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoBackendPageHeader(
-            $this->_browser->find($this->adminPanelHeaderBlock, Locator::SELECTOR_CLASS_NAME)
-        );
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserInjectable.php b/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserInjectable.php
index 7dd1a130998232c6b3f974c82ddd3f6cf74a41dc..feeccc7cd5cfbe19a5187b74551dc4d2556ea2cd 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserInjectable.php
@@ -28,36 +28,33 @@ use Mtf\Repository\AbstractRepository;
 
 /**
  * Class Admin User Repository
- *
  */
 class AdminUserInjectable extends AbstractRepository
 {
-    /*
+    /**
      * @constructor
      * @param array $defaultConfig
      * @param array $defaultData
      */
     public function __construct(array $defaultConfig = [], array $defaultData = [])
     {
-        $this->_data['custom_admin'] = [
-            'username' => 'AdminUser%isolation%',
+        $this->_data['default'] = [
+            'username' => 'admin',
             'firstname' => 'FirstName%isolation%',
             'lastname' => 'LastName%isolation%',
             'email' => 'email%isolation%@example.com',
             'password' => '123123q',
             'password_confirmation' => '123123q',
-            'user_role' => 'user_role%isolation%'
+            'user_id' => 1
         ];
 
-        $this->_data['default_admin'] = [
-            'username' => 'admin',
+        $this->_data['custom_admin'] = [
+            'username' => 'AdminUser%isolation%',
             'firstname' => 'FirstName%isolation%',
             'lastname' => 'LastName%isolation%',
             'email' => 'email%isolation%@example.com',
             'password' => '123123q',
             'password_confirmation' => '123123q',
-            'user_role' => 'Administrators',
-            'user_id' => '1'
         ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserRole.php b/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserRole.php
index c162f8898a877f6d80c1a44bc405a8c4d3485195..c50b52232b9c735415d913fdab9b44e3285c0177 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserRole.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserRole.php
@@ -32,6 +32,7 @@ use Mtf\Repository\AbstractRepository;
 class AdminUserRole extends AbstractRepository
 {
     /**
+     * @constructor
      * @param array $defaultConfig
      * @param array $defaultData
      */
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..97cc5a45aa7b801a6026288290a1112cc9a7e1e4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.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\User\Test\TestCase;
+
+use Magento\Backend\Test\Page\AdminAuthLogin;
+use Magento\Backend\Test\Page\Dashboard;
+use Magento\User\Test\Page\Adminhtml\UserEdit;
+use Magento\User\Test\Page\Adminhtml\UserIndex;
+use Mtf\TestCase\Injectable;
+use Magento\User\Test\Fixture\AdminUserInjectable;
+use Mtf\Fixture\FixtureFactory;
+
+/**
+ * Test Creation for DeleteAdminUserEntity
+ *
+ * Test Flow:
+ * Preconditions:
+ * 1. Create new admin user and assign it to new role.
+ * Steps:
+ * 1. Log in as admin user from data set.
+ * 2. Go to System>Permissions>All Users
+ * 3. Open admin user from precondition
+ * 4. Click "Delete User" button
+ * 5. Perform all assertions
+ *
+ * @group ACL_(MX)
+ * @ZephyrId MAGETWO-23416
+ */
+class DeleteAdminUserEntityTest extends Injectable
+{
+    /**
+     * @var UserIndex
+     */
+    protected $userIndex;
+
+    /**
+     * @var UserEdit
+     */
+    protected $userEdit;
+
+    /**
+     * @var Dashboard
+     */
+    protected $dashboard;
+
+    /**
+     * @var AdminAuthLogin
+     */
+    protected $adminAuthLogin;
+
+    /**
+     * Preparing preconditions for test.
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function __prepare(FixtureFactory $fixtureFactory)
+    {
+        $role = $fixtureFactory->createByCode('adminUserRole', ['dataSet' => 'default']);
+        $role->persist();
+        $role_id = $role->getData('role_id');
+        $adminUser = $fixtureFactory->createByCode(
+            'adminUserInjectable',
+            [
+                'dataSet' => 'custom_admin',
+                'data' => ['role_id' => $role_id]
+            ]
+        );
+        $adminUser->persist();
+
+        return [
+            'adminUser' => $adminUser
+        ];
+    }
+
+    /**
+     * Preparing pages for each test iteration.
+     *
+     * @param UserIndex $userIndex
+     * @param UserEdit $userEdit
+     * @param Dashboard $dashboard
+     * @param AdminAuthLogin $adminAuthLogin
+     * @return array
+     */
+    public function __inject(
+        UserIndex $userIndex,
+        UserEdit $userEdit,
+        Dashboard $dashboard,
+        AdminAuthLogin $adminAuthLogin
+    ) {
+        $this->userIndex = $userIndex;
+        $this->userEdit = $userEdit;
+        $this->dashboard = $dashboard;
+        $this->adminAuthLogin = $adminAuthLogin;
+    }
+
+    /**
+     * Runs Delete User Entity test
+     *
+     * @param AdminUserInjectable $adminUser
+     * @param string $isDefaultUser
+     * @return void
+     */
+    public function testDeleteAdminUserEntity(
+        AdminUserInjectable $adminUser,
+        $isDefaultUser
+    ) {
+        $filter = [
+            'username' => $adminUser->getUsername()
+        ];
+        //Steps
+        if ($isDefaultUser == 0) {
+            $this->adminAuthLogin->open();
+            $this->adminAuthLogin->getLoginBlock()->fill($adminUser);
+            $this->adminAuthLogin->getLoginBlock()->submit();
+        }
+        $this->userIndex->open();
+        $this->userIndex->getUserGrid()->searchAndOpen($filter);
+        $this->userEdit->getPageActions()->delete();
+    }
+
+    /**
+     * Logout Admin User from account
+     *
+     * return void
+     */
+    public function tearDown()
+    {
+        $this->dashboard->getAdminPanelHeader()->logOut();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest/testDeleteAdminUserEntity.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest/testDeleteAdminUserEntity.csv
new file mode 100644
index 0000000000000000000000000000000000000000..60040ccc535ca7ce0039f7da61b372dd341b7fbc
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest/testDeleteAdminUserEntity.csv
@@ -0,0 +1,3 @@
+"isDefaultUser";"constraint"
+"0";"assertImpossibleDeleteYourOwnAccount, assertUserInGrid"
+"1";"assertUserSuccessDeleteMessage, assertUserNotInGrid"
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/curl/di.xml
index 2b731bc10bd55fec01cec726aeabe0dcb29be6c4..60f06e7f1110f5043df2ee0507011ced629a6892 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/etc/curl/di.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/curl/di.xml
@@ -23,7 +23,7 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/Magento/ObjectManager/etc/config.xsd">
-    <preference for="Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface" type="\Magento\User\Test\Handler\AdminUserRole\Curl" />
-    <preference for="Magento\User\Test\Handler\AdminUser\AdminUserInterface" type="\Magento\User\Test\Handler\AdminUser\Curl" />
-</config>
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface" type="\Magento\User\Test\Handler\AdminUserRole\Curl"/>
+    <preference for="Magento\User\Test\Handler\AdminUser\AdminUserInterface" type="\Magento\User\Test\Handler\AdminUser\Curl"/>
+</config>
\ 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 d35518ac3c7f1cb133dc7bdd6eab66d4bbfef729..1107ec8a9371bceaba480e6b5b1c914e3637c643 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,34 +36,59 @@
             <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>
+    <assertRoleSuccessSaveMessage module="Magento_User">
+        <severeness>low</severeness>
+        <require>
+            <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleIndex" />
+        </require>
+    </assertRoleSuccessSaveMessage>
     <assertRoleSuccessDeleteMessage module="Magento_User">
         <severeness>low</severeness>
         <require>
             <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleIndex" />
         </require>
     </assertRoleSuccessDeleteMessage>
-   <assertRoleInGrid module="Magento_User">
+    <assertRoleInGrid module="Magento_User">
         <severeness>low</severeness>
         <require>
             <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleIndex" />
         </require>
-   </assertRoleInGrid>
+    </assertRoleInGrid>
     <assertRoleNotInGrid module="Magento_User">
         <severeness>low</severeness>
         <require>
             <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleIndex" />
+            <role class="Magento\User\Test\Fixture\AdminUserRole" />
         </require>
     </assertRoleNotInGrid>
+    <assertImpossibleDeleteYourOwnAccount module="Magento_User">
+        <severeness>low</severeness>
+        <require>
+            <userEdit class="Magento\User\Test\Page\Adminhtml\UserEdit" />
+        </require>
+    </assertImpossibleDeleteYourOwnAccount>
     <assertImpossibleDeleteYourOwnRole module="Magento_User">
         <severeness>low</severeness>
         <require>
             <rolePage class="Magento\User\Test\Page\Adminhtml\UserRoleEditRole" />
         </require>
     </assertImpossibleDeleteYourOwnRole>
+    <assertUserInGrid module="Magento_User">
+        <severeness>low</severeness>
+        <require>
+            <rolePage class="Magento\User\Test\Page\Adminhtml\UserIndex" />
+        </require>
+    </assertUserInGrid>
+    <assertUserNotInGrid module="Magento_User">
+        <severeness>low</severeness>
+        <require>
+            <rolePage class="Magento\User\Test\Page\Adminhtml\UserIndex" />
+        </require>
+    </assertUserNotInGrid>
+    <assertUserSuccessDeleteMessage module="Magento_User">
+        <severeness>low</severeness>
+        <require>
+            <rolePage class="Magento\User\Test\Page\Adminhtml\UserIndex" />
+        </require>
+    </assertUserSuccessDeleteMessage>
 </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 529ab99fd95c9f8e82188f1a346c7240667a9e7c..097d3e5dd5e46235663351ffd7419d2ba199e281 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
@@ -24,11 +24,6 @@
  */
 -->
 <fixture>
-    <adminUser module="Magento_User">
-        <type>flat</type>
-        <entity_type>admin_user</entity_type>
-        <collection>Magento\User\Model\Resource\User\Collection</collection>
-    </adminUser>
     <adminUserInjectable module="Magento_User">
         <type>flat</type>
         <entity_type>admin_user</entity_type>
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
index e5a2ec81677b21ebc2986adcda30b298c95ec1a3..a5b7baf8dbfffcbcfc9837a3813f9e430a2f5a97 100644
--- 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
@@ -34,8 +34,14 @@
         <area>adminhtml</area>
         <class>Magento\User\Test\Page\Adminhtml\UserRoleEditRole</class>
     </adminUserRoleNew>
-    <adminAuthLogin>
-        <mca>admin/auth/login</mca>
-        <class>Magento\User\Test\Page\Adminhtml\AdminAuthLogin</class>
-    </adminAuthLogin>
+    <adminUserIndex>
+        <mca>admin/user</mca>
+        <area>adminhtml</area>
+        <class>Magento\User\Test\Page\Adminhtml\UserIndex</class>
+    </adminUserIndex>
+    <adminUserEdit>
+        <mca>admin/user/edit</mca>
+        <area>adminhtml</area>
+        <class>Magento\User\Test\Page\Adminhtml\UserEdit</class>
+    </adminUserEdit>
 </page>
\ No newline at end of file
diff --git a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Cleanup/TestCaseProperties.php b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Cleanup/TestCaseProperties.php
index ec8d844915e947ffc0fbbd865b2cc839694f9c5b..2a31fbdf526056e827b17fec522e6f01d4c37cf1 100644
--- a/dev/tests/integration/framework/Magento/TestFramework/Workaround/Cleanup/TestCaseProperties.php
+++ b/dev/tests/integration/framework/Magento/TestFramework/Workaround/Cleanup/TestCaseProperties.php
@@ -44,7 +44,7 @@ class TestCaseProperties
             foreach ($properties as $property) {
                 $property->setAccessible(true);
                 $value = $property->getValue($test);
-                if (is_object($value) && method_exists($value, '__destruct')) {
+                if (is_object($value) && method_exists($value, '__destruct') && is_callable([$value, '__destruct'])) {
                     $value->__destruct();
                 }
                 $property->setValue($test, null);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f95890098d6120ae0492ac2550216c788cc7758
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Resource\Product\Indexer\Eav;
+/**
+ * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
+ */
+class SourceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source
+     */
+    protected $source;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product
+     */
+    protected $productResource;
+
+    /**
+     * Sets up the fixture, for example, opens a network connection.
+     * This method is called before a test is executed.
+     */
+    protected function setUp()
+    {
+        $this->source = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source'
+        );
+
+        /** @var \Magento\Catalog\Model\Resource\Product $productResource */
+        $this->productResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Catalog\Model\Resource\Product'
+        );
+    }
+
+    /**
+     *  Test reindex for configurable product with both disabled and enabled variations.
+     */
+    public function testReindexEntitiesForConfigurableProduct()
+    {
+        /** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attr **/
+        $attr = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config')
+           ->getAttribute('catalog_product', 'test_configurable');
+        $attr->setIsFilterable(1)->save();
+
+        /** @var \Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection $options **/
+        $options = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection'
+        );
+        $options->setAttributeFilter($attr->getId())->load();
+        $optionIds = $options->getAllIds();
+
+        $adapter = $this->productResource->getReadConnection();
+        $select = $adapter->select()->from($this->productResource->getTable('catalog_product_index_eav'))
+            ->where('entity_id = ?', 1)
+            ->where('attribute_id = ?', $attr->getId())
+            ->where('value IN (?)', $optionIds);
+
+        $result = $adapter->fetchAll($select);
+        $this->assertCount(2, $result);
+
+        /** @var \Magento\Catalog\Model\Product $product1 **/
+        $product1 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Product');
+        $product1 = $product1->load($optionIds[0] * 10);
+        $product1->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED)->save();
+
+        /** @var \Magento\Catalog\Model\Product $product2 **/
+        $product2 = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Catalog\Model\Product');
+        $product2 = $product2->load($optionIds[1] * 10);
+        $product2->setStatus(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED)->save();
+
+        $result = $adapter->fetchAll($select);
+        $this->assertCount(0, $result);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_ccsave_payment.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_rollback.php
similarity index 62%
rename from dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_ccsave_payment.php
rename to dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_rollback.php
index 33a4ed1899068f702988384bb047d544571f3d6d..6ffb72acf9bb123fe18604ce907ad2648eb8c84e 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/_files/quote_with_ccsave_payment.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_simple_rollback.php
@@ -22,15 +22,18 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-require 'quote_with_address.php';
-/** @var \Magento\Sales\Model\Quote $quote */
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
 
-$quote->getShippingAddress()->setShippingMethod('flatrate_flatrate');
-$quote->getPayment()->setMethod('ccsave');
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
 
-$quote->collectTotals();
-$quote->save();
+/** @var $product \Magento\Catalog\Model\Product */
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$product->load(1);
+if ($product->getId()) {
+    $product->delete();
+}
 
-$objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-$quoteService = $objectManager->create('Magento\Sales\Model\Service\Quote', array('quote' => $quote));
-$quoteService->getQuote()->getPayment()->setMethod('ccsave');
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1bb99f463d4c3e04026820706d80b687c24ad2d
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/product_virtual_rollback.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$product->load(21);
+if ($product->getId()) {
+    $product->delete();
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_crosssell_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_crosssell_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..e0138c03c9b45fcfab4eee3b49194413d95b9e32
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_crosssell_rollback.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var $crossProduct \Magento\Catalog\Model\Product */
+$crossProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$crossProduct->load(1);
+if ($crossProduct->getId()) {
+    $crossProduct->delete();
+}
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$product->load(2);
+if ($product->getId()) {
+    $product->delete();
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_new_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_new_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..d3afe5486389e71311f3cc6b41f38b137e3c77d6
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_new_rollback.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$product->load(1);
+if ($product->getId()) {
+    $product->delete();
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_related_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_related_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb54578000682ce3705c69ce81f6957100aad588
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_related_rollback.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var $relatedProduct \Magento\Catalog\Model\Product */
+$relatedProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$relatedProduct->load(1);
+if ($relatedProduct->getId()) {
+    $relatedProduct->delete();
+}
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$product->load(2);
+if ($product->getId()) {
+    $product->delete();
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_upsell.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_upsell.php
new file mode 100644
index 0000000000000000000000000000000000000000..31bad3794336d6a3799845745b528bd2fc402dfa
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_upsell.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)
+ */
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$product->setTypeId(
+    \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE
+)->setId(
+    1
+)->setAttributeSetId(
+    4
+)->setName(
+    'Simple Up Sell'
+)->setSku(
+    'simple'
+)->setPrice(
+    100
+)->setVisibility(
+    \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH
+)->setStatus(
+    \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED
+)->setWebsiteIds(
+    array(1)
+)->setStockData(
+    array('qty' => 100, 'is_in_stock' => 1)
+)->save();
+
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$product->setTypeId(
+    \Magento\Catalog\Model\Product\Type::TYPE_SIMPLE
+)->setId(
+    2
+)->setAttributeSetId(
+    4
+)->setName(
+    'Simple Product With Up Sell'
+)->setSku(
+    'simple_with_upsell'
+)->setPrice(
+    10
+)->setVisibility(
+    \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH
+)->setStatus(
+    \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED
+)->setWebsiteIds(
+    array(1)
+)->setStockData(
+    array('qty' => 100, 'is_in_stock' => 1)
+)->setUpSellLinkData(
+    array(1 => array('position' => 1))
+)->save();
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/products_upsell_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_upsell_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..f15594777e5582ebbb2e8cae058a4eca77715e72
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/products_upsell_rollback.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)
+ */
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+/** @var $upSellProduct \Magento\Catalog\Model\Product */
+$upSellProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$upSellProduct->load(1);
+if ($upSellProduct->getId()) {
+    $upSellProduct->delete();
+}
+
+/** @var $product \Magento\Catalog\Model\Product */
+$product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$product->load(2);
+if ($product->getId()) {
+    $product->delete();
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/Centinel/CreateOrderTest.php b/dev/tests/integration/testsuite/Magento/Centinel/CreateOrderTest.php
index 5b6f063d36b59d1bc66b20541e89a253c55e5410..e32afba7425f241844915710c80830f192ff894f 100644
--- a/dev/tests/integration/testsuite/Magento/Centinel/CreateOrderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Centinel/CreateOrderTest.php
@@ -28,6 +28,12 @@ namespace Magento\Centinel;
  */
 class CreateOrderTest extends \Magento\Backend\Utility\Controller
 {
+    public function setUp()
+    {
+        parent::setUp();
+        $this->markTestIncomplete('MAGETWO-24796: [TD] Fix integration test according to story MAGETWO-23885');
+    }
+
     /**
      * @magentoConfigFixture default_store payment/ccsave/centinel 1
      * @magentoDataFixture Magento/Catalog/_files/product_simple.php
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
index b0add5539b38bc28a6881fc5ace61a5763f71b59..5bd46f2824fc0b4d0d1a5f3623bc6adc829eb0a3 100644
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
+++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
@@ -458,10 +458,10 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @param array $productsData
-     * @dataProvider generateSimpleProductsWithoutQtyDataProvider
+     * @dataProvider generateSimpleProductsWithPartialDataDataProvider
      * @magentoDbIsolation enabled
      */
-    public function testGenerateSimpleProductsWithoutQty($productsData)
+    public function testGenerateSimpleProductsWithPartialData($productsData)
     {
         $this->_product->setNewVariationsAttributeSetId(4);
         $generatedProducts = $this->_model->generateSimpleProducts($this->_product, $productsData);
@@ -472,6 +472,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             );
             $product->load($productId);
             $this->assertEquals('0', $product->getStockItem()->getData('manage_stock'));
+            $this->assertEquals('1', $product->getStockItem()->getData('is_in_stock'));
         }
     }
 
@@ -515,7 +516,7 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
     /**
      * @return array
      */
-    public static function generateSimpleProductsWithoutQtyDataProvider()
+    public static function generateSimpleProductsWithPartialDataDataProvider()
     {
         return array(
             array(
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/Edit/FormTest.php
index c08088f6cc346ae617e0d2be789a63b0ca881923..2c6cf5b1d62c2c77d5b689116aea91077bf662f9 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/Edit/FormTest.php
@@ -106,10 +106,11 @@ class FormTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetFormExistInCustomGroup()
     {
+        $builder = Bootstrap::getObjectManager()->create('\Magento\Framework\Service\V1\Data\FilterBuilder');
         /** @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchCriteria */
         $searchCriteria = Bootstrap::getObjectManager()
             ->create('Magento\Framework\Service\V1\Data\SearchCriteriaBuilder')
-            ->addFilter([(new FilterBuilder())->setField('code')->setValue('custom_group')->create()])->create();
+            ->addFilter([$builder->setField('code')->setValue('custom_group')->create()])->create();
         /** @var CustomerGroup $customerGroup */
         $customerGroup = $this->customerGroupService->searchGroups($searchCriteria)->getItems()[0];
         $this->registry->register(RegistryConstants::CURRENT_GROUP_ID, $customerGroup->getId());
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
index 41f7651b6d26329f51271562cbd165c8d0e83a0c..0a44b35075f928e199e5bfa8bcb0322f713c56fd 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
@@ -97,10 +97,11 @@ class EditTest extends AbstractController
      */
     public function testDeleteButtonExistInCustomGroup()
     {
+        $builder = Bootstrap::getObjectManager()->create('\Magento\Framework\Service\V1\Data\FilterBuilder');
         /** @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchCriteria */
         $searchCriteria = Bootstrap::getObjectManager()
             ->create('Magento\Framework\Service\V1\Data\SearchCriteriaBuilder')
-            ->addFilter([(new FilterBuilder())->setField('code')->setValue('custom_group')->create()])->create();
+            ->addFilter([$builder->setField('code')->setValue('custom_group')->create()])->create();
         /** @var CustomerGroup $customerGroup */
         $customerGroup = $this->customerGroupService->searchGroups($searchCriteria)->getItems()[0];
         $this->getRequest()->setParam('id', $customerGroup->getId());
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
index efc37113916b6ba4c05604e6c34c1e538b0edfdd..fd36e4dfd62dd2568cf6900e3c4b6b4be5301230 100755
--- a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
@@ -76,6 +76,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
         $this->_customerDetailsBuilder =
             $this->_objectManager->create('Magento\Customer\Service\V1\Data\CustomerDetailsBuilder');
 
+        $regionBuilder = $this->_objectManager->create('Magento\Customer\Service\V1\Data\RegionBuilder');
         $this->_addressBuilder->setId(1)
             ->setCountryId('US')
             ->setCustomerId(1)
@@ -83,7 +84,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             ->setDefaultShipping(true)
             ->setPostcode('75477')
             ->setRegion(
-                (new V1\Data\RegionBuilder())->setRegionCode('AL')->setRegion('Alabama')->setRegionId(1)->create()
+                $regionBuilder->setRegionCode('AL')->setRegion('Alabama')->setRegionId(1)->create()
             )
             ->setStreet(['Green str, 67'])
             ->setTelephone('3468676')
@@ -99,7 +100,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             ->setDefaultShipping(false)
             ->setPostcode('47676')
             ->setRegion(
-                (new V1\Data\RegionBuilder())->setRegionCode('AL')->setRegion('Alabama')->setRegionId(1)->create()
+                $regionBuilder->setRegionCode('AL')->setRegion('Alabama')->setRegionId(1)->create()
             )
             ->setStreet(['Black str, 48'])
             ->setCity('CityX')
@@ -1217,22 +1218,23 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
 
     public function searchCustomersDataProvider()
     {
+        $builder = Bootstrap::getObjectManager()->create('\Magento\Framework\Service\V1\Data\FilterBuilder');
         return [
             'Customer with specific email' => [
-                [(new FilterBuilder())->setField('email')->setValue('customer@search.example.com')->create()],
+                [$builder->setField('email')->setValue('customer@search.example.com')->create()],
                 null,
                 [1 => ['email' => 'customer@search.example.com', 'firstname' => 'Firstname']]
             ],
             'Customer with specific first name' => [
-                [(new FilterBuilder())->setField('firstname')->setValue('Firstname2')->create()],
+                [$builder->setField('firstname')->setValue('Firstname2')->create()],
                 null,
                 [2 => ['email' => 'customer2@search.example.com', 'firstname' => 'Firstname2']]
             ],
             'Customers with either email' => [
                 [],
                 [
-                    (new FilterBuilder())->setField('firstname')->setValue('Firstname')->create(),
-                    (new FilterBuilder())->setField('firstname')->setValue('Firstname2')->create()
+                    $builder->setField('firstname')->setValue('Firstname')->create(),
+                    $builder->setField('firstname')->setValue('Firstname2')->create()
                 ],
                 [
                     1 => ['email' => 'customer@search.example.com', 'firstname' => 'Firstname'],
@@ -1241,7 +1243,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             ],
             'Customers created since' => [
                 [
-                    (new FilterBuilder())->setField('created_at')->setValue('2011-02-28 15:52:26')
+                    $builder->setField('created_at')->setValue('2011-02-28 15:52:26')
                         ->setConditionType('gt')->create()
                 ],
                 [],
@@ -1266,7 +1268,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             ->create('Magento\Framework\Service\V1\Data\SearchCriteriaBuilder');
 
         // Filter for 'firstname' like 'First'
-        $filterBuilder = new FilterBuilder();
+        $filterBuilder = $this->_objectManager->create('\Magento\Framework\Service\V1\Data\FilterBuilder');
         $firstnameFilter = $filterBuilder->setField('firstname')
             ->setConditionType('like')
             ->setValue('First%')
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAddressServiceTest.php b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAddressServiceTest.php
index ec65c59b472e168286e01252c4057b6c352efdb9..767f5b0a12900d1c13c73fa38b45b505a60670bb 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAddressServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerAddressServiceTest.php
@@ -60,7 +60,8 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
         $this->_addressBuilder = $this->_objectManager->create('Magento\Customer\Service\V1\Data\AddressBuilder');
         $this->_customerBuilder = $this->_objectManager->create('Magento\Customer\Service\V1\Data\CustomerBuilder');
 
-        $region = (new \Magento\Customer\Service\V1\Data\RegionBuilder())
+        $builder = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\RegionBuilder');
+        $region = $builder
             ->setRegionCode('AL')
             ->setRegion('Alabama')
             ->setRegionId(1)
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerGroupServiceTest.php b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerGroupServiceTest.php
index 38b6d907034964f98e5be0202c45be72c8f40797..90053a700c367da98f381026af0fa75f260cc7f8 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerGroupServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Service/V1/CustomerGroupServiceTest.php
@@ -143,7 +143,8 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
 
     public function testCreateGroup()
     {
-        $group = (new Data\CustomerGroupBuilder())->setId(null)->setCode('Test Group')->setTaxClassId(3)->create();
+        $builder = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\CustomerGroupBuilder');
+        $group = $builder->setId(null)->setCode('Test Group')->setTaxClassId(3)->create();
         $groupId = $this->_groupService->saveGroup($group);
         $this->assertNotNull($groupId);
 
@@ -155,7 +156,8 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
 
     public function testUpdateGroup()
     {
-        $group = (new Data\CustomerGroupBuilder())->setId(null)->setCode('New Group')->setTaxClassId(3)->create();
+        $builder = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\CustomerGroupBuilder');
+        $group = $builder->setId(null)->setCode('New Group')->setTaxClassId(3)->create();
         $groupId = $this->_groupService->saveGroup($group);
         $this->assertNotNull($groupId);
 
@@ -164,7 +166,7 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($group->getCode(), $newGroup->getCode());
         $this->assertEquals($group->getTaxClassId(), $newGroup->getTaxClassId());
 
-        $updates = (new Data\CustomerGroupBuilder())->setId($groupId)->setCode('Updated Group')->setTaxClassId(3)
+        $updates = $builder->setId($groupId)->setCode('Updated Group')->setTaxClassId(3)
             ->create();
         $newId = $this->_groupService->saveGroup($updates);
         $this->assertEquals($newId, $groupId);
@@ -256,17 +258,18 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
 
     public function searchGroupsDataProvider()
     {
+        $builder = Bootstrap::getObjectManager()->create('\Magento\Framework\Service\V1\Data\FilterBuilder');
         return [
             'eq' => [
-                [(new FilterBuilder())->setField(CustomerGroup::CODE)->setValue('General')->create()],
+                [$builder->setField(CustomerGroup::CODE)->setValue('General')->create()],
                 null,
                 [1 => [CustomerGroup::CODE => 'General', CustomerGroup::TAX_CLASS_ID => 3]]
             ],
             'and' => [
                 [
-                    (new FilterBuilder())->setField(CustomerGroup::CODE)->setValue('General')->create(),
-                    (new FilterBuilder())->setField(CustomerGroup::TAX_CLASS_ID)->setValue('3')->create(),
-                    (new FilterBuilder())->setField(CustomerGroup::ID)->setValue('1')->create(),
+                    $builder->setField(CustomerGroup::CODE)->setValue('General')->create(),
+                    $builder->setField(CustomerGroup::TAX_CLASS_ID)->setValue('3')->create(),
+                    $builder->setField(CustomerGroup::ID)->setValue('1')->create(),
                 ],
                 [],
                 [1 => [CustomerGroup::CODE => 'General', CustomerGroup::TAX_CLASS_ID => 3]]
@@ -274,8 +277,8 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
             'or' => [
                 [],
                 [
-                    (new FilterBuilder())->setField(CustomerGroup::CODE)->setValue('General')->create(),
-                    (new FilterBuilder())->setField(CustomerGroup::CODE)->setValue('Wholesale')->create(),
+                    $builder->setField(CustomerGroup::CODE)->setValue('General')->create(),
+                    $builder->setField(CustomerGroup::CODE)->setValue('Wholesale')->create(),
                 ],
                 [
                     1 => [CustomerGroup::CODE => 'General', CustomerGroup::TAX_CLASS_ID => 3],
@@ -284,7 +287,7 @@ class CustomerGroupServiceTest extends \PHPUnit_Framework_TestCase
             ],
             'like' => [
                 [
-                    (new FilterBuilder())->setField(CustomerGroup::CODE)->setValue('er')->setConditionType('like')
+                    $builder->setField(CustomerGroup::CODE)->setValue('er')->setConditionType('like')
                         ->create()
                 ],
                 [],
diff --git a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_group.php b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_group.php
index a99badfc753869acd2165d880ed439ef4cf285ad..2bbf2c1bed2fc202a10a4a768765d73c83fa7f19 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/_files/customer_group.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/_files/customer_group.php
@@ -25,10 +25,11 @@
 $customerGroupService = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
     'Magento\Customer\Service\V1\CustomerGroupService'
 );
-$customerGroupBuilder = (new Magento\Customer\Service\V1\Data\CustomerGroupBuilder())->setCode(
-    'custom_group'
-)->setTaxClassId(
-    3
+
+$builder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+    '\Magento\Customer\Service\V1\Data\CustomerGroupBuilder'
 );
+$customerGroupBuilder = $builder->setCode('custom_group')->setTaxClassId(3);
+
 $customerGroup = new Magento\Customer\Service\V1\Data\CustomerGroup($customerGroupBuilder);
 $customerGroupService->saveGroup($customerGroup);
diff --git a/dev/tests/integration/testsuite/Magento/DesignEditor/Model/Translate/_files/_inline_page_original.html b/dev/tests/integration/testsuite/Magento/DesignEditor/Model/Translate/_files/_inline_page_original.html
index 7c275839c59e0fdf8b366227203f5e9b97bff5c1..e242158b1386fbde096cd3d19a10f26944e5083f 100644
--- a/dev/tests/integration/testsuite/Magento/DesignEditor/Model/Translate/_files/_inline_page_original.html
+++ b/dev/tests/integration/testsuite/Magento/DesignEditor/Model/Translate/_files/_inline_page_original.html
@@ -18,9 +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.
  *
- * @category    Magento
- * @package     Magento_DesignEditor
- * @subpackage  integration_tests
  * @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)
  */
diff --git a/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_rollback.php b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..68994cbb42c944a10d3470001635618ee99c9979
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/GroupedProduct/_files/product_grouped_rollback.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var \Magento\Framework\Registry $registry */
+$registry = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Registry');
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', true);
+
+
+/** @var $simpleProduct \Magento\Catalog\Model\Product */
+$simpleProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$simpleProduct->load(2);
+if ($simpleProduct->getId()) {
+    $simpleProduct->delete();
+}
+
+/** @var $virtualProduct \Magento\Catalog\Model\Product */
+$virtualProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$virtualProduct->load(21);
+if ($virtualProduct->getId()) {
+    $virtualProduct->delete();
+}
+
+/** @var $groupedProduct \Magento\Catalog\Model\Product */
+$groupedProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Catalog\Model\Product');
+$groupedProduct->load(9);
+if ($groupedProduct->getId()) {
+    $groupedProduct->delete();
+}
+
+$registry->unregister('isSecureArea');
+$registry->register('isSecureArea', false);
diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/_files/product_with_custom_options.csv b/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/_files/product_with_custom_options.csv
index d75112c11cbf95711fcce0d15d773f367121835e..f0dcc3da8b4fe713ff88b68e57a126330f9e3022 100644
--- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/_files/product_with_custom_options.csv
+++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/_files/product_with_custom_options.csv
@@ -1,4 +1,4 @@
-"sku","_store","_attribute_set","_type","_category","_root_category","_product_websites","color","cost","country_of_manufacture","created_at","custom_design","custom_design_from","custom_design_to","custom_layout_update","description","gallery","gift_message_available","has_options","image","image_label","manufacturer","media_gallery","meta_description","meta_keyword","meta_title","minimal_price","msrp","msrp_display_actual_price_type","msrp_enabled","name","news_from_date","news_to_date","options_container","page_layout","price","required_options","short_description","small_image","small_image_label","special_from_date","special_price","special_to_date","status","tax_class_id","thumbnail","thumbnail_label","updated_at","url_key","url_path","visibility","weight","qty","min_qty","use_config_min_qty","is_qty_decimal","backorders","use_config_backorders","min_sale_qty","use_config_min_sale_qty","max_sale_qty","use_config_max_sale_qty","is_in_stock","notify_stock_qty","use_config_notify_stock_qty","manage_stock","use_config_manage_stock","use_config_qty_increments","qty_increments","use_config_enable_qty_inc","enable_qty_increments","is_decimal_divided","_links_related_sku","_links_related_position","_links_crosssell_sku","_links_crosssell_position","_links_upsell_sku","_links_upsell_position","_associated_sku","_associated_default_qty","_associated_position","_tier_price_website","_tier_price_customer_group","_tier_price_qty","_tier_price_price","_group_price_website","_group_price_customer_group","_group_price_price","_media_attribute_id","_media_image","_media_label","_media_position","_media_is_disabled","_custom_option_store","_custom_option_type","_custom_option_title","_custom_option_is_required","_custom_option_price","_custom_option_sku","_custom_option_max_characters","_custom_option_sort_order","_custom_option_row_title","_custom_option_row_price","_custom_option_row_sku","_custom_option_row_sort"
+"sku","_store","_attribute_set","_type","_category","_root_category","_product_websites","color","cost","country_of_manufacture","created_at","custom_design","custom_design_from","custom_design_to","custom_layout_update","description","gallery","gift_message_available","has_options","image","image_label","manufacturer","media_gallery","meta_description","meta_keyword","meta_title","minimal_price","msrp","msrp_display_actual_price_type","msrp_enabled","name","news_from_date","news_to_date","options_container","page_layout","price","required_options","short_description","small_image","small_image_label","special_from_date","special_price","special_to_date","status","tax_class_id","thumbnail","thumbnail_label","updated_at","url_key","url_path","visibility","weight","qty","min_qty","use_config_min_qty","is_qty_decimal","backorders","use_config_backorders","min_sale_qty","use_config_min_sale_qty","max_sale_qty","use_config_max_sale_qty","is_in_stock","notify_stock_qty","use_config_notify_stock_qty","manage_stock","use_config_manage_stock","use_config_qty_increments","qty_increments","use_config_enable_qty_inc","enable_qty_increments","is_decimal_divided","_related_sku","_related_position","_crosssell_sku","_crosssell_position","_upsell_sku","_upsell_position","_associated_sku","_associated_default_qty","_associated_position","_tier_price_website","_tier_price_customer_group","_tier_price_qty","_tier_price_price","_group_price_website","_group_price_customer_group","_group_price_price","_media_attribute_id","_media_image","_media_label","_media_position","_media_is_disabled","_custom_option_store","_custom_option_type","_custom_option_title","_custom_option_is_required","_custom_option_price","_custom_option_sku","_custom_option_max_characters","_custom_option_sort_order","_custom_option_row_title","_custom_option_row_price","_custom_option_row_sku","_custom_option_row_sort"
 "simple",,"Default","simple",,,"base",,,,,,,,,,,,1,,,,,,,,,,,,"New Product",,,"Block after Info Column",,"10.0000",1,,,,,,,1,,,,"2012-07-13 12:04:17","new-product","new-product.html",4,,"100.0000","0.0000",1,0,0,1,"1.0000",1,"0.0000",1,1,,1,0,1,1,"0.0000",1,0,0,,,,,,,,,,,,,,,,,,,,,,,"field","Test Field",1,"1.0000","1-text",100,0,,,,
 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,default,,"Test Field",,,,,,,,,
 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"date_time","Test Date and Time",1,"2.0000","2-date",,0,,,,
diff --git a/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/_files/products_to_import_invalid_attribute_set.csv b/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/_files/products_to_import_invalid_attribute_set.csv
index 8976e7f7f246ef98cfcdd5df61246a7caa9537aa..3f852c2b90c60551c6f2760016a2c29e9a8f5285 100644
--- a/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/_files/products_to_import_invalid_attribute_set.csv
+++ b/dev/tests/integration/testsuite/Magento/ImportExport/Model/Import/Entity/_files/products_to_import_invalid_attribute_set.csv
@@ -1,4 +1,4 @@
-sku,price,name,_type,_attribute_set,_links_upsell_sku,description
+sku,price,name,_type,_attribute_set,_upsell_sku,description
 simple1,25,"Simple Product",simple,Default,,description
 simple2,NULL,"Simple Product2",invalid attribute set,Default,,HiThere
 simple3,58,"Simple Product 3",simple,Default,simple2,description
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractTest.php
index 419c47799ccb51dfd9138478f2ec2accee7d3cae..166f138ed929699d8e91ebbe024ed866df47f0ea 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/Form/AbstractTest.php
@@ -67,10 +67,16 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
         $formFactory = $objectManager->get('Magento\Framework\Data\FormFactory');
         $form = $formFactory->create();
         $fieldset = $form->addFieldset('test_fieldset', array());
-        $dateAttribute = (new AttributeMetadataBuilder(
-            new OptionBuilder(),
-            new ValidationRuleBuilder()
-        ))->setAttributeCode(
+        $attributeBuilder = $objectManager->create(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            [
+                'optionBuilder' => $objectManager->create('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder'),
+                'validationRuleBuilder' => $objectManager->create(
+                    '\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder'
+                ),
+            ]
+        );
+        $dateAttribute = $attributeBuilder->setAttributeCode(
             'date'
         )->setBackendType(
             'datetime'
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/FormTest.php b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/FormTest.php
index 1e4b6478cfea180eea09cdedd7c04f0c38774dad..8b395149a37f8a18e388fd6f5185d9f30fa363c2 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Block/Adminhtml/Order/Create/FormTest.php
@@ -107,6 +107,9 @@ ORDER_DATA_JSON;
 
     private function setUpMockAddress()
     {
+        $regionBuilder1 = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\RegionBuilder');
+        $regionBuilder2 = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\RegionBuilder');
+
         /** @var \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder */
         $addressBuilder = $this->_objectManager->create('Magento\Customer\Service\V1\Data\AddressBuilder');
         /** @var \Magento\Customer\Service\V1\CustomerAddressServiceInterface $addressService */
@@ -126,7 +129,7 @@ ORDER_DATA_JSON;
             '75477'
         )->setRegion(
             new V1\Data\Region(
-                (new V1\Data\RegionBuilder())->populateWithArray(
+                $regionBuilder1->populateWithArray(
                     array('region_code' => 'AL', 'region' => 'Alabama', 'region_id' => 1)
                 )
             )
@@ -156,7 +159,7 @@ ORDER_DATA_JSON;
             '47676'
         )->setRegion(
             new V1\Data\Region(
-                (new V1\Data\RegionBuilder())->populateWithArray(
+                $regionBuilder2->populateWithArray(
                     array('region_code' => 'AL', 'region' => 'Alabama', 'region_id' => 1)
                 )
             )
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
index f34d88da2cb59a6f98f8a756637ef24313e3a95b..f9f373c06b99594b877f47a060410ad2d769346a 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
@@ -138,33 +138,6 @@ class CreateTest extends \PHPUnit_Framework_TestCase
         $this->assertNull($payment->getCcLast4());
     }
 
-    /**
-     * @magentoDataFixture Magento/Sales/_files/order_paid_with_saved_cc.php
-     */
-    public function testInitFromOrderSavedCcInformationNotDeleted()
-    {
-        /** @var $objectManager \Magento\TestFramework\ObjectManager */
-        $objectManager = Bootstrap::getObjectManager();
-
-        /** @var $order \Magento\Sales\Model\Order */
-        $order = $objectManager->create('Magento\Sales\Model\Order');
-        $order->loadByIncrementId('100000001');
-
-        $payment = $order->getPayment();
-        $this->assertEquals('5', $payment->getCcExpMonth());
-        $this->assertEquals('2016', $payment->getCcExpYear());
-        $this->assertEquals('AE', $payment->getCcType());
-        $this->assertEquals('0005', $payment->getCcLast4());
-
-        $objectManager->get('Magento\Framework\Registry')->unregister('rule_data');
-        $payment = $this->_model->initFromOrder($order)->getQuote()->getPayment();
-
-        $this->assertEquals('5', $payment->getCcExpMonth());
-        $this->assertEquals('2016', $payment->getCcExpYear());
-        $this->assertEquals('AE', $payment->getCcType());
-        $this->assertEquals('0005', $payment->getCcLast4());
-    }
-
     /**
      * @magentoAppIsolation enabled
      */
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Model/Service/QuoteTest.php b/dev/tests/integration/testsuite/Magento/Sales/Model/Service/QuoteTest.php
index d422d31701a7d76026714fa50993fe7b79a93569..b6dc3f5470988d493c35e8721a7bb44793bb717c 100755
--- a/dev/tests/integration/testsuite/Magento/Sales/Model/Service/QuoteTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Model/Service/QuoteTest.php
@@ -228,6 +228,7 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
      */
     private function getSampleAddressEntity()
     {
+        $regionBuilder =  Bootstrap::getObjectManager()->create('\Magento\Customer\Service\V1\Data\RegionBuilder');
         $this->_customerAddressBuilder->setCountryId(
             'US'
         )->setDefaultBilling(
@@ -237,7 +238,7 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
         )->setPostcode(
             '75477'
         )->setRegion(
-            (new RegionBuilder())->setRegion('Alabama')->setRegionId(1)->setRegionCode('AL')->create()
+            $regionBuilder->setRegion('Alabama')->setRegionId(1)->setRegionCode('AL')->create()
         )->setStreet(
             array('Green str, 67')
         )->setTelephone(
@@ -260,7 +261,7 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
         )->setPostcode(
             '47676'
         )->setRegion(
-            (new RegionBuilder())->setRegion('Alabama')->setRegionId(1)->setRegionCode('AL')->create()
+            $regionBuilder->setRegion('Alabama')->setRegionId(1)->setRegionCode('AL')->create()
         )->setStreet(
             array('Black str, 48')
         )->setCity(
diff --git a/dev/tests/integration/testsuite/Magento/Sales/_files/order_paid_with_saved_cc.php b/dev/tests/integration/testsuite/Magento/Sales/_files/order_paid_with_saved_cc.php
deleted file mode 100644
index 7bab4a6991f8e013ce34ac4c492b7b043f237d53..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/Sales/_files/order_paid_with_saved_cc.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-\Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea(
-    \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE
-);
-
-$addressData = include __DIR__ . '/address_data.php';
-
-$billingAddress = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-    'Magento\Sales\Model\Order\Address',
-    array('data' => $addressData)
-);
-$billingAddress->setAddressType('billing');
-
-$shippingAddress = clone $billingAddress;
-$shippingAddress->setId(null)->setAddressType('shipping');
-
-$payment = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order\Payment');
-$payment->setMethod('ccsave')->setCcExpMonth('5')->setCcLast4('0005')->setCcType('AE')->setCcExpYear('2016');
-
-$order = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Sales\Model\Order');
-$order->setIncrementId(
-    '100000001'
-)->setSubtotal(
-    100
-)->setBaseSubtotal(
-    100
-)->setCustomerIsGuest(
-    true
-)->setBillingAddress(
-    $billingAddress
-)->setShippingAddress(
-    $shippingAddress
-)->setStoreId(
-    \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-        'Magento\Store\Model\StoreManagerInterface'
-    )->getStore()->getId()
-)->setPayment(
-    $payment
-);
-
-$order->save();
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
index be9f738483c99a252ea69c324a0abb6784503dfa..30dca15ae97320a61aeb78a50d5f719359cd13c0 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SetupUtil.php
@@ -488,7 +488,7 @@ class SetupUtil
     {
         /** @var \Magento\Customer\Service\V1\CustomerGroupService $customerGroupService */
         $customerGroupService = $this->objectManager->create('Magento\Customer\Service\V1\CustomerGroupService');
-        $customerGroupBuilder = (new \Magento\Customer\Service\V1\Data\CustomerGroupBuilder())
+        $customerGroupBuilder = $this->objectManager->create('\Magento\Customer\Service\V1\Data\CustomerGroupBuilder')
             ->setCode('custom_group')
             ->setTaxClassId($customerTaxClassId);
         $customerGroup = new \Magento\Customer\Service\V1\Data\CustomerGroup($customerGroupBuilder);
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
index 6706fb04571d9c3bfa94e1ed812738bfc0c62c0b..2c4621007df75244096eb76b80604f066f87fce6 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Type/CustomerTest.php
@@ -41,6 +41,7 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
     {
         /** @var $objectManager \Magento\TestFramework\ObjectManager */
         $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $builder = $this->_objectManager->create('\Magento\Customer\Service\V1\Data\CustomerGroupBuilder');
 
         /* Create a tax class */
         $model = $this->_objectManager->create('Magento\Tax\Model\ClassModel');
@@ -53,7 +54,7 @@ class CustomerTest extends \PHPUnit_Framework_TestCase
         $model->setId($taxClassId);
         /** @var $customerGroupService \Magento\Customer\Service\V1\CustomerGroupServiceInterface */
         $customerGroupService = $this->_objectManager->create('\Magento\Customer\Service\V1\CustomerGroupService');
-        $group = (new CustomerGroupBuilder())->setId(null)->setCode(self::GROUP_CODE)->setTaxClassId($taxClassId)
+        $group = $builder->setId(null)->setCode(self::GROUP_CODE)->setTaxClassId($taxClassId)
             ->create();
         $customerGroupService->saveGroup($group);
 
diff --git a/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/design-abstraction_select.html b/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/design-abstraction_select.html
index dd48203f1fa680126a221e23a11579a1d03c78c4..8349949dbe6bf4fd6908d338412b7f4bfd635906 100644
--- a/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/design-abstraction_select.html
+++ b/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/design-abstraction_select.html
@@ -18,9 +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.
  *
- * @category    Magento
- * @package     Magento_Widget
- * @subpackage  integration_tests
  * @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)
  */
diff --git a/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/page_types_select.html b/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/page_types_select.html
index 503e3cfb2d8960cf047acfc1cb95d34fba88cbf5..bc52f9da0ece2064196868a7ac8ea17de9bb155b 100644
--- a/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/page_types_select.html
+++ b/dev/tests/integration/testsuite/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit/Chooser/_files/page_types_select.html
@@ -18,9 +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.
  *
- * @category    Magento
- * @package     Magento_Widget
- * @subpackage  integration_tests
  * @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)
  */
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario.jmx b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario.jmx
index 33a9e95f11a7473c6d6a22a4696248ceb03615b6..327c10bc179f6572e248a3cd364c943448d0b0f2 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario.jmx
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario.jmx
@@ -19,9 +19,6 @@
  * 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     performance_tests
- * @subpackage  unit_tests
  * @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)
  */
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario.jtl b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario.jtl
index 53fd0e6678c0e4f3bea83b17b0ec5238e4cbb4ae..91ed72017c4a408cfa95ac77e3bf603af0b14f68 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario.jtl
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario.jtl
@@ -19,9 +19,6 @@
  * 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     performance_tests
- * @subpackage  unit_tests
  * @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)
  */
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_error.jmx b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_error.jmx
index 33a9e95f11a7473c6d6a22a4696248ceb03615b6..327c10bc179f6572e248a3cd364c943448d0b0f2 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_error.jmx
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_error.jmx
@@ -19,9 +19,6 @@
  * 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     performance_tests
- * @subpackage  unit_tests
  * @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)
  */
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_error.jtl b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_error.jtl
index 210427835de9535350bb9f43d96f48d708ff86a0..5d3f4c6ea18c924a2227727175cce7eea12db701 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_error.jtl
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_error.jtl
@@ -19,9 +19,6 @@
  * 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     performance_tests
- * @subpackage  unit_tests
  * @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)
  */
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_failure.jmx b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_failure.jmx
index 33a9e95f11a7473c6d6a22a4696248ceb03615b6..327c10bc179f6572e248a3cd364c943448d0b0f2 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_failure.jmx
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_failure.jmx
@@ -19,9 +19,6 @@
  * 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     performance_tests
- * @subpackage  unit_tests
  * @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)
  */
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_failure.jtl b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_failure.jtl
index 5433d676347f0a776a5bf597da75bacf6f2278d3..b9420e16cf01da25669358fddca19d21198452ad 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_failure.jtl
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_failure.jtl
@@ -19,9 +19,6 @@
  * 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     performance_tests
- * @subpackage  unit_tests
  * @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)
  */
diff --git a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_without_report.jmx b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_without_report.jmx
index 33a9e95f11a7473c6d6a22a4696248ceb03615b6..327c10bc179f6572e248a3cd364c943448d0b0f2 100644
--- a/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_without_report.jmx
+++ b/dev/tests/performance/framework/tests/unit/testsuite/Magento/Test/Performance/_files/scenario_without_report.jmx
@@ -19,9 +19,6 @@
  * 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     performance_tests
- * @subpackage  unit_tests
  * @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)
  */
diff --git a/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CodeSniffer.php b/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CodeSniffer.php
index 8d2e932729d10b61853e3f6ba9049e30f2b84239..2650dfb0097fb74597a6231f9aab321e9fcab988 100644
--- a/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CodeSniffer.php
+++ b/dev/tests/static/framework/Magento/TestFramework/CodingStandard/Tool/CodeSniffer.php
@@ -120,7 +120,7 @@ class CodeSniffer implements ToolInterface
         $this->wrapper->checkRequirements();
         $settings = $this->wrapper->getDefaults();
         $settings['files'] = $whiteList;
-        $settings['standard'] = $this->rulesetDir;
+        $settings['standard'] = [$this->rulesetDir];
         $settings['ignored'] = $blackList;
         $settings['extensions'] = $extensions;
         $settings['reportFile'] = $this->reportFile;
diff --git a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/CodingStandard/Tool/CodeSnifferTest.php b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/CodingStandard/Tool/CodeSnifferTest.php
index 2894dccb3f4a0942c5fdb7fe6105697c96306fda..91ebc3b58dc8fb98c9fe91fce863999331679d8d 100644
--- a/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/CodingStandard/Tool/CodeSnifferTest.php
+++ b/dev/tests/static/framework/tests/unit/testsuite/Magento/TestFramework/CodingStandard/Tool/CodeSnifferTest.php
@@ -65,7 +65,7 @@ class CodeSnifferTest extends \PHPUnit_Framework_TestCase
 
         $expectedCliEmulation = array(
             'files' => $whiteList,
-            'standard' => self::RULE_SET,
+            'standard' => [self::RULE_SET],
             'ignored' => $blackList,
             'extensions' => $extensions,
             'reportFile' => self::REPORT_FILE,
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 57923ed71f6145c776f106442798bef6c71587c8..f8bffc780f1b2f0de7288e4940411bedb7146e91 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -2517,6 +2517,13 @@ return array(
         'Magento\SalesArchive\Block\Adminhtml\Sales\Order\Grid\Button',
         'Magento\SalesArchive\Block\Adminhtml\Sales\Order\Grid'
     ],
+    ['Magento\OfflinePayments\Block\Form\Ccsave'],
+    ['Magento\OfflinePayments\Block\Info\Ccsave'],
+    ['Magento\OfflinePayments\Model\Ccsave'],
+    ['Magento\Sales\Model\Payment\Method\Converter'],
+    ['Magento\Payment\Model\Config\Source\Allowedmethods'],
+    ['Magento\Paypal\Model\PayflowDirect'],
+    ['Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Store'],
     ['Magento\Framework\View\Url', 'Magento\Framework\View\Asset\Repository'],
     ['Magento\Less\File\Source\Base', 'Magento\Framework\View\File\Collector\Base'],
     ['Magento\Less\File\Source\Theme', 'Magento\Framework\View\File\Collector\ThemeModular'],
@@ -2579,4 +2586,9 @@ return array(
     ['Magento\Css\PreProcessor\Cache\CacheInterface'],
     ['Magento\Css\PreProcessor\Cache\CacheManager'],
     ['Magento\Framework\View\Design\FileResolution\Strategy\ViewInterface'],
+    [
+        'Magento\Bundle\Pricing\Price\BasePrice',
+        'Magento\Catalog\Pricing\Price\BasePrice'
+    ],
+    ['\Magento\Bundle\Pricing\Price\BasePriceInterface'],
 );
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 06439ab61e2cacb599dd05643a3ec35ef6ce4745..e3181c66e2a5f9cbeff898435fc6d65b1d31a5ab 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
@@ -1696,6 +1696,12 @@ return array(
     ['_isDataChanged', 'Magento\Catalog\Model\Product'],
     ['getVisibleOnFrontStates', 'Magento\Sales\Model\Order\Config', 'getVisibleOnFrontStatuses'],
     ['getInvisibleOnFrontStates', 'Magento\Sales\Model\Order\Config', 'getInvisibleOnFrontStatuses'],
+    ['_shouldBeConverted', 'Magento\Sales\Model\Resource\AbstractResource'],
+    ['_beforeSave', 'Magento\Sales\Model\Resource\AbstractResource'],
+    ['_afterSave', 'Magento\Sales\Model\Resource\AbstractResource'],
+    ['_afterLoad', 'Magento\Sales\Model\Resource\AbstractResource'],
+    ['getAllMethods', 'Magento\Payment\Model\Config'],
+    ['_getMethod', 'Magento\Payment\Model\Config'],
     ['getViewFileUrl', 'Magento\Framework\View\Url', 'Magento\Framework\View\Asset\Repository::getUrl'],
     ['getCssFiles', 'Magento\Core\Helper\Theme', 'Magento\Core\Helper\Theme::getCssAssets'],
     ['getGroupedCssFiles', 'Magento\Core\Helper\Theme'],
diff --git a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt
index def5917a24f6aff3593b6ec479b5f117d99ce56e..b3840585683fd01d30a88b4873f0aafd5dc0eda3 100644
--- a/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Php/_files/whitelist/common.txt
@@ -27,6 +27,7 @@ app/code/Magento/Catalog/Model/ProductOptions
 app/code/Magento/Catalog/Model/ProductTypes
 app/code/Magento/Catalog/Model/Plugin
 app/code/Magento/Catalog/Model/Observer/Reindex.php
+app/code/Magento/Catalog/Service
 app/code/Magento/CatalogInventory/Block/Adminhtml/Form/Field/Stock.php
 app/code/Magento/Centinel/Model/State/Jcb.php
 app/code/Magento/Checkout/Block/Cart/Link.php
@@ -64,6 +65,7 @@ app/code/Magento/Eav/Model/Cache/Type.php
 app/code/Magento/GiftMessage/Model/Plugin
 app/code/Magento/GoogleShopping/Block/SiteVerification.php
 app/code/Magento/GoogleShopping/Model/AttributeFactory.php
+app/code/Magento/GroupedProduct/Service
 app/code/Magento/Eav/Model/Entity/Attribute/Config
 app/code/Magento/Eav/Model/Entity/Attribute/Config.php
 app/code/Magento/Email
diff --git a/dev/tests/unit/framework/Magento/TestFramework/Helper/ObjectManager.php b/dev/tests/unit/framework/Magento/TestFramework/Helper/ObjectManager.php
index 6d2c3a615a66b617cde15b0c9f23e380b7b3395a..36507e50baeeb2dccabb6f44628e57c3fc42706b 100644
--- a/dev/tests/unit/framework/Magento/TestFramework/Helper/ObjectManager.php
+++ b/dev/tests/unit/framework/Magento/TestFramework/Helper/ObjectManager.php
@@ -170,11 +170,46 @@ class ObjectManager
      */
     public function getObject($className, array $arguments = array())
     {
+        if (is_subclass_of($className, '\Magento\Framework\Service\Data\AbstractObjectBuilder')) {
+            return $this->getBuilder($className, $arguments);
+        }
         $constructArguments = $this->getConstructArguments($className, $arguments);
         $reflectionClass = new \ReflectionClass($className);
         return $reflectionClass->newInstanceArgs($constructArguments);
     }
 
+    /**
+     * Get data object builder
+     *
+     * @param string $className
+     * @param array $arguments
+     * @return object
+     */
+    protected function getBuilder($className, array $arguments)
+    {
+        $objectFactory = $this->_testObject->getMock('Magento\Framework\Service\Data\ObjectFactory', [], [], '', false);
+
+        if (!isset($arguments['objectFactory'])) {
+            $arguments['objectFactory'] = $objectFactory;
+        }
+
+
+        $constructArguments = $this->getConstructArguments($className, $arguments);
+        $reflectionClass = new \ReflectionClass($className);
+        $builderObject = $reflectionClass->newInstanceArgs($constructArguments);
+
+        $objectFactory->expects($this->_testObject->any())
+            ->method('create')
+            ->will($this->_testObject->returnCallback(
+                function ($className, $arguments) {
+                    $reflectionClass = new \ReflectionClass($className);
+                    return $reflectionClass->newInstanceArgs($arguments);
+                }
+            ));
+
+        return $builderObject;
+    }
+
     /**
      * Retrieve list of arguments that used for new object instance creation
      *
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/_files/invalidSystemXmlArray.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/_files/invalidSystemXmlArray.php
index a63ca7a436f5f4d600ecab92f6885d2fdc54d333..0dd4dc12280882c9799bec825347498ed9371676 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/_files/invalidSystemXmlArray.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/_files/invalidSystemXmlArray.php
@@ -45,8 +45,7 @@ return array(
         '<?xml version="1.0"?><config><system><section id="section1"><label>Label</label><field id="field_id">' .
         '</field><field id="new_field_id"/></section></system></config>',
         array(
-            "Element 'field': This element is not expected. Expected is one of ( label, class, tab, header_css, " .
-            "resource, group )."
+            "Element 'field': This element is not expected."
         )
     ),
     'group_id_not_unique' => array(
@@ -165,14 +164,6 @@ return array(
         '</field></group><group id="group2"><label>Label_One</label></group></section></system></config>',
         array("Element 'options': Missing child element(s). Expected is ( option ).")
     ),
-    'section_with_only_one_allowed_element' => array(
-        '<?xml version="1.0"?><config><system><section id="section1" advanced="false">' .
-        '<group id="group1" /></section></system></config>',
-        array(
-            "Element 'section': Missing child element(s). Expected is one of ( label, class, tab, header_css, " .
-            "resource, group )."
-        )
-    ),
     'system_node_without_allowed_elements' => array(
         '<?xml version="1.0"?><config><system/></config>',
         array("Element 'system': Missing child element(s). Expected is one of ( tab, section ).")
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/_files/valid_system.xml b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/_files/valid_system.xml
index ecb0fbd2fd4c6487ba1a2da399d870c78efe6943..710be42b3cce685f26b6bd9170fbdbaacbec437e 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Config/_files/valid_system.xml
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Config/_files/valid_system.xml
@@ -33,7 +33,6 @@
                 <fieldset_css>some_css</fieldset_css>
                 <clone_fields>1</clone_fields>
                 <clone_model>Some_Clone_Model</clone_model>
-                <expanded>1</expanded>
                 <field id="field_id" translate="label"  type="some_type" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
                     <label>Some Label</label>
                     <source_model>Some_Source_Model</source_model>
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/OptionTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/OptionTest.php
index ee87e8a321ffd3d29e93b50a02e56af6cdde82db..8be08360ed1f35da2afd530df755b9f0d71cf659 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/OptionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/OptionTest.php
@@ -122,7 +122,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface');
+        $priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
         $amount = $this->getMock('Magento\Framework\Pricing\Amount\AmountInterface');
 
         $priceRenderBlock = $this->getMockBuilder('Magento\Framework\Pricing\Render')
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Adjustment/CalculatorTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Adjustment/CalculatorTest.php
index e7171e2b24438149169711a9323940cea4e432cb..5f7cbfb1931f400c1c9d8971bf040da56426252a 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Adjustment/CalculatorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Adjustment/CalculatorTest.php
@@ -72,7 +72,7 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['getPriceInfo', 'getPriceType', '__wakeup'])
             ->disableOriginalConstructor()
             ->getMock();
-        $priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface', [], [], '', true);
+        $priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
         $priceInfo->expects($this->any())->method('getPrice')->will($this->returnCallback(function ($type) {
             if (!isset($this->priceMocks[$type])) {
                 throw new \PHPUnit_Framework_ExpectationFailedException('Unexpected type of price model');
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/BasePriceTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/BasePriceTest.php
deleted file mode 100644
index e74eb2e392014f848f036ec19d162a70f405d816..0000000000000000000000000000000000000000
--- a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/BasePriceTest.php
+++ /dev/null
@@ -1,123 +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\Bundle\Pricing\Price;
-
-use Magento\Catalog\Pricing\Price as CatalogPrice;
-
-class BasePriceTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var BasePrice
-     */
-    protected $model;
-
-    /**
-     * @var \Magento\Framework\Pricing\Object\SaleableInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $saleable;
-
-    /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $priceInfo;
-
-    /**
-     * @var float
-     */
-    protected $quantity;
-
-    public function setUp()
-    {
-        $this->quantity = 1.5;
-
-        $this->saleable = $this->getMockBuilder('Magento\Catalog\Model\Product')
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface');
-
-        $this->saleable->expects($this->once())
-            ->method('getPriceInfo')
-            ->will($this->returnValue($this->priceInfo));
-
-        $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->model = $objectHelper->getObject('Magento\Bundle\Pricing\Price\BasePrice', [
-            'saleableItem' => $this->saleable,
-            'quantity' => $this->quantity
-        ]);
-    }
-
-    /**
-     * @covers \Magento\Bundle\Pricing\Price\BasePrice::calculateBaseValue
-     * @covers \Magento\Bundle\Pricing\Price\BasePrice::getValue
-     */
-    public function testGetValue()
-    {
-        $priceValues = [115, 90, 75];
-        $tearPriceValue = 15;
-        $groupPriceValue = 10;
-        $specialPriceValue = 40;
-        $result = 45;
-
-        $pricesIncludedInBase = [];
-        foreach ($priceValues as $priceValue) {
-            $price = $this->getMock('Magento\Catalog\Pricing\Price\RegularPrice', [], [], '', false);
-            $price->expects($this->atLeastOnce())
-                ->method('getValue')
-                ->will($this->returnValue($priceValue));
-            $pricesIncludedInBase[] = $price;
-        }
-
-        $this->priceInfo->expects($this->once())
-            ->method('getPrices')
-            ->will($this->returnValue($pricesIncludedInBase));
-
-        $tearPrice = $this->getMock('Magento\Framework\Pricing\Price\PriceInterface');
-        $tearPrice->expects($this->atLeastOnce())
-            ->method('getValue')
-            ->will($this->returnValue($tearPriceValue));
-
-        $groupPrice = $this->getMock('Magento\Framework\Pricing\Price\PriceInterface');
-        $groupPrice->expects($this->atLeastOnce())
-            ->method('getValue')
-            ->will($this->returnValue($groupPriceValue));
-
-        $specialPrice = $this->getMock('Magento\Framework\Pricing\Price\PriceInterface');
-        $specialPrice->expects($this->atLeastOnce())
-            ->method('getValue')
-            ->will($this->returnValue($specialPriceValue));
-
-        $this->priceInfo->expects($this->any())
-            ->method('getPrice')
-            ->will($this->returnValueMap([
-                [CatalogPrice\TierPrice::PRICE_CODE, $this->quantity, $tearPrice],
-                [CatalogPrice\GroupPrice::PRICE_CODE, $this->quantity, $groupPrice],
-                [CatalogPrice\SpecialPrice::PRICE_CODE, $this->quantity, $specialPrice],
-            ]));
-
-        $this->assertEquals($result, $this->model->getValue());
-        $this->assertEquals($result, $this->model->getValue());
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/BundleSelectionPriceTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/BundleSelectionPriceTest.php
index 095891164fe08e2bf69f0af35fbdad25bf65e11d..eaa8ac14a49d078c0c0263b63456b1b065bec802 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/BundleSelectionPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/BundleSelectionPriceTest.php
@@ -24,240 +24,240 @@
 
 namespace Magento\Bundle\Pricing\Price;
 
-use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
 use Magento\Catalog\Pricing\Price as CatalogPrice;
+use Magento\Catalog\Pricing\Price\RegularPrice;
 
 /**
  * Class BundleSelectionPriceTest
  *
- *
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class BundleSelectionPriceTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var \Magento\Bundle\Pricing\Price\BundleSelectionPrice */
-    protected $bundleSelectionPrice;
-
-    /** @var ObjectManagerHelper */
-    protected $objectManagerHelper;
-
-    /** @var \Magento\Framework\Pricing\Object\SaleableInterface|\PHPUnit_Framework_MockObject_MockObject */
-    protected $saleableInterfaceMock;
-
-    /** @var float */
-    protected $quantity = 1.;
+    /**
+     * @var \Magento\Bundle\Pricing\Price\BundleSelectionPrice
+     */
+    protected $selectionPrice;
 
-    /** @var \Magento\Framework\Pricing\Adjustment\CalculatorInterface|\PHPUnit_Framework_MockObject_MockObject */
-    protected $calculatorInterfaceMock;
+    /**
+     * @var \Magento\Framework\Pricing\Adjustment\CalculatorInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $calculatorMock;
 
-    /** @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject */
+    /**
+     * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
+     */
     protected $productMock;
 
-    /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
-    protected $managerInterfaceMock;
+    /**
+     * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $bundleMock;
 
-    /** @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject */
-    protected $priceInfoMock;
+    /**
+     * @var \Magento\Framework\Event\Manager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManagerMock;
 
-    /** @var \Magento\Catalog\Pricing\Price\BasePrice|\PHPUnit_Framework_MockObject_MockObject */
-    protected $basePriceMock;
+    /**
+     * @var \Magento\Framework\Pricing\PriceInfo\Base|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $priceInfoMock;
 
-    /** @var \Magento\Catalog\Pricing\Price\FinalPrice|\PHPUnit_Framework_MockObject_MockObject */
+    /**
+     * @var \Magento\Catalog\Pricing\Price\FinalPrice|\PHPUnit_Framework_MockObject_MockObject
+     */
     protected $finalPriceMock;
 
-    /** @var \Magento\Catalog\Pricing\Price\RegularPrice|\PHPUnit_Framework_MockObject_MockObject */
+    /**
+     * @var \Magento\Catalog\Pricing\Price\RegularPrice|\PHPUnit_Framework_MockObject_MockObject
+     */
     protected $regularPriceMock;
 
-    /** @var  float */
-    protected $finalPriceValue;
-
-    /** @var  float */
-    protected $regularPriceValue;
+    /**
+     * @var \Magento\Bundle\Pricing\Price\DiscountCalculator|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $discountCalculatorMock;
 
-    /** @var  float */
-    protected $expectedResult;
+    /**
+     * @var float
+     */
+    protected $quantity;
 
-    protected function prepare()
+    /**
+     * Test setUp
+     */
+    protected function setUp()
     {
-        $this->saleableInterfaceMock = $this->getMock(
+        $this->productMock = $this->getMock(
             'Magento\Catalog\Model\Product',
-            [
-                'getPriceInfo',
-                'getSelectionPriceType',
-                'getSelectionPriceValue',
-                '__wakeup',
-                '__sleep'
-            ],
+            ['__wakeup', 'getPriceInfo', 'getSelectionPriceType', 'getSelectionPriceValue'],
             [],
             '',
             false
         );
-        $this->calculatorInterfaceMock = $this->getMock('Magento\Framework\Pricing\Adjustment\CalculatorInterface');
-        $this->productMock = $this->getMock(
+
+        $this->bundleMock = $this->getMock(
             'Magento\Catalog\Model\Product',
-            ['getPriceType', 'setFinalPrice', 'getQty', 'getData', 'getPriceInfo', '__wakeup', '__sleep'],
+            ['__wakeup', 'getPriceType', 'getPriceInfo', 'setFinalPrice', 'getData'],
+            [],
+            '',
+            false
+        );
+        $this->calculatorMock = $this->getMock(
+            'Magento\Framework\Pricing\Adjustment\CalculatorInterface',
+            [],
             [],
             '',
             false,
+            true,
             false
         );
-
-        $this->managerInterfaceMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
-
-        $this->priceInfoMock = $this->getMock('\Magento\Framework\Pricing\PriceInfoInterface');
-        $this->priceInfoMock->expects($this->atLeastOnce())
-            ->method('getPrice')
-            ->will($this->returnCallback(array($this, 'getPriceCallback')));
-
-        $this->productMock->expects($this->atLeastOnce())
+        $this->eventManagerMock = $this->getMock(
+            'Magento\Framework\Event\Manager',
+            ['dispatch'],
+            [],
+            '',
+            false
+        );
+        $this->priceInfoMock = $this->getMock(
+            'Magento\Framework\Pricing\PriceInfo\Base',
+            ['getPrice'],
+            [],
+            '',
+            false
+        );
+        $this->discountCalculatorMock = $this->getMock(
+            'Magento\Bundle\Pricing\Price\DiscountCalculator',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->finalPriceMock = $this->getMock(
+            'Magento\Catalog\Pricing\Price\FinalPrice',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->regularPriceMock = $this->getMock(
+            'Magento\Catalog\Pricing\Price\RegularPrice',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->productMock->expects($this->once())
             ->method('getPriceInfo')
             ->will($this->returnValue($this->priceInfoMock));
 
-        $this->saleableInterfaceMock->expects($this->atLeastOnce())
-            ->method('getPriceInfo')
-            ->will($this->returnValue($this->priceInfoMock));
+        $this->quantity = 1;
+        $this->selectionPrice = new \Magento\Bundle\Pricing\Price\BundleSelectionPrice(
+            $this->productMock,
+            $this->quantity,
+            $this->calculatorMock,
+            $this->bundleMock,
+            $this->eventManagerMock,
+            $this->discountCalculatorMock
+        );
     }
 
     /**
-     * @param string $priceType
-     * @return \PHPUnit_Framework_MockObject_MockObject
+     *  test fro method getValue with dynamic productType
      */
-    public function getPriceCallback($priceType)
+    public function testGetValueTypeDynamic()
     {
-        switch ($priceType) {
-            case CatalogPrice\BasePrice::PRICE_CODE:
-                $this->basePriceMock = $this->getMock('Magento\Bundle\Pricing\Price\BasePrice', [], [], '', false);
-                $this->basePriceMock->expects($this->once())
-                    ->method('calculateBaseValue')
-                    ->with($this->expectedResult)
-                    ->will($this->returnArgument(0));
-                return $this->basePriceMock;
-            case CatalogPrice\FinalPrice::PRICE_CODE:
-                $this->finalPriceMock = $this->getMock(
-                    'Magento\Catalog\Pricing\Price\FinalPrice',
-                    [],
-                    [],
-                    '',
-                    false
-                );
-                $this->finalPriceMock->expects($this->once())
-                    ->method('getValue')
-                    ->will($this->returnValue($this->finalPriceValue));
-                return $this->finalPriceMock;
-            case CatalogPrice\RegularPrice::PRICE_CODE:
-                $this->regularPriceMock = $this->getMock(
-                    'Magento\Catalog\Pricing\Price\RegularPrice',
-                    [],
-                    [],
-                    '',
-                    false
-                );
-                $this->regularPriceMock->expects($this->once())
-                    ->method('getValue')
-                    ->will($this->returnValue($this->regularPriceValue));
-                return $this->regularPriceMock;
-            default:
-                break;
-        }
-        $this->fail('Price mock was not found');
+        $this->bundleMock->expects($this->once())
+            ->method('getPriceType')
+            ->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_DYNAMIC));
+        $this->priceInfoMock->expects($this->once())
+            ->method('getPrice')
+            ->with($this->equalTo(FinalPrice::PRICE_CODE))
+            ->will($this->returnValue($this->finalPriceMock));
+        $this->finalPriceMock->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue(100));
+        $this->discountCalculatorMock->expects($this->once())
+            ->method('calculateDiscount')
+            ->with(
+                $this->equalTo($this->bundleMock),
+                $this->equalTo(100)
+            )
+            ->will($this->returnValue(70));
+        $this->assertEquals(70, $this->selectionPrice->getValue());
+        $this->assertEquals(70, $this->selectionPrice->getValue());
     }
 
     /**
-     * @param string $bundlePriceType
-     * @param array $selectionData
-     * @param float $expectedResult
-     * @dataProvider getValueDataProvider
+     * test for method getValue with type Fixed and selectionPriceType not null
      */
-    public function testGetValue($bundlePriceType, $selectionData, $expectedResult)
+    public function testGetValueTypeFixedWithSelectionPriceType()
     {
-        $this->prepare();
-        $this->expectedResult = $expectedResult;
-        $this->productMock->expects($this->once())
+        $this->bundleMock->expects($this->once())
             ->method('getPriceType')
-            ->will($this->returnValue($bundlePriceType));
-
-        if (isset($selectionData['getSelectionPriceType'])) {
-            $this->saleableInterfaceMock->expects($this->once())
-                ->method('getSelectionPriceType')
-                ->will($this->returnValue($selectionData['getSelectionPriceType']));
-            if ($selectionData['getSelectionPriceType']) {
-                $this->regularPriceValue = $selectionData['regularPriceValue'];
-                $this->productMock->expects($this->once())
-                    ->method('setFinalPrice')
-                    ->with($this->equalTo($selectionData['regularPriceValue']))
-                    ->will($this->returnSelf());
-                $this->productMock->expects($this->once())
-                    ->method('getQty')
-                    ->will($this->returnValue($selectionData['bundleQty']));
-
-                $this->productMock->expects($this->once())
-                    ->method('getData')
-                    ->with($this->equalTo('final_price'))
-                    ->will($this->returnValue($selectionData['finalPrice']));
-
-                $this->managerInterfaceMock->expects($this->once())
-                    ->method('dispatch')
-                    ->with(
-                        $this->equalTo('catalog_product_get_final_price'),
-                        $this->equalTo(['product' => $this->productMock, 'qty' => $selectionData['bundleQty']])
-                    )
-                    ->will($this->returnSelf());
-            }
-            $this->quantity = $selectionData['bundleQty'];
-            $this->saleableInterfaceMock->expects($this->once())
+            ->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED));
+        $this->bundleMock->expects($this->atLeastOnce())
+            ->method('getPriceInfo')
+            ->will($this->returnValue($this->priceInfoMock));
+        $this->priceInfoMock->expects($this->once())
+            ->method('getPrice')
+            ->with($this->equalTo(RegularPrice::PRICE_CODE))
+            ->will($this->returnValue($this->regularPriceMock));
+        $this->regularPriceMock->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue(100));
+        $this->bundleMock->expects($this->once())
+            ->method('setFinalPrice')
+            ->will($this->returnSelf());
+        $this->eventManagerMock->expects($this->once())
+            ->method('dispatch');
+        $this->bundleMock->expects($this->exactly(2))
+            ->method('getData')
+            ->will($this->returnValueMap(
+                    [
+                        ['qty', null, 1],
+                        ['final_price', null, 100],
+                    ]
+                )
+            );
+        $this->productMock->expects($this->once())
+            ->method('getSelectionPriceType')
+            ->will($this->returnValue(true));
+        $this->productMock->expects($this->any())
             ->method('getSelectionPriceValue')
-            ->will($this->returnValue($selectionData['selectionPriceValue']));
-        } else {
-            $this->finalPriceValue = $expectedResult;
-        }
-        $this->objectManagerHelper = new ObjectManagerHelper($this);
-        $this->bundleSelectionPrice = $this->objectManagerHelper->getObject(
-            'Magento\Bundle\Pricing\Price\BundleSelectionPrice',
-            [
-                'saleableItem' => $this->saleableInterfaceMock,
-                'quantity' => $this->quantity,
-                'calculator' => $this->calculatorInterfaceMock,
-                'bundleProduct' => $this->productMock,
-                'eventManager' => $this->managerInterfaceMock
-            ]
-        );
-
-        $this->assertSame($expectedResult, $this->bundleSelectionPrice->getValue());
-        // test value caching
-        $this->assertSame($expectedResult, $this->bundleSelectionPrice->getValue());
+            ->will($this->returnValue(100));
+        $this->discountCalculatorMock->expects($this->once())
+            ->method('calculateDiscount')
+            ->with(
+                $this->equalTo($this->bundleMock),
+                $this->equalTo(100)
+            )
+            ->will($this->returnValue(70));
+        $this->assertEquals(70, $this->selectionPrice->getValue());
     }
 
     /**
-     * @return array
+     * test for method getValue with type Fixed and selectionPriceType is empty or zero
      */
-    public function getValueDataProvider()
+    public function testGetValueTypeFixedWithoutSelectionPriceType()
     {
-        return [
-            'dynamic bundle' => [
-                'bundle type' => 0,
-                'selection data' => [],
-                'expected result' => 3.3
-            ],
-            'fixed bundle - percent price' => [
-                'bundle type' => 1,
-                'selection data' => [
-                    'getSelectionPriceType' => true,
-                    'regularPriceValue' => 4.,
-                    'bundleQty' => 3.,
-                    'finalPrice' => 100,
-                    'selectionPriceValue' => 10.
-                ],
-                'expected result' => 10.
-            ],
-            'fixed bundle - fixed price' => [
-                'bundle type' => 1,
-                'selection data' => [
-                    'getSelectionPriceType' => false,
-                    'bundleQty' => 2.,
-                    'selectionPriceValue' => 10.
-                ],
-                'expected result' => 20.
-            ],
-        ];
+        $this->bundleMock->expects($this->once())
+            ->method('getPriceType')
+            ->will($this->returnValue(\Magento\Bundle\Model\Product\Price::PRICE_TYPE_FIXED));
+        $this->productMock->expects($this->once())
+            ->method('getSelectionPriceType')
+            ->will($this->returnValue(false));
+        $this->productMock->expects($this->any())
+            ->method('getSelectionPriceValue')
+            ->will($this->returnValue(100));
+        $this->discountCalculatorMock->expects($this->once())
+            ->method('calculateDiscount')
+            ->with(
+                $this->equalTo($this->bundleMock),
+                $this->equalTo(100)
+            )
+            ->will($this->returnValue(70));
+        $this->assertEquals(70, $this->selectionPrice->getValue());
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/DiscountCalculatorTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/DiscountCalculatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f5c91f0cf83f7911178cdd0723cbe7878a37e16
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/DiscountCalculatorTest.php
@@ -0,0 +1,152 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Bundle\Pricing\Price;
+
+use Magento\Catalog\Pricing\Price\FinalPrice;
+
+/**
+ * Class DiscountCalculatorTest
+ */
+class DiscountCalculatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Bundle\Pricing\Price\DiscountCalculator
+     */
+    protected $calculator;
+
+    /**
+     * @var \Magento\Catalog\Model\Product|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var \Magento\Framework\Pricing\PriceInfo\Base |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $priceInfoMock;
+
+    /**
+     * @var \Magento\Catalog\Pricing\Price\FinalPrice|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $finalPriceMock;
+
+    /**
+     * @var \Magento\Bundle\Pricing\Price\DiscountProviderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $priceMock;
+
+    /**
+     * Test setUp
+     */
+    public function setUp()
+    {
+        $this->productMock = $this->getMock(
+            'Magento\Catalog\Model\Product',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->priceInfoMock = $this->getMock(
+            'Magento\Framework\Pricing\PriceInfo\Base',
+            ['getPrice', 'getPrices'],
+            [],
+            '',
+            false
+        );
+        $this->finalPriceMock = $this->getMock(
+            'Magento\Catalog\Pricing\Price\FinalPrice',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->priceMock = $this->getMockForAbstractClass('Magento\Bundle\Pricing\Price\DiscountProviderInterface');
+        $this->calculator = new \Magento\Bundle\Pricing\Price\DiscountCalculator();
+    }
+
+    /**
+     * Returns price mock with specified %
+     *
+     * @param int $value
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getPriceMock($value)
+    {
+        $price = clone $this->priceMock;
+        $price->expects($this->exactly(3))
+            ->method('getDiscountPercent')
+            ->will($this->returnValue($value));
+        return $price;
+    }
+
+    /**
+     * test method calculateDiscount with default price amount
+     */
+    public function testCalculateDiscountWithDefaultAmount()
+    {
+        $this->productMock->expects($this->exactly(2))
+            ->method('getPriceInfo')
+            ->will($this->returnValue($this->priceInfoMock));
+        $this->priceInfoMock->expects($this->once())
+            ->method('getPrice')
+            ->with($this->equalTo(FinalPrice::PRICE_CODE))
+            ->will($this->returnValue($this->finalPriceMock));
+        $this->finalPriceMock->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue(100));
+        $this->priceInfoMock->expects($this->once())
+            ->method('getPrices')
+            ->will($this->returnValue(
+                [
+                    $this->getPriceMock(30),
+                    $this->getPriceMock(20),
+                    $this->getPriceMock(40),
+                ]
+            )
+        );
+        $this->assertEquals(20, $this->calculator->calculateDiscount($this->productMock));
+    }
+
+    /**
+     * test method calculateDiscount with custom price amount
+     */
+    public function testCalculateDiscountWithCustomAmount()
+    {
+        $this->productMock->expects($this->once())
+            ->method('getPriceInfo')
+            ->will($this->returnValue($this->priceInfoMock));
+        $this->priceInfoMock->expects($this->once())
+            ->method('getPrices')
+            ->will($this->returnValue(
+                    [
+                        $this->getPriceMock(30),
+                        $this->getPriceMock(20),
+                        $this->getPriceMock(40),
+                    ]
+                )
+            );
+        $this->assertEquals(10, $this->calculator->calculateDiscount($this->productMock, 50));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/FinalPriceTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/FinalPriceTest.php
index f1e4daf947cca653c3e00cee7015dbff1d21c04c..6607d80eace010c2b0077f0fb1d95c517fe38152 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/FinalPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/FinalPriceTest.php
@@ -46,10 +46,10 @@ class FinalPriceTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $bundleCalculatorMock;
 
-    /** @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\Framework\Pricing\PriceInfo\Base |\PHPUnit_Framework_MockObject_MockObject */
     protected $priceInfoMock;
 
-    /** @var \Magento\Bundle\Pricing\Price\BasePrice|\PHPUnit_Framework_MockObject_MockObject */
+    /** @var \Magento\Catalog\Pricing\Price\BasePrice|\PHPUnit_Framework_MockObject_MockObject */
     protected $basePriceMock;
 
     /** @var BundleOptionPrice|\PHPUnit_Framework_MockObject_MockObject */
@@ -63,7 +63,7 @@ class FinalPriceTest extends \PHPUnit_Framework_TestCase
         $this->saleableInterfaceMock = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
         $this->bundleCalculatorMock = $this->getMock('Magento\Bundle\Pricing\Adjustment\BundleCalculatorInterface');
 
-        $this->basePriceMock = $this->getMock('Magento\Bundle\Pricing\Price\BasePrice', [], [], '', false);
+        $this->basePriceMock = $this->getMock('Magento\Catalog\Pricing\Price\BasePrice', [], [], '', false);
         $this->basePriceMock->expects($this->any())
             ->method('getValue')
             ->will($this->returnValue($this->baseAmount));
@@ -72,13 +72,13 @@ class FinalPriceTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->priceInfoMock = $this->getMock('\Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
+        $this->priceInfoMock = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
 
         $this->priceInfoMock->expects($this->atLeastOnce())
             ->method('getPrice')
             ->will($this->returnValueMap([
                 [\Magento\Catalog\Pricing\Price\BasePrice::PRICE_CODE, $this->basePriceMock],
-                [BundleOptionPrice::PRICE_CODE, $this->quantity, $this->bundleOptionMock]
+                [BundleOptionPrice::PRICE_CODE, $this->bundleOptionMock]
             ]));
 
         $this->saleableInterfaceMock->expects($this->once())
@@ -96,19 +96,14 @@ class FinalPriceTest extends \PHPUnit_Framework_TestCase
     /**
      * @dataProvider getValueDataProvider
      */
-    public function testGetValue($baseAmount, $discountValue, $result)
+    public function testGetValue($baseAmount, $optionsValue, $result)
     {
         $this->baseAmount = $baseAmount;
-        $optionsValue = rand(1, 10);
         $this->prepareMock();
         $this->bundleOptionMock->expects($this->once())
             ->method('getValue')
             ->will($this->returnValue($optionsValue));
 
-        $this->basePriceMock->expects($this->once())->method('calculateBaseValue')
-            ->with($this->equalTo($optionsValue))
-            ->will($this->returnValue($discountValue));
-
         $this->assertSame($result, $this->finalPrice->getValue());
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/GroupPriceTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/GroupPriceTest.php
index 060baae3ed733cf73309645c2d23f6a20fd035e3..0ec45ccb35d24b878394dae6c24104a300635acb 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/GroupPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/GroupPriceTest.php
@@ -36,7 +36,7 @@ class GroupPriceTest extends \PHPUnit_Framework_TestCase
     protected $saleable;
 
     /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfo\Base |\PHPUnit_Framework_MockObject_MockObject
      */
     protected $priceInfo;
 
@@ -47,25 +47,29 @@ class GroupPriceTest extends \PHPUnit_Framework_TestCase
             ->disableOriginalConstructor()
             ->getMock();
 
-        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface');
+        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
 
         $this->saleable->expects($this->once())
             ->method('getPriceInfo')
             ->will($this->returnValue($this->priceInfo));
 
         $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->model = $objectHelper->getObject('Magento\Bundle\Pricing\Price\GroupPrice', [
-            'saleableItem' => $this->saleable
-        ]);
+        $this->model = $objectHelper->getObject(
+            'Magento\Bundle\Pricing\Price\GroupPrice',
+            [
+                'saleableItem' => $this->saleable
+            ]
+        );
     }
 
     /**
-     * @param float $basePrice
-     * @param [] $storedGroupPrice
-     * @param float $value
+     * @param $regularPrice
+     * @param $storedGroupPrice
+     * @param $value
+     * @param $percent
      * @dataProvider getValueDataProvider
      */
-    public function testGetValue($basePrice, $storedGroupPrice, $value)
+    public function testGetValue($regularPrice, $storedGroupPrice, $value, $percent)
     {
         $customerGroupId = 234;
 
@@ -82,14 +86,14 @@ class GroupPriceTest extends \PHPUnit_Framework_TestCase
             $price = $this->getMock('Magento\Framework\Pricing\Price\PriceInterface');
             $this->priceInfo->expects($this->once())
                 ->method('getPrice')
-                ->with(\Magento\Catalog\Pricing\Price\BasePrice::PRICE_CODE)
+                ->with(\Magento\Catalog\Pricing\Price\RegularPrice::PRICE_CODE)
                 ->will($this->returnValue($price));
             $price->expects($this->once())
                 ->method('getValue')
-                ->will($this->returnValue($basePrice));
+                ->will($this->returnValue($regularPrice));
         }
-
         $this->assertEquals($value, $this->model->getValue());
+        $this->assertEquals($percent, $this->model->getDiscountPercent());
     }
 
     /**
@@ -98,9 +102,12 @@ class GroupPriceTest extends \PHPUnit_Framework_TestCase
     public function getValueDataProvider()
     {
         return array(
-            ['basePrice' => 100, 'storedGroupPrice' => [['cust_group' => 234, 'website_price' => 40]], 'value' => 60],
-            ['basePrice' => 75, 'storedGroupPrice' => [['cust_group' => 234, 'website_price' => 40]], 'value' => 45],
-            ['basePrice' => 75, 'storedGroupPrice' => [], 'value' => false],
+            ['regularPrice' => 100, 'storedGroupPrice'
+                => [['cust_group' => 234, 'website_price' => 40]], 'value' => 60, 'percent' => 60],
+            ['regularPrice' => 75, 'storedGroupPrice'
+                => [['cust_group' => 234, 'website_price' => 40]], 'value' => 45, 'percent' => 60],
+            ['regularPrice' => 75, 'storedGroupPrice'
+                => [], 'value' => false, 'percent' => null],
         );
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/SpecialPriceTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/SpecialPriceTest.php
index dea2c4834422cb9d23bac6986babb4b38264bbb7..431296fa1d68cdf447c92189fd6b06b3a88949cf 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/SpecialPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/SpecialPriceTest.php
@@ -36,7 +36,7 @@ class SpecialPriceTest extends \PHPUnit_Framework_TestCase
     protected $saleable;
 
     /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfo\Base |\PHPUnit_Framework_MockObject_MockObject
      */
     protected $priceInfo;
 
@@ -52,7 +52,7 @@ class SpecialPriceTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->localeDate = $this->getMock('Magento\Framework\Stdlib\DateTime\TimezoneInterface');
-        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface');
+        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
 
         $this->saleable->expects($this->once())
             ->method('getPriceInfo')
@@ -66,16 +66,17 @@ class SpecialPriceTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @param float $basePrice
-     * @param float $specialPrice
-     * @param bool $isScopeDateInInterval
-     * @param float $value
+     * @param $regularPrice
+     * @param $specialPrice
+     * @param $isScopeDateInInterval
+     * @param $value
+     * @param $percent
      * @dataProvider getValueDataProvider
      */
-    public function testGetValue($basePrice, $specialPrice, $isScopeDateInInterval, $value)
+    public function testGetValue($regularPrice, $specialPrice, $isScopeDateInInterval, $value, $percent)
     {
         $specialFromDate =  'some date from';
-        $specialToDate =  'som date to';
+        $specialToDate =  'some date to';
 
         $this->saleable->expects($this->once())
             ->method('getSpecialPrice')
@@ -103,15 +104,18 @@ class SpecialPriceTest extends \PHPUnit_Framework_TestCase
             $price = $this->getMock('Magento\Framework\Pricing\Price\PriceInterface');
             $this->priceInfo->expects($this->once())
                 ->method('getPrice')
-                ->with(\Magento\Catalog\Pricing\Price\BasePrice::PRICE_CODE)
+                ->with(\Magento\Catalog\Pricing\Price\RegularPrice::PRICE_CODE)
                 ->will($this->returnValue($price));
             $price->expects($this->once())
                 ->method('getValue')
-                ->will($this->returnValue($basePrice));
+                ->will($this->returnValue($regularPrice));
         }
 
         $this->assertEquals($value, $this->model->getValue());
+
+        //check that the second call will get data from cache the same as in first call
         $this->assertEquals($value, $this->model->getValue());
+        $this->assertEquals($percent, $this->model->getDiscountPercent());
     }
 
     /**
@@ -120,9 +124,12 @@ class SpecialPriceTest extends \PHPUnit_Framework_TestCase
     public function getValueDataProvider()
     {
         return array(
-            ['basePrice' => 100, 'specialPrice' => 40, 'isScopeDateInInterval' => true,  'value' => 60],
-            ['basePrice' => 75,  'specialPrice' => 40, 'isScopeDateInInterval' => true,  'value' => 45],
-            ['basePrice' => 75,  'specialPrice' => 40, 'isScopeDateInInterval' => false, 'value' => false],
+            ['regularPrice' => 100, 'specialPrice' => 40, 'isScopeDateInInterval' => true,  'value' => 40,
+                'percent' => 40],
+            ['regularPrice' => 75,  'specialPrice' => 40, 'isScopeDateInInterval' => true,  'value' => 30,
+                'percent' => 40],
+            ['regularPrice' => 75,  'specialPrice' => 40, 'isScopeDateInInterval' => false, 'value' => false,
+                'percent' => null],
         );
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/TierPriceTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/TierPriceTest.php
index 516dcc4679aa36bb4efc5c7e3392713b1cc5e97b..9d2aa9f67990d8902052385bf14d4f9d3aea10c9 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/TierPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Price/TierPriceTest.php
@@ -54,7 +54,7 @@ class TierPriceTest extends \PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface');
+        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
 
         $this->product = $this->getMockBuilder('Magento\Catalog\Model\Product')
             ->setMethods(['getPriceInfo', 'hasCustomerGroupId', 'getCustomerGroupId', 'getResource', '__wakeup'])
diff --git a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Render/FinalPriceBoxTest.php b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Render/FinalPriceBoxTest.php
index 1dc0eeea7b3d85e223e10b6d36eec1132d4f7f72..46ce50d346e96c67a3dc97fdce91aa4a41fae014 100644
--- a/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Render/FinalPriceBoxTest.php
+++ b/dev/tests/unit/testsuite/Magento/Bundle/Pricing/Render/FinalPriceBoxTest.php
@@ -52,7 +52,7 @@ class FinalPriceBoxTest extends \PHPUnit_Framework_TestCase
      */
     public function testShowRangePrice($value, $maxValue, $result)
     {
-        $priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface');
+        $priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
         $optionPrice = $this->getMockBuilder('Magento\Bundle\Pricing\Price\BundleOptionPrice')
             ->disableOriginalConstructor()
             ->getMock();
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/CategoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/CategoryTest.php
index 110292007c8c66ca244964cfbfc04192be2fb845..650bf9efc75c02b66613c5230ce4291ed033fc17 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/CategoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Helper/Form/CategoryTest.php
@@ -18,9 +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.
  *
- * @category    Magento
- * @package     Magento_Catalog
- * @subpackage  unit_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)
  */
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Options/AjaxTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Options/AjaxTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf0d854600d46dc8e0a9d783c1a7719911f3d881
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Block/Adminhtml/Product/Options/AjaxTest.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Block\Adminhtml\Product\Options;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class AjaxTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Catalog\Block\Adminhtml\Product\Options\Ajax */
+    protected $block;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Backend\Block\Context|\PHPUnit_Framework_MockObject_MockObject */
+    protected $context;
+
+    /** @var \Magento\Framework\Json\EncoderInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $encoderInterface;
+
+    /** @var \PHPUnit_Framework_MockObject_MockObject */
+    protected $productFactory;
+
+    /** @var \Magento\Core\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $coreHelper;
+
+    /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $registry;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMockBuilder('Magento\Backend\Block\Context')
+            ->setMethods(['getEventManager', 'getScopeConfig', 'getLayout', 'getRequest'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->encoderInterface= $this->getMock('Magento\Framework\Json\EncoderInterface');
+        $this->productFactory= $this->getMock('Magento\Catalog\Model\ProductFactory', ['create']);
+        $this->coreHelper= $this->getMock('Magento\Core\Helper\Data', [], [], '', false);
+        $this->registry= $this->getMock('Magento\Framework\Registry');
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+    }
+
+    /**
+     *  Test protected `_toHtml` method via public `toHtml` method.
+     */
+    public function testToHtml()
+    {
+        $eventManager= $this->getMockBuilder('Magento\Framework\Event\Manager')
+            ->disableOriginalConstructor()
+            ->setMethods(['dispatch'])
+            ->getMock();
+        $eventManager->expects($this->once())->method('dispatch')->will($this->returnValue(true));
+
+        $scopeConfig= $this->getMockBuilder('\Magento\Framework\App\Config')
+            ->setMethods(['getValue'])
+            ->disableOriginalConstructor()->getMock();
+        $scopeConfig->expects($this->once())->method('getValue')->withAnyParameters()
+            ->will($this->returnValue(false));
+
+        $product= $this->getMockBuilder('Magento\Catalog\Model\Product')->disableOriginalConstructor()
+            ->setMethods(['setStoreId', 'load', 'getId', '__wakeup', '__sleep'])
+            ->getMock();
+        $product->expects($this->once())->method('setStoreId')->will($this->returnSelf());
+        $product->expects($this->once())->method('load')->will($this->returnSelf());
+        $product->expects($this->once())->method('getId')->will($this->returnValue(1));
+
+        $optionsBlock = $this->getMockBuilder('Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Option')
+            ->setMethods(['setIgnoreCaching', 'setProduct', 'getOptionValues'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $optionsBlock->expects($this->once())->method('setIgnoreCaching')->with(true)->will($this->returnSelf());
+        $optionsBlock->expects($this->once())->method('setProduct')->with($product)->will($this->returnSelf());
+        $optionsBlock->expects($this->once())->method('getOptionValues')->will($this->returnValue([]));
+
+        $layout= $this->getMockBuilder('Magento\Framework\View\Layout\Element\Layout')
+            ->disableOriginalConstructor()
+            ->setMethods(['createBlock'])
+            ->getMock();
+        $layout->expects($this->once())->method('createBlock')
+            ->with('Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\Option')
+            ->will($this->returnValue($optionsBlock));
+
+        $request= $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->setMethods(['getParam'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $request->expects($this->once())->method('getParam')->with('store')
+            ->will($this->returnValue(0));
+
+        $this->context->expects($this->once())->method('getEventManager')
+            ->will($this->returnValue($eventManager));
+        $this->context->expects($this->once())->method('getScopeConfig')
+            ->will($this->returnValue($scopeConfig));
+        $this->context->expects($this->once())->method('getLayout')
+            ->will($this->returnValue($layout));
+        $this->context->expects($this->once())->method('getRequest')
+            ->will($this->returnValue($request));
+        $this->registry->expects($this->once())->method('registry')
+            ->with('import_option_products')
+            ->will($this->returnValue([1]));
+        $this->productFactory->expects($this->once())->method('create')->will($this->returnValue($product));
+
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Block\Adminhtml\Product\Options\Ajax',
+            [
+                'context' => $this->context,
+                'jsonEncoder' => $this->encoderInterface,
+                'productFactory' => $this->productFactory,
+                'coreData' => $this->coreHelper,
+                'registry' => $this->registry
+            ]
+        );
+        $this->block->toHtml();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Initialization/HelperTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Initialization/HelperTest.php
index 8a18f4f0bbd6ebd8aef8ca2054bebe01e4a39868..2faacb4ec0408f83dd0d70653775faf2c86fd9b0 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Initialization/HelperTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/Initialization/HelperTest.php
@@ -70,6 +70,11 @@ class HelperTest extends \PHPUnit_Framework_TestCase
      */
     protected $helper;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $jsHelperMock;
+
     protected function setUp()
     {
         $this->requestMock = $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false);
@@ -86,7 +91,7 @@ class HelperTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->productLinksMock = $this->getMock(
-            'Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks',
+            'Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks',
             array(),
             array(),
             '',
@@ -128,11 +133,13 @@ class HelperTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($this->storeMock)
         );
 
+        $this->jsHelperMock = $this->getMock('\Magento\Backend\Helper\Js', [], [], '', false);
         $this->helper = new Helper(
             $this->requestMock,
             $this->storeManagerMock,
             $this->stockFilterMock,
-            $this->productLinksMock
+            $this->productLinksMock,
+            $this->jsHelperMock
         );
     }
 
@@ -170,7 +177,7 @@ class HelperTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->requestMock->expects(
-            $this->at(2)
+            $this->at(3)
         )->method(
             'getPost'
         )->with(
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
index 585f5386382736063a17761123a5aa39b64b2499..85d3f8bc32a72648e2d0d8feafee01539f485223 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
@@ -30,12 +30,52 @@ class ProductTest extends \PHPUnit_Framework_TestCase
      */
     protected $_controller;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $context;
+
     /**
      * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor
      */
     protected $_priceProcessor;
 
     public function setUp()
+    {
+        $this->initContext();
+        $this->_priceProcessor = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Price\Processor')
+            ->disableOriginalConstructor()->getMock();
+
+        $productBuilder = $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Builder')->setMethods([
+            'build'
+        ])->disableOriginalConstructor()->getMock();
+
+        $product = $this->getMockBuilder('\Magento\Catalog\Model\Product')->disableOriginalConstructor()
+            ->setMethods(['getTypeId', 'getStoreId', '__sleep', '__wakeup'])->getMock();
+        $product->expects($this->any())->method('getTypeId')->will($this->returnValue('simple'));
+        $product->expects($this->any())->method('getStoreId')->will($this->returnValue('1'));
+        $productBuilder->expects($this->any())->method('build')->will($this->returnValue($product));
+
+        $this->_controller = new \Magento\Catalog\Controller\Adminhtml\Product(
+            $this->context,
+            $this->getMock('Magento\Framework\Registry', array(), array(), '', false),
+            $this->getMock('Magento\Framework\Stdlib\DateTime\Filter\Date', array(), array(), '', false),
+            $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper')
+                ->disableOriginalConstructor()->getMock(),
+            $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter')
+                ->disableOriginalConstructor()->getMock(),
+            $this->getMock('Magento\Catalog\Model\Product\Copier', array(), array(), '', false),
+            $productBuilder,
+            $this->getMock('Magento\Catalog\Model\Product\Validator', array(), array(), '', false),
+            $this->getMock('Magento\Catalog\Model\Product\TypeTransitionManager', array(), array(), '', false),
+            $this->_priceProcessor
+        );
+    }
+
+    /**
+     *  Init context object
+     */
+    protected function initContext()
     {
         $productActionMock = $this->getMock('Magento\Catalog\Model\Product\Action', array(), array(), '', false);
         $objectManagerMock = $this->getMockForAbstractClass(
@@ -48,76 +88,74 @@ class ProductTest extends \PHPUnit_Framework_TestCase
             array('get')
         );
         $objectManagerMock->expects($this->any())->method('get')->will($this->returnValue($productActionMock));
-        $this->_priceProcessor = $this->getMock(
-            'Magento\Catalog\Model\Indexer\Product\Price\Processor',
-            array(),
-            array(),
-            '',
-            false
-        );
-        $requestInterfaceMock = $this->getMock('Magento\Framework\App\RequestInterface', array(), array(), '', false);
-        $responseInterfaceMock = $this->getMock(
-            'Magento\Framework\App\ResponseInterface',
+
+        $block = $this->getMockBuilder('\Magento\Framework\View\Element\AbstractBlock')
+            ->disableOriginalConstructor()->getMockForAbstractClass();
+        $layout = $this->getMockBuilder('Magento\Framework\View\Layout\Element\Layout')
+            ->setMethods(['getBlock'])->disableOriginalConstructor()
+            ->getMock();
+        $layout->expects($this->any())->method('getBlock')->will($this->returnValue($block));
+        $view = $this->getMockBuilder('Magento\Framework\App\View')
+            ->setMethods(['loadLayout', 'getLayout', 'renderLayout'])
+            ->disableOriginalConstructor()->getMock();
+        $view->expects($this->any())->method('renderLayout')->will($this->returnSelf());
+        $view->expects($this->any())->method('getLayout')->will($this->returnValue($layout));
+        $view->expects($this->any())->method('loadLayout')->with(array(
+            'popup',
+            'catalog_product_new',
+            'catalog_product_simple'
+        ))->will($this->returnSelf());
+
+        $eventManager = $this->getMockBuilder('Magento\Framework\Event\Manager')
+            ->setMethods(['dispatch'])->disableOriginalConstructor()->getMock();
+        $eventManager->expects($this->any())->method('dispatch')->will($this->returnSelf());
+        $title = $this->getMockBuilder('\Magento\Framework\App\Action\Title')
+            ->setMethods(['add'])->disableOriginalConstructor()->getMock();
+        $title->expects($this->any())->method('add')->withAnyParameters()->will($this->returnSelf());
+        $requestInterfaceMock = $this->getMockBuilder('Magento\Framework\App\Request\Http')->setMethods(
+            array('getParam', 'getFullActionName')
+        )->disableOriginalConstructor()->getMock();
+
+        $responseInterfaceMock = $this->getMockBuilder('Magento\Framework\App\ResponseInterface')->setMethods(
             array('setRedirect', 'sendResponse')
-        );
-        $managerInterfaceMock = $this->getMock(
-            'Magento\Framework\Message\ManagerInterface',
-            array(),
-            array(),
-            '',
-            false
-        );
+        )->getMock();
+
+        $managerInterfaceMock = $this->getMock('Magento\Framework\Message\ManagerInterface');
         $sessionMock = $this->getMock('Magento\Backend\Model\Session', array(), array(), '', false);
         $actionFlagMock = $this->getMock('Magento\Framework\App\ActionFlag', array(), array(), '', false);
         $helperDataMock = $this->getMock('Magento\Backend\Helper\Data', array(), array(), '', false);
-        $contextMock = $this->getMock(
+        $this->context = $this->getMock(
             'Magento\Backend\App\Action\Context',
             array(
                 'getRequest',
                 'getResponse',
                 'getObjectManager',
+                'getEventManager',
                 'getMessageManager',
                 'getSession',
                 'getActionFlag',
-                'getHelper'
+                'getHelper',
+                'getTitle',
+                'getView'
             ),
             array(),
             '',
             false
         );
-        $contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($requestInterfaceMock));
-        $contextMock->expects($this->any())->method('getResponse')->will($this->returnValue($responseInterfaceMock));
-        $contextMock->expects($this->any())->method('getObjectManager')->will($this->returnValue($objectManagerMock));
-        $contextMock->expects($this->any())
+
+        $this->context->expects($this->any())->method('getTitle')->will($this->returnValue($title));
+        $this->context->expects($this->any())->method('getEventManager')->will($this->returnValue($eventManager));
+        $this->context->expects($this->any())->method('getView')->will($this->returnValue($view));
+        $this->context->expects($this->any())->method('getRequest')->will($this->returnValue($requestInterfaceMock));
+        $this->context->expects($this->any())->method('getResponse')->will($this->returnValue($responseInterfaceMock));
+        $this->context->expects($this->any())->method('getObjectManager')->will($this->returnValue($objectManagerMock));
+
+        $this->context->expects($this->any())
             ->method('getMessageManager')
             ->will($this->returnValue($managerInterfaceMock));
-        $contextMock->expects($this->any())->method('getSession')->will($this->returnValue($sessionMock));
-        $contextMock->expects($this->any())->method('getActionFlag')->will($this->returnValue($actionFlagMock));
-        $contextMock->expects($this->any())->method('getHelper')->will($this->returnValue($helperDataMock));
-        $this->_controller = new \Magento\Catalog\Controller\Adminhtml\Product(
-            $contextMock,
-            $this->getMock('Magento\Framework\Registry', array(), array(), '', false),
-            $this->getMock('Magento\Framework\Stdlib\DateTime\Filter\Date', array(), array(), '', false),
-            $this->getMock(
-                'Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper',
-                array(),
-                array(),
-                '',
-                false
-            ),
-            $this->getMock(
-                'Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter',
-                array(),
-                array(),
-                '',
-                false
-            ),
-            $this->getMock('Magento\Catalog\Model\Product\Copier', array(), array(), '', false),
-            $this->getMock('Magento\Catalog\Controller\Adminhtml\Product\Builder', array(), array(), '', false),
-            $this->getMock('Magento\Catalog\Model\Product\Validator', array(), array(), '', false),
-            $this->getMock('Magento\Catalog\Model\Product\TypeTransitionManager', array(), array(), '', false),
-            $this->_priceProcessor
-        );
+        $this->context->expects($this->any())->method('getSession')->will($this->returnValue($sessionMock));
+        $this->context->expects($this->any())->method('getActionFlag')->will($this->returnValue($actionFlagMock));
+        $this->context->expects($this->any())->method('getHelper')->will($this->returnValue($helperDataMock));
     }
 
     public function testMassStatusAction()
@@ -126,4 +164,18 @@ class ProductTest extends \PHPUnit_Framework_TestCase
 
         $this->_controller->massStatusAction();
     }
+
+    /**
+     * Testing `newAction` method
+     */
+    public function testNewAction()
+    {
+        $this->_controller->getRequest()->expects($this->at(0))->method('getParam')
+            ->with('set')->will($this->returnValue(true));
+        $this->_controller->getRequest()->expects($this->at(1))->method('getParam')
+            ->with('popup')->will($this->returnValue(true));
+        $this->_controller->getRequest()->expects($this->any())->method('getFullActionName')
+            ->will($this->returnValue('catalog_product_new'));
+        $this->_controller->newAction();
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/MediaTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/MediaTest.php
index 50156d529fd1897cfe89a3fa504f97f9028a129e..821ab44fee3ac603e8590fdd061fddc5de8f8018 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/MediaTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Backend/MediaTest.php
@@ -28,48 +28,93 @@ class MediaTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\Catalog\Model\Product\Attribute\Backend\Media
      */
-    protected $_model;
+    protected $model;
 
     /**
      * @var \Magento\TestFramework\Helper\ObjectManager
      */
     protected $_objectHelper;
 
+    /**
+     * @var \Magento\Framework\Object | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dataObject;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resourceModel;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $mediaConfig;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $mediaDirectory;
+
     protected function setUp()
     {
         $this->_objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', array(), array(), '', false);
+        $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
 
-        $fileStorageDb = $this->getMock('Magento\Core\Helper\File\Storage\Database', array(), array(), '', false);
-        $coreData = $this->getMock('Magento\Core\Helper\Data', array(), array(), '', false);
-        $resource = $this->getMock(
+        $fileStorageDb = $this->getMock('Magento\Core\Helper\File\Storage\Database', [], [], '', false);
+        $coreData = $this->getMock('Magento\Core\Helper\Data', [], [], '', false);
+        $this->resourceModel = $this->getMock(
             'Magento\Catalog\Model\Resource\Product\Attribute\Backend\Media',
-            array('getMainTable', '__wakeup'),
-            array(),
+            [
+                'getMainTable',
+                '__wakeup',
+                'insertGallery',
+                'deleteGalleryValueInStore',
+                'insertGalleryValueInStore',
+                'deleteGallery'
+            ],
+            [],
             '',
             false
         );
-        $resource->expects($this->any())->method('getMainTable')->will($this->returnValue('table'));
+        $this->resourceModel->expects($this->any())->method('getMainTable')->will($this->returnValue('table'));
 
-        $mediaConfig = $this->getMock('Magento\Catalog\Model\Product\Media\Config', array(), array(), '', false);
-        $directory = $this->getMockBuilder(
-            'Magento\Framework\Filesystem\Directory\Write'
-        )->disableOriginalConstructor()->getMock();
+        $this->mediaConfig = $this->getMock('Magento\Catalog\Model\Product\Media\Config', [], [], '', false);
+        $this->mediaDirectory = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\Write')
+            ->disableOriginalConstructor()
+            ->getMock();
         $filesystem = $this->getMockBuilder('Magento\Framework\App\Filesystem')
             ->disableOriginalConstructor()
             ->getMock();
-        $filesystem->expects($this->once())->method('getDirectoryWrite')->will($this->returnValue($directory));
-        $this->_model = $this->_objectHelper->getObject(
+        $filesystem->expects($this->once())->method('getDirectoryWrite')->will(
+            $this->returnValue($this->mediaDirectory)
+        );
+
+        $this->productFactory = $this->getMockBuilder('Magento\Catalog\Model\Resource\ProductFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+
+        $this->model = $this->_objectHelper->getObject(
             'Magento\Catalog\Model\Product\Attribute\Backend\Media',
-            array(
+            [
+                'productFactory' => $this->productFactory,
                 'eventManager' => $eventManager,
                 'fileStorageDb' => $fileStorageDb,
                 'coreData' => $coreData,
-                'mediaConfig' => $mediaConfig,
+                'mediaConfig' => $this->mediaConfig,
                 'filesystem' => $filesystem,
-                'resourceProductAttribute' => $resource
-            )
+                'resourceProductAttribute' => $this->resourceModel
+            ]
         );
+        $this->dataObject = $this->getMockBuilder('Magento\Framework\Object')
+            ->disableOriginalConstructor()
+            ->setMethods(['getIsDuplicate', 'isLockedAttribute'])
+            ->getMock();
     }
 
     public function testGetAffectedFields()
@@ -79,33 +124,139 @@ class MediaTest extends \PHPUnit_Framework_TestCase
 
         $attribute = $this->getMock(
             'Magento\Eav\Model\Entity\Attribute\AbstractAttribute',
-            array('getBackendTable', 'isStatic', 'getAttributeId', 'getName', '__wakeup'),
-            array(),
+            ['getBackendTable', 'isStatic', 'getAttributeId', 'getName', '__wakeup'],
+            [],
             '',
             false
         );
         $attribute->expects($this->any())->method('getName')->will($this->returnValue('image'));
-
         $attribute->expects($this->any())->method('getAttributeId')->will($this->returnValue($attributeId));
-
         $attribute->expects($this->any())->method('isStatic')->will($this->returnValue(false));
-
         $attribute->expects($this->any())->method('getBackendTable')->will($this->returnValue('table'));
 
-
-        $this->_model->setAttribute($attribute);
+        $this->model->setAttribute($attribute);
 
         $object = new \Magento\Framework\Object();
-        $object->setImage(array('images' => array(array('value_id' => $valueId))));
+        $object->setImage(['images' => [['value_id' => $valueId]]]);
         $object->setId(555);
 
         $this->assertEquals(
-            array(
-                'table' => array(
-                    array('value_id' => $valueId, 'attribute_id' => $attributeId, 'entity_id' => $object->getId())
-                )
-            ),
-            $this->_model->getAffectedFields($object)
+            [
+                'table' => [
+                    ['value_id' => $valueId, 'attribute_id' => $attributeId, 'entity_id' => $object->getId()]
+                ]
+            ],
+            $this->model->getAffectedFields($object)
         );
     }
+
+    public function testAfterSaveDuplicate()
+    {
+        $attributeCode = 'test_code';
+        $attributeMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeMock->expects($this->once())
+            ->method('getAttributeCode')
+            ->will($this->returnValue($attributeCode));
+
+        $this->dataObject->expects($this->once())
+            ->method('getIsDuplicate')
+            ->will($this->returnValue(true));
+        $this->dataObject->setData($attributeCode, []);
+
+        $this->model->setAttribute($attributeMock);
+        $this->assertNull($this->model->afterSave($this->dataObject));
+    }
+
+    public function testAfterSaveNoAttribute()
+    {
+        $attributeCode = 'test_code';
+        $attributeMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeMock->expects($this->once())
+            ->method('getAttributeCode')
+            ->will($this->returnValue($attributeCode));
+
+        $this->dataObject->expects($this->once())
+            ->method('getIsDuplicate')
+            ->will($this->returnValue(false));
+        $this->dataObject->setData($attributeCode, []);
+
+        $this->model->setAttribute($attributeMock);
+        $this->assertNull($this->model->afterSave($this->dataObject));
+    }
+
+    public function testAfterSaveDeleteFiles()
+    {
+        $storeId = 1;
+        $storeIds = ['store_1' => 1, 'store_2' => 2];
+        $attributeCode = 'test_code';
+        $toDelete = [1];
+        $mediaPath = 'catalog/media';
+        $filePathToRemove = $mediaPath . '/file/path';
+        $attributeValue = [
+            'images' => [
+                [
+                    'removed' => true,
+                    'value_id' => 1,
+                    'file' => 'file/path'
+                ],
+                [
+                    'removed' => false,
+                    'value_id' => 1,
+                    'file' => 'file/path2'
+                ]
+            ]
+        ];
+        $assignedImages = [
+            ['filepath' => 'path_to_image']
+        ];
+
+        $attributeMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $attributeMock->expects($this->once())
+            ->method('getAttributeCode')
+            ->will($this->returnValue($attributeCode));
+
+        $this->dataObject->expects($this->once())
+            ->method('getIsDuplicate')
+            ->will($this->returnValue(false));
+        $this->dataObject->expects($this->once())
+            ->method('isLockedAttribute')
+            ->will($this->returnValue(false));
+        $this->dataObject->setData($attributeCode, $attributeValue);
+        $this->dataObject->setId(1);
+        $this->dataObject->setStoreId($storeId);
+        $this->dataObject->setStoreIds($storeIds);
+
+        $productMock = $this->getMockBuilder('Magento\Catalog\Model\Product')
+            ->disableOriginalConstructor()
+            ->setMethods(['getAssignedImages', '__wakeup'])
+            ->getMock();
+        $productMock->expects($this->any())
+            ->method('getAssignedImages')
+            ->will($this->returnValue($assignedImages));
+
+        $this->productFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($productMock));
+
+        $this->resourceModel->expects($this->once())
+            ->method('deleteGallery')
+            ->with($toDelete);
+
+        $this->mediaConfig->expects($this->once())
+            ->method('getBaseMediaPath')
+            ->will($this->returnValue($mediaPath));
+
+        $this->mediaDirectory->expects($this->once())
+            ->method('delete')
+            ->with($filePathToRemove);
+
+        $this->model->setAttribute($attributeMock);
+        $this->assertNull($this->model->afterSave($this->dataObject));
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/CountryofmanufactureTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/CountryofmanufactureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..40bba460bfc916421042ae607729ecf6145e9eac
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Product/Attribute/Source/CountryofmanufactureTest.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Product\Attribute\Source;
+
+class CountryofmanufactureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \Magento\Store\Model\Store
+     */
+    protected $storeMock;
+
+    /**
+     * @var \Magento\Framework\App\Cache\Type\Config
+     */
+    protected $cacheConfig;
+
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManagerHelper;
+
+    protected function setUp()
+    {
+        $this->storeManagerMock = $this->getMock('\Magento\Store\Model\StoreManagerInterface');
+        $this->storeMock = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false);
+        $this->cacheConfig = $this->getMock('\Magento\Framework\App\Cache\Type\Config', array(), array(), '', false);
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+    }
+
+    /**
+     * Test for getAllOptions method
+     *
+     * @param $cachedDataSrl
+     * @param $cachedDataUnsrl
+     *
+     * @dataProvider testGetAllOptionsDataProvider
+     */
+    public function testGetAllOptions($cachedDataSrl, $cachedDataUnsrl)
+    {
+        $this->storeMock->expects($this->once())->method('getCode')->will($this->returnValue('store_code'));
+        $this->storeManagerMock->expects($this->once())->method('getStore')->will($this->returnValue($this->storeMock));
+        $this->cacheConfig->expects($this->once())
+            ->method('load')
+            ->with($this->equalTo('COUNTRYOFMANUFACTURE_SELECT_STORE_store_code'))
+            ->will($this->returnValue($cachedDataSrl));
+
+        $countryOfManufacture = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Model\Product\Attribute\Source\Countryofmanufacture',
+            [
+                'storeManager' => $this->storeManagerMock,
+                'configCacheType' => $this->cacheConfig,
+            ]
+        );
+        $this->assertEquals($cachedDataUnsrl, $countryOfManufacture->getAllOptions());
+    }
+
+    /**
+     * Data provider for testGetAllOptions
+     *
+     * @return array
+     */
+    public function testGetAllOptionsDataProvider()
+    {
+        return
+            [
+                ['cachedDataSrl' => 'a:1:{s:3:"key";s:4:"data";}', 'cachedDataUnsrl' => ['key' => 'data']]
+            ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductTest.php
index b67afb1fb3b70c8f861fe354fd131133947e6867..c66ff5fe315c2bf239e1becffbfcdae5ba5f29ee 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/ProductTest.php
@@ -53,7 +53,12 @@ class ProductTest extends \PHPUnit_Framework_TestCase
     /**
      * @var Product\Type|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $productTypeMock;
+    protected $productTypeInstanceMock;
+
+    /**
+     * @var Product\Option|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $optionInstanceMock;
 
     /**
      * @var \Magento\Framework\Pricing\PriceInfo\Base|\PHPUnit_Framework_MockObject_MockObject
@@ -62,13 +67,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        $this->categoryIndexerMock = $this->getMockForAbstractClass(
-            '\Magento\Indexer\Model\IndexerInterface',
-            array(),
-            '',
-            false,
-            false
-        );
+        $this->categoryIndexerMock = $this->getMockForAbstractClass('\Magento\Indexer\Model\IndexerInterface');
 
         $this->productFlatProcessor = $this->getMock(
             'Magento\Catalog\Model\Indexer\Product\Flat\Processor',
@@ -79,7 +78,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_priceInfoMock = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
-        $this->productTypeMock = $this->getMock('Magento\Catalog\Model\Product\Type', [], [], '', false);
+        $this->productTypeInstanceMock = $this->getMock('Magento\Catalog\Model\Product\Type', [], [], '', false);
         $this->productPriceProcessor = $this->getMock(
             'Magento\Catalog\Model\Indexer\Product\Price\Processor',
             array(),
@@ -93,16 +92,16 @@ class ProductTest extends \PHPUnit_Framework_TestCase
             ->method('getAreaCode')
             ->will($this->returnValue(\Magento\Backend\App\Area\FrontNameResolver::AREA_CODE));
 
-        $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface', array(), array(), '', false);
+        $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface');
         $actionValidatorMock = $this->getMock(
-            '\Magento\Framework\Model\ActionValidator\RemoveAction', 
-            [], 
-            [], 
-            '', 
+            '\Magento\Framework\Model\ActionValidator\RemoveAction',
+            [],
+            [],
+            '',
             false
         );
         $actionValidatorMock->expects($this->any())->method('isAllowed')->will($this->returnValue(true));
-        $cacheInterfaceMock = $this->getMock('Magento\Framework\App\CacheInterface', array(), array(), '', false);
+        $cacheInterfaceMock = $this->getMock('Magento\Framework\App\CacheInterface');
 
         $contextMock = $this->getMock(
             '\Magento\Framework\Model\Context',
@@ -117,15 +116,20 @@ class ProductTest extends \PHPUnit_Framework_TestCase
             ->method('getActionValidator')
             ->will($this->returnValue($actionValidatorMock));
 
+        $this->optionInstanceMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Option')
+            ->setMethods(['setProduct', 'saveOptions', '__wakeup', '__sleep'])
+            ->disableOriginalConstructor()->getMock();
+
         $this->objectManagerHelper = new ObjectManagerHelper($this);
         $this->model = $this->objectManagerHelper->getObject(
             'Magento\Catalog\Model\Product',
             [
                 'context' => $contextMock,
-                'catalogProductType' => $this->productTypeMock,
+                'catalogProductType' => $this->productTypeInstanceMock,
                 'categoryIndexer' => $this->categoryIndexerMock,
                 'productFlatIndexerProcessor' => $this->productFlatProcessor,
                 'productPriceIndexerProcessor' => $this->productPriceProcessor,
+                'catalogProductOption' => $this->optionInstanceMock,
                 'data' => array('id' => 1)
             ]
         );
@@ -202,7 +206,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetPriceInfo()
     {
-        $this->productTypeMock->expects($this->once())
+        $this->productTypeInstanceMock->expects($this->once())
             ->method('getPriceInfo')
             ->with($this->equalTo($this->model))
             ->will($this->returnValue($this->_priceInfoMock));
@@ -214,7 +218,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
      */
     public function testSetQty()
     {
-        $this->productTypeMock->expects($this->once())
+        $this->productTypeInstanceMock->expects($this->once())
             ->method('getPriceInfo')
             ->with($this->equalTo($this->model))
             ->will($this->returnValue($this->_priceInfoMock));
@@ -227,7 +231,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
      */
     public function testReloadPriceInfo()
     {
-        $this->productTypeMock->expects($this->exactly(2))
+        $this->productTypeInstanceMock->expects($this->exactly(2))
             ->method('getPriceInfo')
             ->with($this->equalTo($this->model))
             ->will($this->returnValue($this->_priceInfoMock));
@@ -243,4 +247,44 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->model->setQty(1);
         $this->assertEquals(1, $this->model->getQty());
     }
+
+    /**
+     *  Test for `save` method
+     */
+    public function testSave()
+    {
+        $this->model->setIsDuplicate(false);
+        $this->configureSaveTest();
+        $this->optionInstanceMock->expects($this->any())->method('setProduct')->will($this->returnSelf());
+        $this->optionInstanceMock->expects($this->once())->method('saveOptions')->will($this->returnSelf());
+        $this->model->save();
+    }
+
+    /**
+     *  Test for `save` method for duplicated product
+     */
+    public function testSaveAndDuplicate()
+    {
+        $this->model->setIsDuplicate(true);
+        $this->configureSaveTest();
+        $this->model->save();
+    }
+
+    /**
+     * Configure environment for `testSave` and `testSaveAndDuplicate` methods
+     * @return array
+     */
+    protected function configureSaveTest()
+    {
+        $productTypeMock = $this->getMockBuilder('Magento\Catalog\Model\Product\Type\Simple')
+            ->disableOriginalConstructor()->setMethods(['beforeSave', 'save'])->getMock();
+        $productTypeMock->expects($this->once())->method('beforeSave')->will($this->returnSelf());
+        $productTypeMock->expects($this->once())->method('save')->will($this->returnSelf());
+
+        $this->productTypeInstanceMock->expects($this->once())->method('factory')->with($this->model)
+            ->will($this->returnValue($productTypeMock));
+
+        $this->model->getResource()->expects($this->any())->method('addCommitCallback')->will($this->returnSelf());
+        $this->model->getResource()->expects($this->any())->method('commit')->will($this->returnSelf());
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc4c977b81dc94b28c5e80b358895a0c79b0d937
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Model\Resource\Product\Indexer\Eav;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class SourceTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source */
+    protected $source;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Framework\App\Resource|\PHPUnit_Framework_MockObject_MockObject */
+    protected $resource;
+
+    /** @var \Magento\Eav\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
+    protected $config;
+
+    /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $managerInterface;
+
+    /** @var \Magento\Catalog\Model\Resource\Helper|\PHPUnit_Framework_MockObject_MockObject */
+    protected $helper;
+
+    protected function setUp()
+    {
+        $this->resource = $this->getMock(
+            'Magento\Framework\App\Resource',
+            ['getConnection', 'getTableName'],
+            [],
+            '',
+            false
+        );
+        $this->config = $this->getMock('Magento\Eav\Model\Config', [], [], '', false);
+        $this->managerInterface = $this->getMock('Magento\Framework\Event\ManagerInterface');
+        $this->helper = $this->getMock('Magento\Catalog\Model\Resource\Helper', [], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->source = $this->objectManagerHelper->getObject(
+            'Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source',
+            [
+                'resource' => $this->resource,
+                'eavConfig' => $this->config,
+                'eventManager' => $this->managerInterface,
+                'resourceHelper' => $this->helper
+            ]
+        );
+    }
+
+    /**
+     * Test `reindexEntity` method
+     */
+    public function testReindexEntities()
+    {
+        $query = $this->getMockBuilder('PDO_Statement')->setMethods(['fetch'])->disableOriginalConstructor()->getMock();
+        $query->expects($this->any())->method('fetch')->will($this->returnValue([]));
+
+        $select = $this->getMockBuilder('\Magento\Framework\DB\Select')->setMethods([
+                'select', 'from', 'where', 'join', 'joinLeft', 'joinInner',
+                'assemble', 'columns', 'insertFromSelect', 'query', 'deleteFromSelect'
+            ])->disableOriginalConstructor()->getMock();
+        $select->expects($this->any())->method('from')->withAnyParameters()->will($this->returnSelf());
+        $select->expects($this->any())->method('where')->will($this->returnSelf());
+        $select->expects($this->any())->method('join')->will($this->returnSelf());
+        $select->expects($this->any())->method('query')->will($this->returnValue($query));
+        $select->expects($this->any())->method('columns')->will($this->returnSelf());
+        $select->expects($this->any())->method('joinLeft')->will($this->returnSelf());
+        $select->expects($this->any())->method('insertFromSelect')->will($this->returnSelf());
+        $select->expects($this->any())->method('deleteFromSelect')->with('catalog_product_index_eav_tmp')
+            ->will($this->returnValue($query));
+        $select->expects($this->once())->method('joinInner')
+            ->with(
+                array('d2' => 'catalog_product_entity_int'),
+                'd.entity_id = d2.entity_id AND d2.attribute_id = 96 AND d2.value = 1 AND d.store_id = 0'
+            )->will($this->returnSelf());
+
+        $adapter = $this->getMockBuilder('Magento\Framework\DB\Adapter\Pdo\Mysql')
+            ->setMethods([
+                'select', 'delete', 'beginTransaction', 'getTransactionLevel', 'fetchCol', 'query', 'quoteInto',
+                'describeTable', 'commit'
+            ])->disableOriginalConstructor()->getMock();
+        $adapter->expects($this->any())->method('select')->will($this->returnValue($select));
+        $adapter->expects($this->any())->method('getTransactionLevel')->will($this->returnValue(1));
+        $adapter->expects($this->any())->method('fetchCol')->will($this->returnValue([1]));
+        $adapter->expects($this->any())->method('query')->will($this->returnValue($query));
+        $adapter->expects($this->any())->method('describeTable')->will($this->returnValue([]));
+        $adapter->expects($this->any())->method('commit')->will($this->returnValue(null));
+
+
+        $this->resource->expects($this->any())->method('getConnection')->with('core_write')
+            ->will($this->returnValue($adapter));
+        $this->resource->expects($this->at(4))->method('getTableName')->with('catalog_product_index_eav_tmp')
+            ->will($this->returnArgument(0));
+        $this->resource->expects($this->at(8))->method('getTableName')->with('catalog_product_entity_int')
+            ->will($this->returnArgument(0));
+
+
+        $attribute = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute')->disableOriginalConstructor()
+            ->setMethods(['getId', '__sleep', '__wakeup', 'getBackend', 'getTable', 'isScopeGlobal'])->getMock();
+        $attribute->expects($this->once())->method('getId')->will($this->returnValue(96));
+        $attribute->expects($this->any())->method('getBackend')->will($this->returnSelf());
+        $attribute->expects($this->any())->method('getTable')->will($this->returnValue('some_table'));
+        $attribute->expects($this->any())->method('isScopeGlobal')->will($this->returnValue(true));
+        $this->config->expects($this->any())->method('getAttribute')->will($this->returnValue($attribute));
+
+        $this->source->reindexEntities([1]);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
index b0f87ecaccd1ac98978f5e29729ccb8906757bbe..8ea497367bef5efc74297dd9148374df32df5ef0 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
@@ -34,7 +34,7 @@ class BasePriceTest extends \PHPUnit_Framework_TestCase
     protected $basePrice;
 
     /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfo\Base |\PHPUnit_Framework_MockObject_MockObject
      */
     protected $priceInfoMock;
 
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/ConfiguredPriceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/ConfiguredPriceTest.php
index 8ad8599043886e8d502fd5bedb13c9d2099cc2a5..3be40026abfe28fd5580ed2b31b7069883b74aba 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/ConfiguredPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/ConfiguredPriceTest.php
@@ -67,7 +67,7 @@ class ConfiguredPriceTest extends \PHPUnit_Framework_TestCase
         $basePrice = $this->getMock('Magento\Framework\Pricing\Price\PriceInterface', [], [], '', false);
         $basePrice->expects($this->any())->method('getValue')->will($this->returnValue($this->basePriceValue));
 
-        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface', [], [], '', false);
+        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
         $this->priceInfo->expects($this->any())->method('getPrice')->will($this->returnValue($basePrice));
 
         $this->product = $this->getMockBuilder('Magento\Catalog\Model\Product')
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/GroupPriceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/GroupPriceTest.php
index cc3ac4c83a844c821af9ad33168fb21c2b755701..36d889fbdeb1fdd4df8243275570538aec43fdce 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/GroupPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/GroupPriceTest.php
@@ -128,7 +128,7 @@ class GroupPriceTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->prepareSaleableItemResource()));
 
         $priceInfo = $this->getMockBuilder(
-            'Magento\Framework\Pricing\PriceInfoInterface'
+            'Magento\Framework\Pricing\PriceInfo\Base'
         )->disableOriginalConstructor()->getMockForAbstractClass();
 
         $priceInfo->expects($this->any())
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/TierPriceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/TierPriceTest.php
index d578dd0a4498ecbde8e5c778573ed15b39e8ef44..6dc86b8bd4a5399165bf802ca7a85a4c7cb20f0e 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/TierPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/TierPriceTest.php
@@ -73,7 +73,7 @@ class TierPriceTest extends \PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface', [], [], '', false);
+        $this->priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
 
         $this->product = $this->getMock(
             'Magento\Catalog\Model\Product',
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadServiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d961bb8f274465024d73bd975b6f0271430e2230
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeGroup/ReadServiceTest.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\Catalog\Service\V1\Product\AttributeGroup;
+
+class ReadServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Service\V1\Product\AttributeGroup\ReadService
+     */
+    protected $service;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $groupListFactory;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->groupListFactory = $this->getMock(
+            '\Magento\Eav\Model\Resource\Entity\Attribute\Group\CollectionFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+        $groupBuilder = $helper->getObject('\Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder');
+        $this->service = new ReadService($this->groupListFactory, $groupBuilder);
+    }
+
+    public function testListGroups()
+    {
+        $groupList = $this->getMock(
+            '\Magento\Eav\Model\Resource\Entity\Attribute\Group\Collection',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $this->groupListFactory->expects($this->once())->method('create')->will($this->returnValue($groupList));
+        $item1 = new \Magento\Framework\Object(array('id' => 1, 'attribute_group_name' => 'First'));
+        $item2 = new \Magento\Framework\Object(array('id' => 2, 'attribute_group_name' => 'Second'));
+        $groupList->expects($this->once())->method('getItems')->will($this->returnValue(array($item1, $item2)));
+        $result = $this->service->getList(1);
+        $this->assertCount(2, $result);
+        $this->assertInstanceOf('\Magento\Catalog\Service\V1\Data\Eav\AttributeGroup', $result[0]);
+        $this->assertInstanceOf('\Magento\Catalog\Service\V1\Data\Eav\AttributeGroup', $result[1]);
+        $this->assertEquals('First', $result[0]->getName());
+        $this->assertEquals('Second', $result[1]->getName());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteServiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d8c7e507472e60b4f45fa6830acd2a54e12c2fd
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeGroup/WriteServiceTest.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1\Product\AttributeGroup;
+
+use Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder;
+
+class WriteServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $groupFactory;
+
+    /**
+     * @var WriteService
+     */
+    protected $service;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $group;
+
+    /**
+     * @var \Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder
+     */
+    protected $groupBuilder;
+
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectHelper;
+
+    protected function setUp()
+    {
+        $this->objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->groupFactory = $this->getMock(
+            '\Magento\Catalog\Model\Product\Attribute\GroupFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+        $this->group = $this->getMock(
+            '\Magento\Catalog\Model\Product\Attribute\Group',
+            array(
+                'getId', 'setId', 'setAttributeGroupName', '__wakeUp', 'save', 'load', 'delete', 'hasSystemAttributes'
+            ),
+            array(),
+            '',
+            false
+        );
+        $this->groupFactory->expects($this->any())->method('create')->will($this->returnValue($this->group));
+        $this->groupBuilder = $this->objectHelper->getObject(
+            'Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder'
+        );
+        $this->service = new WriteService($this->groupFactory, $this->groupBuilder);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function testCreateThrowsException()
+    {
+        $this->group->expects($this->once())->method('save')->will($this->throwException(new \Exception()));
+        $groupDataBuilder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder');
+        $groupDataBuilder->setName('testName');
+        $this->service->create(1, $groupDataBuilder->create());
+    }
+
+    public function testCreateCreatesNewAttributeGroup()
+    {
+        $this->group->expects($this->once())->method('setAttributeGroupName')->with('testName');
+        $this->group->expects($this->once())->method('save');
+        $groupDataBuilder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder');
+        $groupDataBuilder->setName('testName');
+        $this->service->create(1, $groupDataBuilder->create());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function testUpdateThrowsExceptionIfNoSuchEntityExists()
+    {
+        $groupDataBuilder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder');
+        $groupDataBuilder->setName('testName');
+        $this->service->update(1, $groupDataBuilder->create());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     */
+    public function testUpdateThrowsExceptionIfEntityWasNotSaved()
+    {
+        $this->group->expects($this->once())->method('save')->will($this->throwException(new \Exception()));
+        $this->group->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $groupDataBuilder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder');
+        $groupDataBuilder->setName('testName');
+        $this->service->update(1, $groupDataBuilder->create());
+    }
+
+    public function testUpdateSavesEntity()
+    {
+        $this->group->expects($this->once())->method('save');
+        $this->group->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $this->group->expects($this->once())->method('setId')->with(null);
+        $this->group->expects($this->once())->method('setAttributeGroupName')->with('testName');
+        $groupDataBuilder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder');
+        $groupDataBuilder->setName('testName');
+        $this->service->update(1, $groupDataBuilder->create());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function testDeleteThrowsExceptionIfNoEntityExists()
+    {
+        $this->group->expects($this->once())->method('getId')->will($this->returnValue(null));
+        $groupDataBuilder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeGroupBuilder');
+        $groupDataBuilder->setName('testName');
+        $this->service->delete(1, $groupDataBuilder->create());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\StateException
+     */
+    public function testDeleteThrowsStateExceptionIfTryToDeleteGroupWithSystemAttributes()
+    {
+        $this->group->expects($this->once())->method('hasSystemAttributes')->will($this->returnValue(true));
+        $this->group->expects($this->never())->method('delete');
+        $this->service->delete(1);
+    }
+
+    public function testDeleteRemovesEntity()
+    {
+        $this->group->expects($this->once())->method('getId')->will($this->returnValue(1));
+        $this->group->expects($this->once())->method('delete');
+        $this->service->delete(1);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeServiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3e9b543bbdadf5799b1f0e4bd50d422d719bfb2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/AttributeServiceTest.php
@@ -0,0 +1,379 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1\Product\AttributeSet;
+
+class AttributeServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var AttributeService
+     */
+    private $service;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attributeMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attributeGroupMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attributeSetMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entityTypeConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attrResourceMock;
+
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectHelper;
+
+    /**
+     * @SuppressWarnings(PHPMD.LongVariable)
+     */
+    protected function setUp()
+    {
+        $this->objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $attributeFactoryMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\AttributeFactory', array('create'), array(), '', false
+        );
+        $setFactoryMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\SetFactory', array('create'), array(), '', false
+        );
+        $groupFactoryMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\GroupFactory', array('create'), array(), '', false
+        );
+        $entityTypeFactoryMock = $this->getMock(
+            '\Magento\Eav\Model\ConfigFactory', array('create'), array(), '', false
+        );
+
+        $this->attributeMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute',
+            array(
+                'getId', 'setId', 'setEntityTypeId', 'setAttributeSetId', 'load',
+                'setAttributeGroupId', 'setSortOrder', 'loadEntityAttributeIdBySet', '__sleep', '__wakeup'
+            ),
+            array(), '', false
+        );
+        $this->attributeGroupMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Group', array(), array(), '', false
+        );
+        $this->attributeSetMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Set', array(), array(), '', false
+        );
+        $this->entityTypeConfigMock = $this->getMock(
+            '\Magento\Eav\Model\Config', array('getEntityType', 'getEntityTypeCode', 'getId', '__sleep', '__wakeup'),
+            array(), '', false
+        );
+        $this->attrResourceMock = $this->getMock(
+            '\Magento\Eav\Model\Resource\Entity\Attribute', array(), array(), '', false
+        );
+
+        $attributeFactoryMock->expects($this->any())->method('create')->will($this->returnValue($this->attributeMock));
+        $setFactoryMock->expects($this->any())->method('create')->will($this->returnValue($this->attributeSetMock));
+        $groupFactoryMock->expects($this->any())->method('create')->will($this->returnValue($this->attributeGroupMock));
+        $entityTypeFactoryMock->expects($this->any())
+            ->method('create')->will($this->returnValue($this->entityTypeConfigMock));
+
+        $this->service = new AttributeService(
+            $attributeFactoryMock,
+            $groupFactoryMock,
+            $setFactoryMock,
+            $entityTypeFactoryMock,
+            $this->attrResourceMock
+        );
+    }
+
+    /**
+     * @covers \Magento\Catalog\Service\V1\Product\AttributeSet\AttributeService::__construct
+     * @covers \Magento\Catalog\Service\V1\Product\AttributeSet\AttributeService::addAttribute
+     */
+    public function testAddAttribute()
+    {
+        $data = [
+            'attribute_id'       => 1,
+            'attribute_group_id' => 1,
+            'sort_order'         => 1
+        ];
+        $builder = $this->objectHelper->getObject('\Magento\Catalog\Service\V1\Data\Eav\AttributeSet\AttributeBuilder');
+        $attributeDataObject = $builder->populateWithArray($data)->create();
+
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $objectMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $objectMock->expects($this->any())->method('getData')->will($this->returnValue(1));
+
+        $this->attributeSetMock->expects($this->once())->method('load')->will($this->returnValue($objectMock));
+        $this->attributeGroupMock->expects($this->once())->method('load')->will($this->returnValue($objectMock));
+        $this->attributeMock->expects($this->once())->method('load')->will($this->returnValue($objectMock));
+
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())
+            ->method('getEntityTypeCode')->will($this->returnValue(\Magento\Catalog\Model\Product::ENTITY));
+        $this->entityTypeConfigMock->expects($this->once())->method('getId')->will($this->returnValue(4));
+
+        $this->attributeMock->expects($this->once())->method('setId')->with(1);
+        $this->attributeMock->expects($this->once())->method('setEntityTypeId')->with(4);
+        $this->attributeMock->expects($this->once())->method('setAttributeSetId')->with(1);
+        $this->attributeMock->expects($this->once())->method('setAttributeGroupId')->with(1);
+        $this->attributeMock->expects($this->once())->method('setSortOrder')->with(1);
+        $this->attributeMock->expects($this->once())
+            ->method('loadEntityAttributeIdBySet')->will($this->returnValue($objectMock));
+        $this->attrResourceMock->expects($this->once())->method('saveInSetIncluding')->with($this->attributeMock);
+
+        $this->service->addAttribute(1, $attributeDataObject);
+    }
+
+    /**
+     * @covers \Magento\Catalog\Service\V1\Product\AttributeSet\AttributeService::addAttribute
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Attribute set does not exist
+     */
+    public function testAddAttributeWithWrongAttributeSet()
+    {
+        $builder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeSet\AttributeBuilder');
+        $attributeDataObject = $builder->populateWithArray([])->create();
+
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $this->attributeSetMock->expects($this->once())->method('load')->will($this->returnValue($objectMock));
+        $this->service->addAttribute(1, $attributeDataObject);
+    }
+
+    /**
+     * @covers \Magento\Catalog\Service\V1\Product\AttributeSet\AttributeService::addAttribute
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Wrong attribute set id provided
+     */
+    public function testAddAttributeWithAttributeSetOfOtherEntityType()
+    {
+        $builder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeSet\AttributeBuilder');
+        $attributeDataObject = $builder->populateWithArray(['attribute_group'])->create();
+
+        $attributeSetMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $attributeSetMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->attributeSetMock->expects($this->once())->method('load')->will($this->returnValue($attributeSetMock));
+
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityTypeCode')->will($this->returnValue('0'));
+
+        $this->service->addAttribute(1, $attributeDataObject);
+    }
+
+    /**
+     * @covers \Magento\Catalog\Service\V1\Product\AttributeSet\AttributeService::addAttribute
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Attribute group does not exist
+     */
+    public function testAddAttributeWithWrongAttributeGroup()
+    {
+        $builder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeSet\AttributeBuilder');
+        $attributeDataObject = $builder->populateWithArray(['attribute_group'])->create();
+
+        $attributeSetMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $attributeSetMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->attributeSetMock->expects($this->once())->method('load')->will($this->returnValue($attributeSetMock));
+
+        $entityCode = \Magento\Catalog\Model\Product::ENTITY;
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())
+            ->method('getEntityTypeCode')->will($this->returnValue($entityCode));
+
+        $attributeGroupMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $this->attributeGroupMock->expects($this->once())->method('load')
+            ->will($this->returnValue($attributeGroupMock));
+
+        $this->service->addAttribute(1, $attributeDataObject);
+    }
+
+    /**
+     * @covers \Magento\Catalog\Service\V1\Product\AttributeSet\AttributeService::addAttribute
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Attribute does not exist
+     */
+    public function testAddAttributeWithWrongAttribute()
+    {
+        $builder = $this->objectHelper->getObject('Magento\Catalog\Service\V1\Data\Eav\AttributeSet\AttributeBuilder');
+        $attributeDataObject = $builder->populateWithArray(['attribute_group'])->create();
+
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $objectMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->attributeSetMock->expects($this->once())->method('load')->will($this->returnValue($objectMock));
+        $this->attributeGroupMock->expects($this->once())->method('load') ->will($this->returnValue($objectMock));
+
+        $entityCode = \Magento\Catalog\Model\Product::ENTITY;
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())
+            ->method('getEntityTypeCode')->will($this->returnValue($entityCode));
+
+        $attributeMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $this->attributeMock->expects($this->once())->method('load')->will($this->returnValue($attributeMock));
+
+        $this->service->addAttribute(1, $attributeDataObject);
+    }
+
+    public function testSuccessfullyDeleteAttribute()
+    {
+        $entityCode = \Magento\Catalog\Model\Product::ENTITY;
+        $methods = array('__wakeup', 'setAttributeSetId',
+            'loadEntityAttributeIdBySet', 'getEntityAttributeId', 'deleteEntity', 'getId', 'getIsUserDefined');
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())
+            ->method('getEntityTypeCode')->will($this->returnValue($entityCode));
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $objectMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->attributeSetMock->expects($this->once())->method('load')->with(1)->will($this->returnValue($objectMock));
+        $attributeMock =
+            $this->getMock('Magento\Eav\Model\Entity\Attribute\AbstractAttribute', $methods, array(), '', false);
+        $this->attributeMock
+            ->expects($this->once())->method('load')->with(10)->will($this->returnValue($attributeMock));
+        $attributeMock->expects($this->any())->method('getId')->will($this->returnValue(2));
+        $attributeMock->expects($this->once())->method('setAttributeSetId')->with(1)->will($this->returnSelf());
+        $attributeMock->expects($this->once())->method('loadEntityAttributeIdBySet')->will($this->returnSelf());
+        $attributeMock->expects($this->once())->method('getEntityAttributeId')->will($this->returnValue(10));
+        $attributeMock->expects($this->once())->method('getIsUserDefined')->will($this->returnValue(true));
+        $attributeMock->expects($this->once())->method('deleteEntity');
+        $this->assertEquals(true, $this->service->deleteAttribute(1, 10));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage No such entity with attributeSetId = 1
+     */
+    public function testDeleteAttributeFromNonExistingAttributeSet()
+    {
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $objectMock->expects($this->any())->method('getId')->will($this->returnValue(false));
+        $this->attributeSetMock->expects($this->once())->method('load')->will($this->returnValue($objectMock));
+        $this->attributeMock->expects($this->never())->method('load');
+
+        $this->service->deleteAttribute(1, 10);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage No such entity with attributeId = 10
+     */
+    public function testDeleteNonExistingAttribute()
+    {
+        $entityCode = \Magento\Catalog\Model\Product::ENTITY;
+        $methods = array('__wakeup', 'setAttributeSetId',
+            'loadEntityAttributeIdBySet', 'getEntityAttributeId', 'deleteEntity', 'getId');
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())
+            ->method('getEntityTypeCode')->will($this->returnValue($entityCode));
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $objectMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->attributeSetMock->expects($this->once())->method('load')->with(1)->will($this->returnValue($objectMock));
+        $attributeMock =
+            $this->getMock('Magento\Eav\Model\Entity\Attribute\AbstractAttribute', $methods, array(), '', false);
+        $this->attributeMock->expects($this->once())->method('load')->with(10)
+            ->will($this->returnValue($attributeMock));
+        $attributeMock->expects($this->any())->method('getId')->will($this->returnValue(false));
+        $attributeMock->expects($this->never())->method('setAttributeSetId');
+        $this->service->deleteAttribute(1, 10);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Requested attribute is not in requested attribute set.
+     */
+    public function testDeleteAttributeNotInAttributeSet()
+    {
+        $entityCode = \Magento\Catalog\Model\Product::ENTITY;
+        $methods = array('__wakeup', 'setAttributeSetId',
+            'loadEntityAttributeIdBySet', 'getEntityAttributeId', 'deleteEntity', 'getId');
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())
+            ->method('getEntityTypeCode')->will($this->returnValue($entityCode));
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $objectMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->attributeSetMock->expects($this->once())->method('load')->with(1)->will($this->returnValue($objectMock));
+        $attributeMock =
+            $this->getMock('Magento\Eav\Model\Entity\Attribute\AbstractAttribute', $methods, array(), '', false);
+        $this->attributeMock->expects($this->once())->method('load')->with(10)
+            ->will($this->returnValue($attributeMock));
+        $attributeMock->expects($this->any())->method('getId')->will($this->returnValue(2));
+        $attributeMock->expects($this->once())->method('setAttributeSetId')->with(1)->will($this->returnSelf());
+        $attributeMock->expects($this->once())->method('loadEntityAttributeIdBySet')->will($this->returnSelf());
+        $attributeMock->expects($this->once())->method('getEntityAttributeId')->will($this->returnValue(false));
+        $attributeMock->expects($this->never())->method('deleteEntity');
+        $this->assertEquals(true, $this->service->deleteAttribute(1, 10));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage Attribute with wrong attribute type is provided
+     */
+    public function testDeleteAttributeHasNotCorrespondingType()
+    {
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())
+            ->method('getEntityTypeCode')->will($this->returnValue('some_type'));
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $objectMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->attributeSetMock->expects($this->once())->method('load')->will($this->returnValue($objectMock));
+        $this->attributeMock->expects($this->never())->method('load');
+        $this->assertEquals(true, $this->service->deleteAttribute(1, 10));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\StateException
+     * @expectedExceptionMessage System attribute can not be deleted
+     */
+    public function testDeleteSystemAttribute()
+    {
+        $entityCode = \Magento\Catalog\Model\Product::ENTITY;
+        $methods = array('__wakeup', 'setAttributeSetId',
+            'loadEntityAttributeIdBySet', 'getEntityAttributeId', 'deleteEntity', 'getId', 'getIsUserDefined');
+        $this->entityTypeConfigMock->expects($this->once())->method('getEntityType')->will($this->returnSelf());
+        $this->entityTypeConfigMock->expects($this->once())
+            ->method('getEntityTypeCode')->will($this->returnValue($entityCode));
+        $objectMock = $this->getMock('\Magento\Framework\Object', array(), array(), '', false);
+        $objectMock->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $this->attributeSetMock->expects($this->once())->method('load')->with(1)->will($this->returnValue($objectMock));
+        $attributeMock =
+            $this->getMock('Magento\Eav\Model\Entity\Attribute\AbstractAttribute', $methods, array(), '', false);
+        $this->attributeMock
+            ->expects($this->once())->method('load')->with(10)->will($this->returnValue($attributeMock));
+        $attributeMock->expects($this->any())->method('getId')->will($this->returnValue(2));
+        $attributeMock->expects($this->once())->method('setAttributeSetId')->with(1)->will($this->returnSelf());
+        $attributeMock->expects($this->once())->method('loadEntityAttributeIdBySet')->will($this->returnSelf());
+        $attributeMock->expects($this->once())->method('getEntityAttributeId')->will($this->returnValue(10));
+        $attributeMock->expects($this->once())->method('getIsUserDefined')->will($this->returnValue(false));
+        $attributeMock->expects($this->never())->method('deleteEntity');
+        $this->service->deleteAttribute(1, 10);
+    }
+
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/ReadServiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1c32d7fbea80b793244e91619d430f1b31dbba5
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/ReadServiceTest.php
@@ -0,0 +1,340 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1\Product\AttributeSet;
+
+class ReadServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Service\V1\Product\AttributeSet\ReadService
+     */
+    protected $service;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $setFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eavConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entityTypeMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $builderMock;
+
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attrCollectionMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attributeBuilderMock;
+
+    protected function setUp()
+    {
+        $this->setFactoryMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\SetFactory',
+            array('create'), array(), '', false);
+        $this->collectionFactoryMock = $this->getMock(
+            '\Magento\Eav\Model\Resource\Entity\Attribute\Set\CollectionFactory',
+            array('create'), array(), '', false
+        );
+
+        $this->eavConfigMock = $this->getMock('\Magento\Eav\Model\Config', array(), array(), '', false);
+        $this->entityTypeMock = $this->getMock('\Magento\Eav\Model\Entity\Type', array(), array(), '', false);
+        $this->eavConfigMock->expects($this->any())
+            ->method('getEntityType')
+            ->with(\Magento\Catalog\Model\Product::ENTITY)
+            ->will($this->returnValue($this->entityTypeMock));
+
+        $this->builderMock = $this->getMock('\Magento\Catalog\Service\V1\Data\Eav\AttributeSetBuilder',
+            array('create', 'setId', 'setName', 'setSortOrder'), array(), '', false);
+
+        $this->attrCollectionMock = $this->getMock('\Magento\Eav\Model\Resource\Entity\Attribute\Collection',
+            array(), array(), '', false);
+        $this->attributeBuilderMock = $this->getMock('\Magento\Catalog\Service\V1\Data\Eav\AttributeBuilder',
+            array(), array(), '', false);
+
+        $this->service = new ReadService(
+            $this->setFactoryMock,
+            $this->collectionFactoryMock,
+            $this->eavConfigMock,
+            $this->builderMock,
+            $this->attrCollectionMock,
+            $this->attributeBuilderMock
+        );
+    }
+
+    public function testGetList()
+    {
+        $attributeSetData = array('attribute_set_id' => 4, 'attribute_set_name' => 'Default', 'sort_order' => 2);
+
+        $collectionMock = $this->getMock(
+            '\Magento\Eav\Model\Resource\Entity\Attribute\Set\Collection', array(), array(), '', false
+        );
+
+        $productEntityId = 4;
+        $this->entityTypeMock->expects($this->once())->method('getId')->will($this->returnValue($productEntityId));
+
+        $this->collectionFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($collectionMock));
+
+        $collectionMock->expects($this->once())->method('setEntityTypeFilter')
+            ->with($productEntityId)
+            ->will($this->returnSelf());
+
+        $collectionMock->expects($this->once())->method('load')->will($this->returnSelf());
+
+        $attributeSets = $resultSets = array();
+
+        //prepare getter checks
+        $setMock = $this->getMock('\Magento\Eav\Model\Resource\Entity\Attribute\Set',
+            array('getId', 'getAttributeSetName', 'getSortOrder', '__wakeup'), array(), '', false);
+        $setMock->expects($this->any())->method('getId')
+            ->will($this->returnValue($attributeSetData['attribute_set_id']));
+        $setMock->expects($this->any())->method('getAttributeSetName')
+            ->will($this->returnValue($attributeSetData['attribute_set_name']));
+        $setMock->expects($this->any())->method('getSortOrder')
+            ->will($this->returnValue($attributeSetData['sort_order']));
+        $attributeSets[] = $setMock;
+
+        //prepare setter checks
+        $this->builderMock->expects($this->once())->method('setId')
+            ->with($attributeSetData['attribute_set_id']);
+        $this->builderMock->expects($this->once())->method('setName')
+            ->with($attributeSetData['attribute_set_name']);
+        $this->builderMock->expects($this->once())->method('setSortOrder')
+            ->with($attributeSetData['sort_order']);
+
+        $dataObjectMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Data\Eav\AttributeSet', array(), array(), '', false
+        );
+        $this->builderMock->expects($this->once())->method('create')->will($this->returnValue($dataObjectMock));
+        $resultSets[] = $dataObjectMock;
+
+        $collectionMock->expects($this->any())->method('getIterator')
+            ->will($this->returnValue(new \ArrayIterator($attributeSets)));
+
+        $this->assertEquals($resultSets, $this->service->getList());
+    }
+
+    public function testGetInfoReturnsAttributeSetIfIdIsValid()
+    {
+        $attributeSetData = array(
+            'id' => 4,
+            'name' => 'Default',
+            'sort_order' => 2,
+        );
+        $attributeSetMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Set',
+            array('load', 'getId', 'getAttributeSetName', 'getSortOrder', '__wakeup', 'getEntityTypeId'),
+            array(),
+            '',
+            false
+        );
+        $entityTypeId = 4;
+        $this->entityTypeMock->expects($this->once())->method('getId')->will($this->returnValue($entityTypeId));
+
+        $this->setFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($attributeSetMock));
+        $attributeSetMock->expects($this->any())->method('getId')
+            ->will($this->returnValue($attributeSetData['id']));
+        $attributeSetMock->expects($this->any())->method('getAttributeSetName')
+            ->will($this->returnValue($attributeSetData['name']));
+        $attributeSetMock->expects($this->any())->method('getSortOrder')
+            ->will($this->returnValue($attributeSetData['sort_order']));
+        $attributeSetMock->expects($this->any())
+            ->method('getEntityTypeId')
+            ->will($this->returnValue($entityTypeId));
+        $attributeSetMock->expects($this->once())
+            ->method('load')
+            ->with($attributeSetData['id'])
+            ->will($this->returnSelf());
+        $this->builderMock->expects($this->once())
+            ->method('setId')
+            ->with($attributeSetData['id'])
+            ->will($this->returnSelf());
+        $this->builderMock->expects($this->once())
+            ->method('setName')
+            ->with($attributeSetData['name'])
+            ->will($this->returnSelf());
+        $this->builderMock->expects($this->once())
+            ->method('setSortOrder')
+            ->with($attributeSetData['sort_order'])
+            ->will($this->returnSelf());
+        $dataObjectMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $this->builderMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($dataObjectMock));
+        $this->assertEquals($dataObjectMock, $this->service->getInfo($attributeSetData['id']));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage No such entity with attributeSetId = 1
+     */
+    public function testGetInfoThrowsExceptionIfIdIsNotValid()
+    {
+        $attributeSetData = array(
+            'id' => 1,
+        );
+        $attributeSetMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Set',
+            array('load', 'getId', 'getName', 'getSortOrder', '__wakeup'),
+            array(),
+            '',
+            false
+        );
+        $this->setFactoryMock->expects($this->once())->method('create')->will($this->returnValue($attributeSetMock));
+        $attributeSetMock->expects($this->once())
+            ->method('load')
+            ->with($attributeSetData['id'])
+            ->will($this->returnSelf());
+        $this->builderMock->expects($this->never())->method('create');
+        $this->service->getInfo($attributeSetData['id']);
+    }
+
+    public function testGetAttributeListIfIdIsValid()
+    {
+        $attributeSetId = 4;
+        $attributeSetMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Set',
+            array('load', 'getId', 'getAttributeSetName', 'getSortOrder', '__wakeup', 'getEntityTypeId'),
+            array(),
+            '',
+            false
+        );
+        $entityTypeId = 4;
+        $this->entityTypeMock->expects($this->once())->method('getId')->will($this->returnValue($entityTypeId));
+
+        $this->setFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($attributeSetMock));
+        $attributeSetMock->expects($this->any())->method('getId')
+            ->will($this->returnValue($attributeSetId));
+        $attributeSetMock->expects($this->any())
+            ->method('getEntityTypeId')
+            ->will($this->returnValue($entityTypeId));
+        $attributeSetMock->expects($this->once())
+            ->method('load')
+            ->with($attributeSetId)
+            ->will($this->returnSelf());
+
+        $this->attrCollectionMock->expects($this->once())->method('setAttributeSetFilter')->with($attributeSetId)
+            ->will($this->returnSelf());
+
+        $attributeData = array(
+            'attribute_id' => 1,
+            'attribute_code' => 'status',
+            'frontend_label' => 'Status',
+            'default_value' => '1',
+            'is_required' => false,
+            'is_user_defined' => false,
+        );
+
+        // Use magento object for simplicity
+        $this->attrCollectionMock->expects($this->once())->method('load')->will($this->returnValue(
+            array(new \Magento\Framework\Object($attributeData))
+        ));
+        $this->attributeBuilderMock->expects($this->once())
+            ->method('setId')
+            ->with($attributeData['attribute_id'])
+            ->will($this->returnSelf());
+        $this->attributeBuilderMock->expects($this->once())
+            ->method('setCode')
+            ->with($attributeData['attribute_code'])
+            ->will($this->returnSelf());
+        $this->attributeBuilderMock->expects($this->once())
+            ->method('setFrontendLabel')
+            ->with($attributeData['frontend_label'])
+            ->will($this->returnSelf());
+        $this->attributeBuilderMock->expects($this->once())
+            ->method('setDefaultValue')
+            ->with($attributeData['default_value'])
+            ->will($this->returnSelf());
+        $this->attributeBuilderMock->expects($this->once())
+            ->method('setIsRequired')
+            ->with($attributeData['is_required'])
+            ->will($this->returnSelf());
+        $this->attributeBuilderMock->expects($this->once())
+            ->method('setIsUserDefined')
+            ->with($attributeData['is_user_defined'])
+            ->will($this->returnSelf());
+
+        $dataObjectMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Data\Eav\Attribute',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $this->attributeBuilderMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($dataObjectMock));
+        $this->assertContains($dataObjectMock, $this->service->getAttributeList($attributeSetId));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage No such entity with attributeSetId = 80085
+     */
+    public function testGetAttributeListThrowsExceptionIfIdIsNotValid()
+    {
+        $attributeSetId = 80085;
+        $attributeSetMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Set',
+            array('load', 'getId', 'getName', 'getSortOrder', '__wakeup'),
+            array(),
+            '',
+            false
+        );
+        $this->setFactoryMock->expects($this->once())->method('create')->will($this->returnValue($attributeSetMock));
+        $attributeSetMock->expects($this->once())
+            ->method('load')
+            ->with($attributeSetId)
+            ->will($this->returnSelf());
+        $this->attrCollectionMock->expects($this->never())->method('load');
+        $this->attributeBuilderMock->expects($this->never())->method('create');
+        $this->service->getAttributeList($attributeSetId);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/WriteServiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..62f48a97cc1e3f356593cea7a9506a0079e01afe
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/AttributeSet/WriteServiceTest.php
@@ -0,0 +1,379 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1\Product\AttributeSet;
+
+use Magento\Catalog\Service\V1\Data\Eav\AttributeSet;
+
+class WriteServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $setFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eavConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $entityTypeMock;
+
+    /**
+     * @var \Magento\Catalog\Service\V1\Product\AttributeSet\WriteService
+     */
+    protected $service;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $setMock;
+
+    /**
+     * @var int default attribute set id
+     */
+    protected $defaultSetId = 4;
+
+    protected function setUp()
+    {
+        $this->setFactoryMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\SetFactory',
+            array('create'), array(), '', false);
+        $this->eavConfigMock = $this->getMock('\Magento\Eav\Model\Config', array(), array(), '', false);
+        $this->entityTypeMock = $this->getMock('\Magento\Eav\Model\Entity\Type', array(), array(), '', false);
+        $this->eavConfigMock->expects($this->any())->method('getEntityType')
+            ->with(\Magento\Catalog\Model\Product::ENTITY)
+            ->will($this->returnValue($this->entityTypeMock));
+        $this->setMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Set',
+            array(
+                'setData', 'getData', 'validate', 'save', 'getId', 'delete', 'setAttributeSetName', 'setSortOrder',
+                'load', 'initFromSkeleton', '__wakeup', 'getEntityTypeId',
+            ),
+            array(),
+            '',
+            false
+        );
+        $this->service = new WriteService(
+            $this->setFactoryMock,
+            $this->eavConfigMock
+        );
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     */
+    public function testCreateWithExistingId()
+    {
+        $setDataMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $this->setFactoryMock->expects($this->any())->method('create')->will($this->returnValue($this->setMock));
+        $setDataMock->expects($this->any())->method('getId')->will($this->returnValue($this->defaultSetId));
+
+        $this->service->create($setDataMock, $this->defaultSetId);
+    }
+
+    /**
+     * @expectedException \Magento\Eav\Exception
+     */
+    public function testCreateWithEmptyName()
+    {
+        $setDataMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $setDataMock->expects($this->any())->method('getId')->will($this->returnValue(null));
+        $setDataMock->expects($this->any())->method('getName')->will($this->returnValue(null));
+        $setDataMock->expects($this->any())->method('getSortOrder')->will($this->returnValue(20));
+
+        $this->setFactoryMock->expects($this->once())->method('create')->will($this->returnValue($this->setMock));
+        $exception = new \Magento\Eav\Exception('empty name');
+        $this->setMock->expects($this->once())->method('validate')->will($this->throwException($exception));
+        $this->setMock->expects($this->never())->method('save');
+
+        $this->service->create($setDataMock, $this->defaultSetId);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     */
+    public function testCreateWithNoSkeletonId()
+    {
+        $setDataMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $setDataMock->expects($this->any())->method('getId')->will($this->returnValue(null));
+        $setDataMock->expects($this->any())->method('getName')->will($this->returnValue('cool attribute set'));
+        $setDataMock->expects($this->any())->method('getSortOrder')->will($this->returnValue(20));
+
+        $this->setFactoryMock->expects($this->once())->method('create')->will($this->returnValue($this->setMock));
+        $this->setMock->expects($this->once())->method('validate')->will($this->returnValue(true));
+
+        $this->service->create($setDataMock, null);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function testCreateWithAbsentSkeleton()
+    {
+        $absentId = 134523;
+        $setDataMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $setDataMock->expects($this->any())->method('getId')->will($this->returnValue(null));
+        $setDataMock->expects($this->any())->method('getName')->will($this->returnValue('cool attribute set'));
+        $setDataMock->expects($this->any())->method('getSortOrder')->will($this->returnValue(20));
+
+        $this->setFactoryMock->expects($this->exactly(2))->method('create')->will($this->returnValue($this->setMock));
+        $this->setMock->expects($this->once())->method('validate')->will($this->returnValue(true));
+        $skeletonSetMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Set',
+            array('setData', 'validate', 'save', 'getId', 'getData', 'load', '__wakeup'),
+            array(),
+            '',
+            false
+        );
+        $skeletonSetMock->expects($this->once())->method('getData')->will($this->returnValue(array()));
+        $this->setMock->expects($this->once())->method('load')
+            ->with($absentId)
+            ->will($this->returnValue($skeletonSetMock));
+
+        $this->service->create($setDataMock, $absentId);
+    }
+
+    public function testCreatePositive()
+    {
+        $setId = 123321;
+        $setDataMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $setDataMock->expects($this->any())->method('getId')->will($this->returnValue(null));
+        $setDataMock->expects($this->any())->method('getName')->will($this->returnValue('cool attribute set'));
+        $setDataMock->expects($this->any())->method('getSortOrder')->will($this->returnValue(20));
+
+        $this->setFactoryMock->expects($this->exactly(2))->method('create')->will($this->returnValue($this->setMock));
+        $this->setMock->expects($this->once())->method('validate')->will($this->returnValue(true));
+        $this->setMock->expects($this->exactly(2))->method('save');
+        $this->setMock->expects($this->once())->method('getId')->will($this->returnValue($setId));
+        $skeletonSetMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Set',
+            array('setData', 'validate', 'save', 'getId', 'load', 'getData', '__wakeup'),
+            array(),
+            '',
+            false
+        );
+        $this->setMock->expects($this->once())->method('load')
+            ->with($this->defaultSetId)
+            ->will($this->returnValue($skeletonSetMock));
+        $skeletonSetMock->expects($this->once())->method('getData')->will($this->returnValue(array(1, 2, 3)));
+        $this->setMock->expects($this->once())->method('initFromSkeleton')->with($this->defaultSetId);
+
+        $this->assertEquals($setId, $this->service->create($setDataMock, $this->defaultSetId));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     */
+    public function testRemoveInvalidId()
+    {
+        $this->setFactoryMock->expects($this->never())->method('create');
+        $this->service->remove('absent id');
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function testRemoveAbsentSet()
+    {
+        $id = 145678;
+        $this->setFactoryMock->expects($this->once())->method('create')->will($this->returnValue($this->setMock));
+        $this->setMock->expects($this->once())->method('load')->with($id)->will($this->returnSelf());
+        $this->setMock->expects($this->once())->method('getData')->will($this->returnValue(null));
+        $this->setMock->expects($this->never())->method('delete');
+        $this->service->remove($id);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     */
+    public function testRemoveWrongEntity()
+    {
+        $id = 14;
+
+        $this->setFactoryMock->expects($this->once())->method('create')->will($this->returnValue($this->setMock));
+        $typeMock = $this->getMock('\Magento\Eav\Model\Entity\Type', array('getId', '__wakeup'), array(), '', false);
+        $this->eavConfigMock->expects($this->any())->method('getEntityType')->will($this->returnValue($typeMock));
+        $typeMock->expects($this->any())->method('getId')->will($this->returnValue(4));
+
+        $this->setMock->expects($this->once())->method('load')->with($id)->will($this->returnSelf());
+        $this->setMock->expects($this->once())->method('getData')->will($this->returnValue(array(5, 7, 9)));
+        $this->setMock->expects($this->any())->method('getEntityTypeId')->will($this->returnValue(1));
+        $this->setMock->expects($this->never())->method('delete');
+        $this->service->remove($id);
+    }
+
+    public function testRemovePositive()
+    {
+        $id = 456;
+        $this->setFactoryMock->expects($this->once())->method('create')->will($this->returnValue($this->setMock));
+        $this->setMock->expects($this->once())->method('load')->with($id)->will($this->returnSelf());
+        $this->setMock->expects($this->once())->method('getData')->will($this->returnValue(array(5, 6, 7)));
+        $this->setMock->expects($this->once())->method('delete');
+
+        $this->service->remove($id);
+    }
+
+    public function testUpdate()
+    {
+        $data = array(
+            AttributeSet::ID => 4,
+            AttributeSet::NAME => 'Test Attribute Set',
+            AttributeSet::ORDER => 200,
+        );
+        $attributeSetDataMock = $this->getMock('Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(), array(), '', false);
+        $attributeSetDataMock->expects($this->any())->method('getId')
+            ->will($this->returnValue($data[AttributeSet::ID]));
+        $attributeSetDataMock->expects($this->any())->method('getName')
+            ->will($this->returnValue($data[AttributeSet::NAME]));
+        $attributeSetDataMock->expects($this->any())->method('getSortOrder')
+            ->will($this->returnValue($data[AttributeSet::ORDER]));
+
+        $entityTypeId = 4;
+        $this->entityTypeMock->expects($this->once())->method('getId')->will($this->returnValue($entityTypeId));
+
+        $this->setFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($this->setMock));
+        $this->setMock->expects($this->once())
+            ->method('load')
+            ->with($data[AttributeSet::ID])
+            ->will($this->returnSelf());
+        $this->setMock->expects($this->any())
+            ->method('getEntityTypeId')
+            ->will($this->returnValue($entityTypeId));
+        $this->setMock->expects($this->any())->method('getId')
+            ->will($this->returnValue($data[AttributeSet::ID]));
+        $this->setMock->expects($this->once())->method('setAttributeSetName')->with($data[AttributeSet::NAME])
+            ->will($this->returnSelf());
+        $this->setMock->expects($this->once())->method('setSortOrder')->with($data[AttributeSet::ORDER])
+            ->will($this->returnSelf());
+        $this->setMock->expects($this->once())->method('save')
+            ->will($this->returnSelf());
+        $this->assertEquals($data[AttributeSet::ID], $this->service->update($attributeSetDataMock));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\InputException
+     * @expectedExceptionMessage id is a required field.
+     */
+    public function testUpdateThrowsExceptionIfAttributeSetIdIsNotSpecified()
+    {
+        $data = array(
+            AttributeSet::ID => null,
+            AttributeSet::NAME => 'Test Attribute Set',
+            AttributeSet::ORDER => 200,
+        );
+        $attributeSetDataMock = $this->getMock('Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(), array(), '', false);
+        $attributeSetDataMock->expects($this->any())->method('getId')
+            ->will($this->returnValue($data[AttributeSet::ID]));
+        $this->service->update($attributeSetDataMock);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage No such entity with id = 9999
+     */
+    public function testUpdateThrowsExceptionIfAttributeSetIdIsInvalid()
+    {
+        $entityTypeId = 4;
+        $data = array(
+            AttributeSet::ID => 9999,
+            AttributeSet::NAME => 'Test Attribute Set',
+            AttributeSet::ORDER => 200,
+        );
+        $attributeSetDataMock = $this->getMock('Magento\Catalog\Service\V1\Data\Eav\AttributeSet',
+            array(), array(), '', false);
+        $attributeSetDataMock->expects($this->any())->method('getId')
+            ->will($this->returnValue($data[AttributeSet::ID]));
+
+        $this->entityTypeMock->expects($this->once())->method('getId')->will($this->returnValue($entityTypeId));
+
+        $this->setFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($this->setMock));
+        $this->setMock->expects($this->once())
+            ->method('load')
+            ->with($data[AttributeSet::ID])
+            ->will($this->returnSelf());
+        $this->setMock->expects($this->any())
+            ->method('getEntityTypeId')
+            ->will($this->returnValue($entityTypeId));
+        $this->setMock->expects($this->any())->method('getId');
+        $this->setMock->expects($this->never())->method('setAttributeSetName');
+        $this->setMock->expects($this->never())->method('setSortOrder');
+        $this->setMock->expects($this->never())->method('save');
+        $this->service->update($attributeSetDataMock);
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\StateException
+     * @expectedExceptionMessage Default attribute set can not be deleted
+     */
+    public function testRemoveDefaultAttributeSet()
+    {
+        $id = 456;
+        $this->setFactoryMock->expects($this->once())->method('create')->will($this->returnValue($this->setMock));
+        $this->setMock->expects($this->once())->method('load')->with($id)->will($this->returnSelf());
+        $this->setMock->expects($this->once())->method('getData')->will($this->returnValue(array(5, 6, 7)));
+        $this->setMock->expects($this->never())->method('delete');
+        $this->entityTypeMock
+            ->expects($this->once())
+            ->method('getDefaultAttributeSetId')
+            ->will($this->returnValue($id));
+        $this->service->remove($id);
+    }
+
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/CrosssellTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/CrosssellTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9afa36d6ab7d6c1aa82933a034c409a3c1d7a687
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/CrosssellTest.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\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider;
+
+class CrosssellTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetLinkedProducts()
+    {
+        $product = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
+        $expected = [$product];
+        $product->expects($this->once())->method('getCrossSellProducts')->will($this->returnValue($expected));
+        $model = new Crosssell();
+        $this->assertEquals($expected, $model->getLinkedProducts($product));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/RelatedTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/RelatedTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..df30fbdcbc6d88e37ee16017a7f49fef98da54ef
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/RelatedTest.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\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider;
+
+class RelatedTest  extends \PHPUnit_Framework_TestCase
+{
+    public function testGetLinkedProducts()
+    {
+        $product = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
+        $expected = [$product];
+        $product->expects($this->once())->method('getRelatedProducts')->will($this->returnValue($expected));
+        $model = new Related();
+        $this->assertEquals($expected, $model->getLinkedProducts($product));
+    }
+} 
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/UpsellTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/UpsellTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..691e93a337724bf6ad4edcf8c5f17d6217abc828
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/UpsellTest.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\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider;
+
+class UpsellTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetLinkedProducts()
+    {
+        $product = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
+        $expected = [$product];
+        $product->expects($this->once())->method('getUpSellProducts')->will($this->returnValue($expected));
+        $model = new Upsell();
+        $this->assertEquals($expected, $model->getLinkedProducts($product));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProviderTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..60f651e36aa52a0405cbe1e6ae3e29d6b4611d86
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/CollectionProviderTest.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+
+class CollectionProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $converterPoolMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $converterMock;
+
+    protected function setUp()
+    {
+        $this->productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
+        $this->converterPoolMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterPool',
+            [], [], '', false
+        );
+        $this->converterMock = $this->getMock(
+            '\Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterInterface'
+        );
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Collection provider is not registered
+     */
+    public function testGetCollectionWithInvalidType()
+    {
+        $provider = new CollectionProvider($this->converterPoolMock);
+        $provider->getCollection($this->productMock, 'someType');
+    }
+
+    /**
+     * @covers \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider::getCollection
+     * @covers \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider::__construct
+     */
+    public function testGetCollection()
+    {
+        $productA = $this->getMock('\Magento\Catalog\Model\Product', ['getId', '__wakeup'], [], '', false);
+        $productA->expects($this->once())->method('getId')->will($this->returnValue('resultA'));
+        $providerA = $this->getMock(
+            '\Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProviderInterface'
+        );
+        $providerA->expects($this->once())
+            ->method('getLinkedProducts')
+            ->with($this->productMock)
+            ->will($this->returnValue([$productA]));
+        $resultA = ['resultA' => $productA];
+
+        $productB = $this->getMock('\Magento\Catalog\Model\Product', ['getId', '__wakeup'], [], '', false);
+        $productB->expects($this->once())->method('getId')->will($this->returnValue('resultB'));
+        $providerB = $this->getMock(
+            '\Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProviderInterface'
+        );
+        $providerB->expects($this->once())
+            ->method('getLinkedProducts')
+            ->with($this->productMock)
+            ->will($this->returnValue([$productB]));
+        $resultB = ['resultB' => $productB];
+
+        $this->converterPoolMock
+            ->expects($this->any())
+            ->method('getConverter')
+            ->will($this->returnValue($this->converterMock));
+
+        $this->converterMock
+            ->expects($this->any())
+            ->method('convert')
+            ->will($this->returnArgument(0));
+
+        $provider = new CollectionProvider(
+            $this->converterPoolMock,
+            [
+                'typeA' => $providerA,
+                'typeB' => $providerB
+            ]
+        );
+
+        $this->assertEquals($resultA, $provider->getCollection($this->productMock, 'typeA'));
+        $this->assertEquals($resultB, $provider->getCollection($this->productMock, 'typeB'));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapper/CompositeTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapper/CompositeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b8176547111ab977c36cd3dd442aac3b6cc6f96
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/DataMapper/CompositeTest.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\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapper;
+
+class CompositeTest extends \PHPUnit_Framework_TestCase
+{
+    public function testMap()
+    {
+        $mapperOne = $this->getMock(
+            '\Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapperInterface'
+        );
+
+        $mapperTwo = $this->getMock(
+            '\Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapperInterface'
+        );
+
+        $model = new Composite([$mapperOne, $mapperTwo]);
+        $originData = ['some' => 'test', 'data' => '.'];
+        $firstModification = ['some' => 'test', 'data' => '.', 'first' => 'modification'];
+        $secondModification = ['some' => 'test', 'data' => '.', 'first' => 'modification', 'second' => 'modification'];
+
+        $mapperOne->expects($this->once())
+            ->method('map')
+            ->with($originData)
+            ->will($this->returnValue($firstModification));
+
+        $mapperTwo->expects($this->once())
+            ->method('map')
+            ->with($firstModification)
+            ->will($this->returnValue($secondModification));
+
+        $this->assertEquals($secondModification, $model->map($originData));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterPoolTests.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterPoolTests.php
new file mode 100644
index 0000000000000000000000000000000000000000..71552cb330073b228c0eae08234bf885ad0f22e8
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterPoolTests.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\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity;
+
+class ConverterPoolTests extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterPool
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $converters = array(
+            'simple' => 'Simple Converter',
+            'complex' => 'Complex Converter',
+            'default' => 'Default Converter',
+        );
+
+        $this->model = new \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity\ConverterPool(
+            $converters
+        );
+    }
+
+    public function testGetConverterExisting()
+    {
+        $this->assertEquals('Simple Converter', $this->model->getConverter('simple'));
+    }
+
+    public function testGetConverterAbsent()
+    {
+        $this->assertEquals('Default Converter', $this->model->getConverter('absent'));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/DefaultConverterTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/DefaultConverterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0bd91bb6c9b7462428dec93c1d9071bd63ca7a6b
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/Data/ProductLink/ProductEntity/DefaultConverterTest.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\Catalog\Service\V1\Product\Link\Data\ProductLink\ProductEntity;
+
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+
+class DefaultConverterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $product;
+
+    /**
+     * @var DefaultConverter
+     */
+    protected $converter;
+
+    protected function setUp()
+    {
+        $this->product = $this->getMock(
+            '\Magento\Catalog\Model\Product',
+            ['getTypeId', 'getSku', 'getPosition', '__sleep', '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+        $this->converter = new DefaultConverter();
+    }
+
+    public function testConvert()
+    {
+        $this->product->expects($this->once())->method('getTypeId')->will($this->returnValue('simple'));
+        $this->product->expects($this->once())->method('getSku')->will($this->returnValue('simple-sku'));
+        $this->product->expects($this->once())->method('getPosition')->will($this->returnValue(1));
+
+        $expected = [
+            ProductLink::TYPE => 'simple',
+            ProductLink::SKU => 'simple-sku',
+            ProductLink::POSITION => 1
+        ];
+
+        $this->assertEquals($expected, $this->converter->convert($this->product));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/LinkTypeResolverTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/LinkTypeResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0af948e7a56a56d046ca20ce3b548ec4deb4fefa
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/LinkTypeResolverTest.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link;
+
+class LinkTypeResolverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var LinkTypeResolver
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $providerMock;
+
+    protected function setUp()
+    {
+        $this->providerMock = $this->getMock('Magento\Catalog\Model\Product\LinkTypeProvider', [], [], '', false);
+        $this->model = new LinkTypeResolver($this->providerMock);
+    }
+
+    public function testGetTypeIdByCode()
+    {
+        $linkTypes = ['crosssell' => 1, 'upsell' => 2, 'related' => 4];
+        $this->providerMock->expects($this->once())->method('getLinkTypes')->will($this->returnValue($linkTypes));
+        $this->assertEquals(4, $this->model->getTypeIdByCode('related'));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Unknown link type code is provided
+     */
+    public function testGetTypeIdByCodeWithInvalidType()
+    {
+        $linkTypes = ['crosssell' => 1, 'upsell' => 2, 'related' => 4];
+        $this->providerMock->expects($this->once())->method('getLinkTypes')->will($this->returnValue($linkTypes));
+        $this->model->getTypeIdByCode('invalid_type');
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/ProductLoaderTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/ProductLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..347e76b35babe970fcf123881fbfd56552f3efa6
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/ProductLoaderTest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Service\V1\Product\Link;
+
+class ProductLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ProductLoader
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $factoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var string
+     */
+    protected $productSku = 'simple-sku';
+
+    protected function setUp()
+    {
+        $this->factoryMock = $this->getMock('\Magento\Catalog\Model\ProductFactory', ['create'], [], '', false);
+        $this->productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
+        $this->model = new ProductLoader($this->factoryMock);
+    }
+
+    public function testLoad()
+    {
+        $this->factoryMock->expects($this->once())->method('create')->will($this->returnValue($this->productMock));
+        $this->productMock->expects($this->once())
+            ->method('getIdBySku')
+            ->with($this->productSku)
+            ->will($this->returnValue(1));
+
+        $this->productMock->expects($this->once())->method('load')->with(1);
+        $this->assertEquals($this->productMock, $this->model->load($this->productSku));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage There is no product with provided SKU
+     */
+    public function testLoadWithNonExistedProduct()
+    {
+        $this->factoryMock->expects($this->once())->method('create')->will($this->returnValue($this->productMock));
+        $this->productMock->expects($this->once())
+            ->method('getIdBySku')
+            ->with($this->productSku)
+            ->will($this->returnValue(null));
+
+        $this->productMock->expects($this->never())->method('load');
+
+        $this->assertEquals($this->productMock, $this->model->load($this->productSku));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/ReadServiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..82e91616653eb5f7a87d5e51eae565b05103561f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/ReadServiceTest.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1\Product\Link;
+
+use Magento\Catalog\Service\V1\Product\Link\Data\LinkType;
+use Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+
+class ReadServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ReadService
+     */
+    protected $service;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $providerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $builderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productBuilderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productLoaderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionProviderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkBuilderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkResolverMock;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->providerMock = $this->getMock('Magento\Catalog\Model\Product\LinkTypeProvider', [], [], '', false);
+        $this->builderMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\Data\LinkTypeBuilder',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->productBuilderMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\Data\ProductLinkBuilder',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->productLoaderMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\ProductLoader',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->collectionProviderMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->linkFactoryMock = $this->getMock(
+            'Magento\Catalog\Model\Product\LinkFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+
+        $this->linkBuilderMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\Data\LinkAttributeBuilder',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->linkResolverMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\LinkTypeResolver',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->service = $helper->getObject(
+            'Magento\Catalog\Service\V1\Product\Link\ReadService',
+            [
+                'linkTypeProvider' => $this->providerMock,
+                'builder' => $this->builderMock,
+                'productLoader'  => $this->productLoaderMock,
+                'productEntityBuilder' => $this->productBuilderMock,
+                'entityCollectionProvider' => $this->collectionProviderMock,
+                'linkFactory' => $this->linkFactoryMock,
+                'linkAttributeBuilder' => $this->linkBuilderMock,
+                'linkTypeResolver' => $this->linkResolverMock
+
+            ]
+        );
+    }
+
+    public function testGetProductLinkTypes()
+    {
+        $types = ['typeOne' => 'codeOne', 'typeTwo' => 'codeTwo'];
+
+        $this->providerMock->expects($this->once())->method('getLinkTypes')->will($this->returnValue($types));
+
+        $this->builderMock->expects($this->exactly(2))
+            ->method('populateWithArray')
+            ->with(
+                $this->logicalOr(
+                    $this->equalTo([LinkType::TYPE => 'typeOne', LinkType::CODE => 'codeOne']),
+                    $this->equalTo([LinkType::TYPE => 'typeTwo', LinkType::CODE => 'codeTwo'])
+                )
+            )->will($this->returnSelf());
+
+        $this->builderMock->expects($this->exactly(2))
+            ->method('create')
+            ->will($this->returnSelf());
+
+        $this->assertCount(2, $this->service->getProductLinkTypes());
+    }
+
+    public function testGetLinkedProducts()
+    {
+        $productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $this->productLoaderMock
+            ->expects($this->once())->method('load')
+            ->with('product_sku')
+            ->will($this->returnValue($productMock));
+        $itemMock = [
+            ProductLink::TYPE => 'typeId',
+            ProductLink::SKU => 'sku',
+            ProductLink::POSITION => 0
+        ];
+        $this->collectionProviderMock
+            ->expects($this->once())
+            ->method('getCollection')
+            ->with($productMock, 'productType')
+            ->will($this->returnValue(array($itemMock)));
+
+        $this->productBuilderMock
+            ->expects($this->once())
+            ->method('populateWithArray')
+            ->with($itemMock)
+            ->will($this->returnSelf());
+        $this->productBuilderMock->expects($this->once())->method('create')->will($this->returnValue('Expected'));
+        $this->assertequals(array('Expected'), $this->service->getLinkedProducts('product_sku', 'productType'));
+    }
+
+    public function testGetLinkedAttributes()
+    {
+        $linkMock = $this->getMock('Magento\Catalog\Model\Product\Link', array(), array(), '', false);
+        $attributeMock = [['code' => 'code_name', 'type' => 'type_name']];
+        $this->linkResolverMock
+            ->expects($this->once())
+            ->method('getTypeIdByCode')
+            ->with('productType')
+            ->will($this->returnValue('type_id'));
+        $this->linkFactoryMock
+            ->expects($this->once())
+            ->method('create')
+            ->with(['data' => ['link_type_id' => 'type_id']])
+            ->will($this->returnValue($linkMock));
+        $data = [
+            Data\LinkAttribute::CODE => 'code_name',
+            Data\LinkAttribute::TYPE => 'type_name'
+        ];
+        $linkMock->expects($this->once())->method('getAttributes')->will($this->returnValue($attributeMock));
+        $this->linkBuilderMock
+            ->expects($this->once())
+            ->method('populateWithArray')
+            ->with($data)
+            ->will($this->returnSelf());
+        $this->linkBuilderMock->expects($this->once())->method('create')->will($this->returnValue('Expected'));
+        $this->assertequals(array('Expected'), $this->service->getLinkAttributes('productType'));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/WriteServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/WriteServiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d5d764f104d409733f9f749cb8cc2860cac7ede
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/Product/Link/WriteServiceTest.php
@@ -0,0 +1,317 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Service\V1\Product\Link;
+
+use \Magento\Framework\Exception\CouldNotSaveException;
+
+class WriteServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var WriteService
+     */
+    protected $service;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $linkInitializerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionProviderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productLoaderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productResourceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dataMapperMock;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->linkInitializerMock = $this->getMock(
+            'Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->collectionProviderMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\CollectionProvider',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->productLoaderMock = $this->getMock(
+           'Magento\Catalog\Service\V1\Product\Link\ProductLoader',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->productResourceMock = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->dataMapperMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\Data\ProductLink\DataMapperInterface',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->service = $helper->getObject('Magento\Catalog\Service\V1\Product\Link\WriteService',
+            [
+                'linkInitializer' => $this->linkInitializerMock,
+                'entityCollectionProvider' => $this->collectionProviderMock,
+                'productLoader' => $this->productLoaderMock,
+                'productResource' => $this->productResourceMock,
+                'dataMapper' => $this->dataMapperMock
+            ]
+        );
+    }
+
+    public function testSaveLinks()
+    {
+        $assignedProductMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+
+        $this->productLoaderMock
+            ->expects($this->once())
+            ->method('load')
+            ->with('product_sku')
+            ->will($this->returnValue($productMock));
+        $assignedProductMock->expects($this->any())->method('getSku')->will($this->returnValue('assigned_sku'));
+        $this->productResourceMock
+            ->expects($this->once())
+            ->method('getProductsIdsBySkus')
+            ->with(array('assigned_sku'))
+           ->will($this->returnValue(['assigned_sku' => 1]));
+        $this->dataMapperMock->expects($this->once())->method('map')->with([1 => ['product_id' => 1]]);
+        $productMock->expects($this->once())->method('save');
+        $this->assertTrue($this->service->assign('product_sku', array($assignedProductMock), 'product_type'));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Product with SKU "assigned_sku" does not exist
+     */
+    public function testSaveLinkWithNotExistingSku()
+    {
+        $assignedProductMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+
+        $this->productLoaderMock
+            ->expects($this->once())
+            ->method('load')
+            ->with('product_sku')
+            ->will($this->returnValue($productMock));
+        $assignedProductMock->expects($this->any())->method('getSku')->will($this->returnValue('assigned_sku'));
+        $this->productResourceMock
+            ->expects($this->once())
+            ->method('getProductsIdsBySkus')
+            ->with(array('assigned_sku'))
+            ->will($this->returnValue(['some_sku' => 1]));
+        $productMock->expects($this->never())->method('save');
+        $this->service->assign('product_sku', array($assignedProductMock), 'product_type');
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\CouldNotSaveException
+     * @expectedExceptionMessage Invalid data provided for linked products
+     */
+    public function testSaveLinkWithInvalidData()
+    {
+        $assignedProductMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+
+        $this->productLoaderMock
+            ->expects($this->once())
+            ->method('load')
+            ->with('product_sku')
+            ->will($this->returnValue($productMock));
+        $assignedProductMock->expects($this->any())->method('getSku')->will($this->returnValue('assigned_sku'));
+        $this->productResourceMock
+            ->expects($this->once())
+            ->method('getProductsIdsBySkus')
+            ->with(array('assigned_sku'))
+            ->will($this->returnValue(['assigned_sku' => 1]));
+        $this->dataMapperMock->expects($this->once())->method('map')->with([1 => ['product_id' => 1]]);
+        $productMock
+            ->expects($this->once())
+            ->method('save')
+            ->will($this->throwException(new CouldNotSaveException('Invalid data provided for linked products')));
+        $this->service->assign('product_sku', array($assignedProductMock), 'product_type');
+    }
+
+    public function testSuccessUpdate()
+    {
+        $linkedEntityMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\Data\ProductLink',
+            [],
+            [],
+            '',
+            false
+        );
+        $productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $linkedProductMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $valueMap = [
+            ['product_sku', $productMock],
+            ['linked_product_sku', $linkedProductMock]
+        ];
+        $linkedEntityMock->expects($this->any())->method('getSku')->will($this->returnValue('linked_product_sku'));
+        $linkedProductMock->expects($this->exactly(3))->method('getId')->will($this->returnValue(10));
+        $this->productLoaderMock
+            ->expects($this->any())
+            ->method('load')
+            ->will($this->returnValueMap($valueMap));
+        $this->collectionProviderMock
+            ->expects($this->once())
+            ->method('getCollection')
+            ->with($productMock, 'product_type')
+            ->will($this->returnValue([10 => 1]));
+        $this->dataMapperMock
+            ->expects($this->once())
+            ->method('map')
+            ->with([10 => ['product_id' => 10]])
+            ->will($this->returnValue('mapped_value'));
+        $this->linkInitializerMock
+            ->expects($this->once())
+            ->method('initializeLinks')
+            ->with($productMock, ['product_type' => 'mapped_value']);
+        $productMock->expects($this->once())->method('save');
+        $this->assertTrue($this->service->update('product_sku', $linkedEntityMock, 'product_type'));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Product with SKU "linked_product_sku" is not linked to product with SKU product_sku
+     */
+    public function testUpdateNotLinkedProduct()
+    {
+        $linkedEntityMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Product\Link\Data\ProductLink',
+            [],
+            [],
+            '',
+            false
+        );
+        $productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $linkedProductMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $valueMap = [
+            ['product_sku', $productMock],
+            ['linked_product_sku', $linkedProductMock]
+        ];
+        $linkedEntityMock->expects($this->exactly(2))->method('getSku')->will($this->returnValue('linked_product_sku'));
+        $linkedProductMock->expects($this->exactly(1))->method('getId')->will($this->returnValue(5));
+        $this->productLoaderMock
+            ->expects($this->any())
+            ->method('load')
+            ->will($this->returnValueMap($valueMap));
+        $this->collectionProviderMock
+            ->expects($this->once())
+            ->method('getCollection')
+            ->with($productMock, 'product_type')
+            ->will($this->returnValue([10 => 1]));
+        $productMock->expects($this->never())->method('save');
+        $this->service->update('product_sku', $linkedEntityMock, 'product_type');
+    }
+
+    public function testSuccessRemove()
+    {
+        $productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $linkedProductMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $valueMap = [
+            ['product_sku', $productMock],
+            ['linked_product_sku', $linkedProductMock]
+        ];
+        $linkedProductMock->expects($this->exactly(2))->method('getId')->will($this->returnValue(10));
+        $this->productLoaderMock
+            ->expects($this->any())
+            ->method('load')
+            ->will($this->returnValueMap($valueMap));
+        $this->collectionProviderMock
+            ->expects($this->once())
+            ->method('getCollection')
+            ->with($productMock, 'product_type')
+            ->will($this->returnValue([10 => 1]));
+        $this->dataMapperMock
+            ->expects($this->once())
+            ->method('map')
+            ->with([])
+            ->will($this->returnValue('mapped_value'));
+        $this->linkInitializerMock
+            ->expects($this->once())
+            ->method('initializeLinks')
+            ->with($productMock, ['product_type' => 'mapped_value']);
+        $productMock->expects($this->once())->method('save');
+        $this->assertTrue($this->service->remove('product_sku', 'linked_product_sku', 'product_type'));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     * @expectedExceptionMessage Product with SKU linked_product_sku is not linked to product with SKU product_sku
+     */
+    public function testRemoveNotLinkedProduct()
+    {
+        $productMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $linkedProductMock = $this->getMock('Magento\Catalog\Model\Product', array(), array(), '', false);
+        $valueMap = [
+            ['product_sku', $productMock],
+            ['linked_product_sku', $linkedProductMock]
+        ];
+        $linkedProductMock->expects($this->exactly(1))->method('getId')->will($this->returnValue(5));
+        $this->productLoaderMock
+            ->expects($this->any())
+            ->method('load')
+            ->will($this->returnValueMap($valueMap));
+        $this->collectionProviderMock
+            ->expects($this->once())
+            ->method('getCollection')
+            ->with($productMock, 'product_type')
+            ->will($this->returnValue([10 => 1]));
+        $productMock->expects($this->never())->method('save');
+        $this->service->remove('product_sku', 'linked_product_sku', 'product_type');
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/ProductTypeServiceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/ProductTypeServiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ce47be825566c11b7943f05f1962ea2f1fb7fcc
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Service/V1/ProductTypeServiceTest.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Service\V1;
+
+class ProductTypeServiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ProductTypeService
+     */
+    private $service;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $typeConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $typeBuilderMock;
+
+    protected function setUp()
+    {
+        $this->typeConfigMock = $this->getMock('Magento\Catalog\Model\ProductTypes\ConfigInterface');
+        $this->typeBuilderMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Data\ProductTypeBuilder',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $this->service = new ProductTypeService(
+            $this->typeConfigMock,
+            $this->typeBuilderMock
+        );
+    }
+
+    public function testGetProductTypes()
+    {
+        $simpleProductType = array(
+            'name' => 'simple',
+            'label' => 'Simple Product',
+        );
+        $productTypeData = array(
+            'simple' => $simpleProductType,
+        );
+        $productTypeMock = $this->getMock(
+            'Magento\Catalog\Service\V1\Data\ProductType',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $this->typeConfigMock->expects($this->any())->method('getAll')->will($this->returnValue($productTypeData));
+        $this->typeBuilderMock->expects($this->once())
+            ->method('setName')
+            ->with($simpleProductType['name'])
+            ->will($this->returnSelf());
+        $this->typeBuilderMock->expects($this->once())
+            ->method('setLabel')
+            ->with($simpleProductType['label'])
+            ->will($this->returnSelf());
+        $this->typeBuilderMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($productTypeMock));
+
+        $productTypes = $this->service->getProductTypes();
+        $this->assertCount(1, $productTypes);
+        $this->assertContains($productTypeMock, $productTypes);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogRule/Pricing/Price/CatalogRulePriceTest.php b/dev/tests/unit/testsuite/Magento/CatalogRule/Pricing/Price/CatalogRulePriceTest.php
index ab93e29b48cfb018698b9a7e29a03701b7d834c4..db097c1d1d55c969fab766ff90f5ee58e6490bec 100644
--- a/dev/tests/unit/testsuite/Magento/CatalogRule/Pricing/Price/CatalogRulePriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogRule/Pricing/Price/CatalogRulePriceTest.php
@@ -55,7 +55,7 @@ class CatalogRulePriceTest extends \PHPUnit_Framework_TestCase
     protected $customerSessionMock;
 
     /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfo\Base | \PHPUnit_Framework_MockObject_MockObject
      */
     protected $priceInfoMock;
 
diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
index 71043e2a7826151696e0598407fa509d8bcd5f4d..53f619bd3e2005f0ee42385da08f5b797bbb17b4 100644
--- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
+++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Model/Product/Type/ConfigurableTest.php
@@ -35,6 +35,21 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
      */
     protected $_model;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_configurableAttributeFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_typeConfigurableFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_attributeCollectionFactory;
+
     /**
      * @var \Magento\TestFramework\Helper\ObjectManager
      */
@@ -52,9 +67,9 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
         $coreRegistry = $this->getMock('Magento\Framework\Registry', array(), array(), '', false);
         $logger = $this->getMock('Magento\Framework\Logger', array(), array(), '', false);
         $productFactoryMock = $this->getMock('Magento\Catalog\Model\ProductFactory', array(), array(), '', false);
-        $confFactoryMock = $this->getMock(
+        $this->_typeConfigurableFactory = $this->getMock(
             'Magento\ConfigurableProduct\Model\Resource\Product\Type\ConfigurableFactory',
-            array(),
+            ['create', 'saveProducts'],
             array(),
             '',
             false
@@ -68,9 +83,9 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $confAttrFactoryMock = $this->getMock(
+        $this->_configurableAttributeFactoryMock = $this->getMock(
             'Magento\ConfigurableProduct\Model\Product\Type\Configurable\AttributeFactory',
-            array(),
+            array('create'),
             array(),
             '',
             false
@@ -82,9 +97,9 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $attrColFactory = $this->getMock(
+        $this->_attributeCollectionFactory = $this->getMock(
             'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\CollectionFactory',
-            array(),
+            array('create'),
             array(),
             '',
             false
@@ -93,13 +108,13 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
             'Magento\ConfigurableProduct\Model\Product\Type\Configurable',
             array(
                 'productFactory' => $productFactoryMock,
-                'typeConfigurableFactory' => $confFactoryMock,
+                'typeConfigurableFactory' => $this->_typeConfigurableFactory,
                 'entityFactory' => $entityFactoryMock,
                 'attributeSetFactory' => $setFactoryMock,
                 'eavAttributeFactory' => $attributeFactoryMock,
-                'configurableAttributeFactory' => $confAttrFactoryMock,
+                'configurableAttributeFactory' => $this->_configurableAttributeFactoryMock,
                 'productCollectionFactory' => $productColFactory,
-                'attributeCollectionFactory' => $attrColFactory,
+                'attributeCollectionFactory' => $this->_attributeCollectionFactory,
                 'eventManager' => $eventManager,
                 'coreData' => $coreDataMock,
                 'fileStorageDb' => $fileStorageDbMock,
@@ -114,4 +129,63 @@ class ConfigurableTest extends \PHPUnit_Framework_TestCase
     {
         $this->assertTrue($this->_model->hasWeight(), 'This product has not weight, but it should');
     }
+
+    /**
+     * Test `Save` method
+     */
+    public function testSave()
+    {
+        $attributeData = [1 => [
+            'id' => 1,
+            'code' => 'someattr',
+            'attribute_id' => 111,
+            'position' => 0,
+            'label' => 'Some Super Attribute',
+            'values' => []
+        ]];
+
+        $product = $this->getMockBuilder('\Magento\Catalog\Model\Product')
+            ->setMethods(['getIsDuplicate', 'dataHasChangedFor', 'getConfigurableAttributesData', 'getStoreId',
+                'getId', 'getData', 'hasData', 'getAssociatedProductIds', '__wakeup', '__sleep'
+            ])->disableOriginalConstructor()
+            ->getMock();
+        $product->expects($this->any())->method('dataHasChangedFor')->will($this->returnValue('false'));
+        $product->expects($this->any())->method('getConfigurableAttributesData')
+            ->will($this->returnValue($attributeData));
+        $product->expects($this->once())->method('getIsDuplicate')->will($this->returnValue(true));
+        $product->expects($this->any())->method('getStoreId')->will($this->returnValue(1));
+        $product->expects($this->any())->method('getId')->will($this->returnValue(1));
+        $product->expects($this->any())->method('getAssociatedProductIds')->will($this->returnValue([2]));
+        $product->expects($this->any())->method('hasData')->with('_cache_instance_used_product_attribute_ids')
+            ->will($this->returnValue(true));
+        $product->expects($this->any())->method('getData')->with('_cache_instance_used_product_attribute_ids')
+            ->will($this->returnValue([1]));
+
+        $attribute = $this->getMockBuilder('\Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute')
+            ->disableOriginalConstructor()
+            ->setMethods(['addData', 'setStoreId', 'setProductId', 'save', '__wakeup', '__sleep'])
+            ->getMock();
+        $expectedAttributeData = $attributeData[1];
+        unset($expectedAttributeData['id']);
+        $attribute->expects($this->once())->method('addData')->with($expectedAttributeData)->will($this->returnSelf());
+        $attribute->expects($this->once())->method('setStoreId')->with(1)->will($this->returnSelf());
+        $attribute->expects($this->once())->method('setProductId')->with(1)->will($this->returnSelf());
+        $attribute->expects($this->once())->method('save')->will($this->returnSelf());
+
+        $this->_configurableAttributeFactoryMock->expects($this->any())->method('create')
+            ->will($this->returnValue($attribute));
+
+        $attributeCollection = $this->getMockBuilder(
+                '\Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable\Attribute\Collection'
+            )->setMethods(['setProductFilter', 'addFieldToFilter', 'walk'])->disableOriginalConstructor()
+            ->getMock();
+        $this->_attributeCollectionFactory->expects($this->any())->method('create')
+            ->will($this->returnValue($attributeCollection));
+
+        $this->_typeConfigurableFactory->expects($this->once())->method('create')->will($this->returnSelf());
+        $this->_typeConfigurableFactory->expects($this->once())->method('saveProducts')->withAnyParameters()
+            ->will($this->returnSelf());
+
+        $this->_model->save($product);
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Pricing/Price/AttributePriceTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Pricing/Price/AttributePriceTest.php
index ce0c9bc305a007e801ca805182442e22f4184c1f..8e7f8fa222fb21b3e404b65cb040b5ef1f3aac40 100644
--- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Pricing/Price/AttributePriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Pricing/Price/AttributePriceTest.php
@@ -50,7 +50,7 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase
     protected $calculatorMock;
 
     /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfo\Base |\PHPUnit_Framework_MockObject_MockObject
      */
     protected $priceInfoMock;
 
diff --git a/dev/tests/unit/testsuite/Magento/Core/Model/View/DesignTest.php b/dev/tests/unit/testsuite/Magento/Core/Model/View/DesignTest.php
index 1f08bd9f014e94707851935aa72ae15a800fe7b2..df8df8bf3cb458e82781168295e3e8fb3018245b 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Model/View/DesignTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Model/View/DesignTest.php
@@ -18,9 +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.
  *
- * @category    Magento
- * @package     Magento_Core
- * @subpackage  unit_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)
  */
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Renderer/Attribute/SendemailTest.php b/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Renderer/Attribute/SendemailTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..53222f9505e0ace53e3c19b5b0cb3c21b270c1ad
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Renderer/Attribute/SendemailTest.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\Customer\Block\Adminhtml\Edit\Renderer\Attribute;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class SendemailTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Sendemail */
+    protected $block;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Backend\Block\Template\Context|\PHPUnit_Framework_MockObject_MockObject */
+    protected $contextMock;
+
+    protected function setUp()
+    {
+        $this->contextMock = $this->getMockBuilder('Magento\Backend\Block\Template\Context')
+            ->setMethods(['getStoreManager'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+    }
+
+    public function testIsSingleStoreMode()
+    {
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', ['isSingleStoreMode'], [], '', false);
+        $storeManagerMock->expects($this->any())
+            ->method('isSingleStoreMode')
+            ->will($this->returnValue(true));
+        $this->contextMock->expects($this->any())
+            ->method('getStoreManager')
+            ->will($this->returnValue($storeManagerMock));
+
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Sendemail',
+            [
+                'context' => $this->contextMock
+            ]
+        );
+
+        $this->assertTrue($this->block->isSingleStoreMode());
+    }
+
+    public function testGetFormHtmlId()
+    {
+        $formMock = $this->getMock('Magento\Framework\Data\Form', ['getHtmlIdPrefix'], [], '', false);
+        $formMock->expects($this->once())->method('getHtmlIdPrefix')->will($this->returnValue('account_form'));
+        $this->block = $this->objectManagerHelper->getObject(
+            'Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Sendemail',
+            [
+                'context' => $this->contextMock,
+                'data' => ['form' => $formMock]
+            ]
+        );
+
+        $this->assertEquals('account_form', $this->block->getFormHtmlId());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php b/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cd77186b769a402d6f042cfa916db929911e9d8a
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Customer/Block/Adminhtml/Edit/Tab/AccountTest.php
@@ -0,0 +1,234 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Block\Adminhtml\Edit\Tab;
+
+use \Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+use \Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+
+class AccountTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Backend\Block\Template\Context|\PHPUnit_Framework_MockObject_MockObject */
+    protected $contextMock;
+
+    /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $registryMock;
+
+    /** @var \Magento\Framework\Data\FormFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $formFactoryMock;
+
+    /** @var \Magento\Framework\Json\EncoderInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $encoderInterfaceMock;
+
+    /** @var \Magento\Customer\Model\Metadata\FormFactory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerFormFactoryMock;
+
+    /** @var \Magento\Store\Model\System\Store|\PHPUnit_Framework_MockObject_MockObject */
+    protected $storeMock;
+
+    /** @var \Magento\Customer\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerHelperMock;
+
+    /** @var \Magento\Customer\Service\V1\CustomerAccountServiceInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerAccountServiceInterfaceMock;
+
+    /** @var \Magento\Customer\Service\V1\CustomerMetadataServiceInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerMetadataServiceInterfaceMock;
+
+    /** @var \Magento\Customer\Service\V1\Data\CustomerBuilder|\PHPUnit_Framework_MockObject_MockObject */
+    protected $customerBuilderMock;
+
+    protected function setUp()
+    {
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->contextMock = $this->getMockBuilder('Magento\Backend\Block\Template\Context')
+            ->setMethods(
+                ['getBackendSession', 'getLayout', 'getStoreManager', 'getUrlBuilder']
+            )->disableOriginalConstructor()
+            ->getMock();
+        $this->registryMock = $this->getMock('Magento\Framework\Registry');
+        $this->formFactoryMock = $this->getMock('Magento\Framework\Data\FormFactory', [], [], '', false);
+        $this->encoderInterfaceMock = $this->getMock('Magento\Framework\Json\EncoderInterface');
+        $this->customerFormFactoryMock = $this->getMockBuilder('Magento\Customer\Model\Metadata\FormFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeMock = $this->getMock('Magento\Store\Model\System\Store', [], [], '', false);
+        $this->customerHelperMock = $this->getMockBuilder('Magento\Customer\Helper\Data')
+            ->setMethods(['getNamePrefixOptions', 'getNameSuffixOptions'])
+            ->disableOriginalConstructor()->getMock();
+        $this->customerAccountServiceInterfaceMock = $this->getMock(
+            'Magento\Customer\Service\V1\CustomerAccountServiceInterface'
+        );
+        $this->customerMetadataServiceInterfaceMock = $this->getMock(
+            'Magento\Customer\Service\V1\CustomerMetadataServiceInterface'
+        );
+        $this->customerBuilderMock = $this->getMockBuilder('Magento\Customer\Service\V1\Data\CustomerBuilder')
+            ->setMethods(['populateWithArray', 'create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    /**
+     * @param $customerData
+     * @param $isSingleStoreMode
+     * @param $canModifyCustomer
+     */
+    private function _setupStoreMode($customerData, $isSingleStoreMode, $canModifyCustomer)
+    {
+        $backendSessionMock = $this->getMock('\Magento\Backend\Model\Session', ['getCustomerData'], [], '', false);
+        $backendSessionMock->expects($this->any())->method('getCustomerData')->will($this->returnValue([]));
+
+        $layoutMock = $this->getMock('\Magento\Framework\View\Layout\Element\Layout', ['createBlock'], [], '', false);
+        $layoutMock->expects($this->at(0))->method('createBlock')
+            ->with('Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Group')
+            ->will($this->returnValue(
+                $this->objectManagerHelper->getObject('\Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Group')
+            ));
+        $layoutMock->expects($this->at(1))->method('createBlock')
+            ->with('Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element')
+            ->will($this->returnValue(
+                $this->objectManagerHelper->getObject(
+                    'Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element'
+                )
+            ));
+        if (empty($customerData['id'])) {
+            $layoutMock->expects($this->at(2))->method('createBlock')
+                ->with('Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Sendemail')
+                ->will($this->returnValue($this->objectManagerHelper->getObject(
+                    'Magento\Customer\Block\Adminhtml\Edit\Renderer\Attribute\Sendemail'
+                ))
+            );
+        }
+
+        $urlBuilderMock = $this->getMock('\Magento\Backend\Model\Url', ['getBaseUrl'], [], '', false);
+        $urlBuilderMock->expects($this->once())->method('getBaseUrl')->will($this->returnValue('someUrl'));
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->any())->method('isSingleStoreMode')
+            ->will($this->returnValue($isSingleStoreMode));
+
+        $customerObject = $this->getMockBuilder('\Magento\Customer\Service\V1\Data\Customer')
+            ->setMethods(['__toArray', 'getId'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $customerObject->expects($this->any())->method('__toArray')->will($this->returnValue($customerData));
+        if (!empty($customerData['id'])) {
+            $customerObject->expects($this->any())->method('getId')->will($this->returnValue($customerData['id']));
+        }
+
+        $fieldset = $this->getMockBuilder('\Magento\Framework\Data\Form\Element\Fieldset')
+            ->setMethods(['getForm', 'addField', 'removeField'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $accountForm = $this->getMockBuilder('Magento\Framework\Data\Form')
+            ->setMethods(['create', 'addFieldset', 'getElement', 'setValues'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $accountForm->expects($this->any())->method('addFieldset')->with('base_fieldset')
+            ->will($this->returnValue($fieldset));
+        $accountForm->expects($this->any())->method('setValues')->will($this->returnValue($accountForm));
+        $fieldset->expects($this->any())->method('getForm')->will($this->returnValue($accountForm));
+        $formElement = $this->getMockBuilder('\Magento\Framework\Data\Form\Element\Select')
+            ->setMethods(['setRenderer', 'addClass', 'setDisabled'])
+            ->disableOriginalConstructor()->getMock();
+
+        $formElement->expects($this->any())->method('setRenderer')->will($this->returnValue(null));
+        $formElement->expects($this->any())->method('addClass')->will($this->returnValue(null));
+        $formElement->expects($this->any())->method('setDisabled')->will($this->returnValue(null));
+        $accountForm->expects($this->any())->method('getElement')->withAnyParameters()
+            ->will($this->returnValue($formElement));
+
+        $fieldset->expects($this->any())->method('addField')->will($this->returnValue($formElement));
+
+        $customerForm = $this->getMock('\Magento\Customer\Model\Metadata\Form', ['getAttributes'], [], '', false);
+        $customerForm->expects($this->any())->method('getAttributes')->will($this->returnValue([]));
+
+        $this->contextMock->expects($this->any())->method('getBackendSession')
+            ->will($this->returnValue($backendSessionMock));
+        $this->contextMock->expects($this->any())->method('getLayout')
+            ->will($this->returnValue($layoutMock));
+        $this->contextMock->expects($this->any())->method('getUrlBuilder')
+            ->will($this->returnValue($urlBuilderMock));
+        $this->contextMock->expects($this->any())->method('getStoreManager')
+            ->will($this->returnValue($storeManagerMock));
+        $this->customerBuilderMock->expects($this->any())->method('populateWithArray')
+            ->will($this->returnValue($this->customerBuilderMock));
+        $this->customerBuilderMock->expects($this->any())->method('create')
+            ->will($this->returnValue($customerObject));
+        $this->customerHelperMock->expects($this->any())->method('getNamePrefixOptions')
+            ->will($this->returnValue(['Pref1', 'Pref2']));
+        $this->customerHelperMock->expects($this->any())->method('getNameSuffixOptions')
+            ->will($this->returnValue(['Suf1', 'Suf2']));
+        $this->formFactoryMock->expects($this->any())->method('create')
+            ->will($this->returnValue($accountForm));
+        $this->customerFormFactoryMock->expects($this->any())->method('create')->with('customer', 'adminhtml_customer')
+            ->will($this->returnValue($customerForm));
+        $this->customerAccountServiceInterfaceMock->expects($this->any())->method('canModify')->withAnyParameters()
+            ->will($this->returnValue($canModifyCustomer));
+        $this->customerAccountServiceInterfaceMock->expects($this->any())->method('getConfirmationStatus')
+            ->withAnyParameters()
+            ->will($this->returnValue(CustomerAccountServiceInterface::ACCOUNT_CONFIRMED));
+    }
+
+    /**
+     * @dataProvider getInitFormData
+     */
+    public function testInitForm($customerData, $isSingleStoreMode, $canModifyCustomer)
+    {
+        $this->_setupStoreMode($customerData, $isSingleStoreMode, $canModifyCustomer);
+        $this->objectManagerHelper->getObject(
+            'Magento\Customer\Block\Adminhtml\Edit\Tab\Account',
+            [
+                'context' => $this->contextMock,
+                'registry' => $this->registryMock,
+                'formFactory' => $this->formFactoryMock,
+                'jsonEncoder' => $this->encoderInterfaceMock,
+                'customerFormFactory' => $this->customerFormFactoryMock,
+                'systemStore' => $this->storeMock,
+                'customerHelper' => $this->customerHelperMock,
+                'customerAccountService' => $this->customerAccountServiceInterfaceMock,
+                'customerMetadataService' => $this->customerMetadataServiceInterfaceMock,
+                'customerBuilder' => $this->customerBuilderMock
+            ]
+        )->initForm();
+    }
+
+    /**
+     * Data provider for method testInitForm
+     * @return array
+     */
+    public function getInitFormData()
+    {
+        return array(
+            array([], true, true),
+            array(['id' => 1], true, true),
+            array([], false, false),
+            array(['id' => 1], false, false),
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Block/Widget/GenderTest.php b/dev/tests/unit/testsuite/Magento/Customer/Block/Widget/GenderTest.php
index 8c3e22c239356b39dc511b3ef12f4ca86635f476..7e0535a694526e6f1cad106825fc68cdd8b02de4 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Block/Widget/GenderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Block/Widget/GenderTest.php
@@ -173,10 +173,12 @@ class GenderTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetCustomer()
     {
-        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        /** @var $customerBuilder \Magento\Customer\Service\V1\Data\CustomerBuilder' */
-        $customerBuilder = $objectManager->getObject('\Magento\Customer\Service\V1\Data\CustomerBuilder');
-        $customerData = $customerBuilder->setFirstname('John')->setLastname('Doe')->create();
+        $data = [
+            'firstname' => 'John', 'lastname' => 'Doe'
+        ];
+        $builder = $this->getMock('\Magento\Customer\Service\V1\Data\CustomerBuilder', [], [], '', false);
+        $builder->expects($this->any())->method('getData')->will($this->returnValue($data));
+        $customerData = new \Magento\Customer\Service\V1\Data\Customer($builder);
 
         $this->_customerSession->expects($this->once())->method('getCustomerId')->will($this->returnValue(1));
         $this->_customerAccountService->expects(
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
index 17fa5328a81e4799648007a199381ae2efd9c309..cc50faf1497384489209b2497047129fc2392a3e 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
@@ -422,10 +422,16 @@ class IndexTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($customerId)
         );
 
-        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        /** @var $customerBuilder \Magento\Customer\Service\V1\Data\CustomerBuilder' */
-        $customerBuilder = $objectManager->getObject('\Magento\Customer\Service\V1\Data\CustomerBuilder');
-        $customer = $customerBuilder->setId($customerId)->setEmail($email)->setWebsiteId($websiteId)->create();
+
+        $customerBuilder = $this->getMock('\Magento\Customer\Service\V1\Data\CustomerBuilder', [], [], '', false);
+        $data = [
+            'id' => $customerId,
+            'email' => $email,
+            'website_id' => $websiteId
+        ];
+        $customerBuilder->expects($this->once())->method('getData')->will($this->returnValue($data));
+
+        $customer = new \Magento\Customer\Service\V1\Data\Customer($customerBuilder);
 
         $this->_acctServiceMock->expects(
             $this->once()
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/MultiselectTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/MultiselectTest.php
index 3eeb87e4086d8f038e4fd8623dbc6b9726294e99..fe2ae2f9c00e684a94d5cc38f4b8babb77888ea2 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/MultiselectTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/MultiselectTest.php
@@ -204,6 +204,8 @@ class MultiselectTest extends AbstractFormTestCase
      */
     protected function runOutputValueTest($value, $expected, $format)
     {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
         $this->attributeMetadataMock->expects(
             $this->any()
         )->method(
@@ -211,8 +213,10 @@ class MultiselectTest extends AbstractFormTestCase
         )->will(
             $this->returnValue(
                 array(
-                    (new OptionBuilder())->setValue('14')->setLabel('fourteen')->create(),
-                    (new OptionBuilder())->setValue('some key')->setLabel('some string')->create()
+                    $helper->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder')
+                        ->setValue('14')->setLabel('fourteen')->create(),
+                    $helper->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder')
+                        ->setValue('some key')->setLabel('some string')->create()
                 )
             )
         );
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/SelectTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/SelectTest.php
index 141741e53238ccbdcebe1f29bf7efbbc1b0091f1..25b072d916a1a71310e70e8dec5588cf445960bb 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/SelectTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/SelectTest.php
@@ -113,6 +113,7 @@ class SelectTest extends AbstractFormTestCase
      */
     public function testOutputValue($value, $expected)
     {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->attributeMetadataMock->expects(
             $this->any()
         )->method(
@@ -120,9 +121,12 @@ class SelectTest extends AbstractFormTestCase
         )->will(
             $this->returnValue(
                 array(
-                    (new OptionBuilder())->setValue('14')->setLabel('fourteen')->create(),
-                    (new OptionBuilder())->setValue('some key')->setLabel('some string')->create(),
-                    (new OptionBuilder())->setValue('true')->setLabel('True')->create()
+                    $helper->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder')
+                        ->setValue('14')->setLabel('fourteen')->create(),
+                    $helper->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder')
+                        ->setValue('some key')->setLabel('some string')->create(),
+                    $helper->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder')
+                        ->setValue('true')->setLabel('True')->create()
                 )
             )
         );
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/TextTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/TextTest.php
index 5c3b8b85ae444dc19ff1add55aff96e875be4a60..b1c90ff6c5c43b86ba5e9a2c8545fb342d7ee922 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/TextTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Metadata/Form/TextTest.php
@@ -124,12 +124,15 @@ class TextTest extends AbstractFormTestCase
      */
     public function testValidateValueLength($value, $expected)
     {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $validationRules = array(
             'min_text_length' => new ValidationRule(
-                (new ValidationRuleBuilder())->populateWithArray(array('name' => 'min_text_length', 'value' => 4))
+                $helper->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder')
+                    ->populateWithArray(array('name' => 'min_text_length', 'value' => 4))
             ),
             'max_text_length' => new ValidationRule(
-                (new ValidationRuleBuilder())->populateWithArray(array('name' => 'max_text_length', 'value' => 8))
+                    $helper->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder')
+                        ->populateWithArray(array('name' => 'max_text_length', 'value' => 8))
             )
         );
 
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php b/dev/tests/unit/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php
index 194e2986bd28c4119c89cb22342704957369e6d4..701739639b2f357b679b32b301eba208285c89b7 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Model/Resource/Group/Grid/ServiceCollectionTest.php
@@ -52,7 +52,7 @@ class ServiceCollectionTest extends \PHPUnit_Framework_TestCase
     public function setUp()
     {
         $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->filterBuilder = new \Magento\Framework\Service\V1\Data\FilterBuilder();
+        $this->filterBuilder = $this->objectManager->getObject('\Magento\Framework\Service\V1\Data\FilterBuilder');
         $filterGroupBuilder = $this->objectManager
             ->getObject('Magento\Framework\Service\V1\Data\Search\FilterGroupBuilder');
         /** @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchBuilder */
@@ -62,7 +62,8 @@ class ServiceCollectionTest extends \PHPUnit_Framework_TestCase
         );
         $this->groupServiceMock = $this->getMockBuilder('\Magento\Customer\Service\V1\CustomerGroupServiceInterface')
             ->getMock();
-        $this->searchResults = (new \Magento\Customer\Service\V1\Data\SearchResultsBuilder())->create();
+        $this->searchResults = $this->objectManager
+            ->getObject('\Magento\Customer\Service\V1\Data\SearchResultsBuilder')->create();
 
         $this->serviceCollection = $this->objectManager
             ->getObject(
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
index fa3934ef73b5ff40bc2ee2c31f85236375b72602..7caf2cbc47538b6c3a33fe60a8da26377e077ba1 100755
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAccountServiceTest.php
@@ -1560,7 +1560,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             );
 
         $customerService = $this->_createService();
-        $filterBuilder = new FilterBuilder();
+        $filterBuilder = $this->_objectManager->getObject('\Magento\Framework\Service\V1\Data\FilterBuilder');
         $filter = $filterBuilder->setField('email')->setValue('customer@search.example.com')->create();
         $this->_searchBuilder->addFilter([$filter]);
 
@@ -1630,7 +1630,7 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
             );
 
         $customerService = $this->_createService();
-        $filterBuilder = new FilterBuilder();
+        $filterBuilder = $this->_objectManager->getObject('\Magento\Framework\Service\V1\Data\FilterBuilder');
         $filter = $filterBuilder->setField('email')->setValue(self::EMAIL)->create();
         $this->_searchBuilder->addFilter([$filter]);
 
@@ -1963,7 +1963,8 @@ class CustomerAccountServiceTest extends \PHPUnit_Framework_TestCase
                 'customerFactory' => $this->_customerFactoryMock,
                 'storeManager' => $this->_storeManagerMock,
                 'converter' => $this->_converter,
-                'searchResultsBuilder' => new Data\SearchResultsBuilder,
+                'searchResultsBuilder' => $this->_objectManager
+                        ->getObject('\Magento\Customer\Service\V1\Data\SearchResultsBuilder'),
                 'customerBuilder' => $this->_customerBuilder,
                 'customerDetailsBuilder' => $this->_customerDetailsBuilder,
                 'customerAddressService' => $this->_customerAddressServiceMock,
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAddressServiceTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAddressServiceTest.php
index fd2485efb6ca3beb7c5b626b0353a2464d45203b..ab041c6ab0b63b26e9d56da6e605a482bcfea8c8 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAddressServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerAddressServiceTest.php
@@ -129,6 +129,11 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
      */
     private $_validator;
 
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $objectManagerHelper;
+
     public function setUp()
     {
         $this->_customerFactoryMock = $this->getMockBuilder(
@@ -227,8 +232,8 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Customer\Model\Metadata\Validator'
         )->disableOriginalConstructor()->getMock();
 
-        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $regionBuilder = $objectManagerHelper->getObject('Magento\Customer\Service\V1\Data\RegionBuilder');
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $regionBuilder = $this->objectManagerHelper->getObject('Magento\Customer\Service\V1\Data\RegionBuilder');
 
         $metadataService = $this->getMockForAbstractClass(
             'Magento\Customer\Service\V1\CustomerMetadataServiceInterface',
@@ -253,12 +258,12 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
             $this->returnValue(array())
         );
 
-        $this->_addressBuilder = $objectManagerHelper->getObject(
+        $this->_addressBuilder = $this->objectManagerHelper->getObject(
             'Magento\Customer\Service\V1\Data\AddressBuilder',
             array('regionBuilder' => $regionBuilder, 'metadataService' => $metadataService)
         );
 
-        $customerBuilder = $objectManagerHelper->getObject(
+        $customerBuilder = $this->objectManagerHelper->getObject(
             'Magento\Customer\Service\V1\Data\CustomerBuilder',
             ['metadataService' => $metadataService]
         );
@@ -483,12 +488,14 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
 
         $customerService = $this->_createService();
 
+
         $this->_addressBuilder->setFirstname(
             'John'
         )->setLastname(
             self::LASTNAME
         )->setRegion(
-            (new Data\RegionBuilder())->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
+            $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                ->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
         )->setStreet(
             array(self::STREET)
         )->setTelephone(
@@ -538,7 +545,8 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
         )->setLastname(
             self::LASTNAME
         )->setRegion(
-            (new RegionBuilder())->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
+                $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                    ->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
         )->setStreet(
             array(self::STREET)
         )->setTelephone(
@@ -608,7 +616,8 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
         )->setLastname(
             self::LASTNAME
         )->setRegion(
-            (new Data\RegionBuilder())->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
+                $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                    ->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
         )->setStreet(
             array(self::STREET)
         )->setTelephone(
@@ -651,7 +660,8 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
         )->setLastname(
             self::LASTNAME
         )->setRegion(
-            (new RegionBuilder())->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
+            $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                ->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
         )->setStreet(
             array(self::STREET)
         )->setTelephone(
@@ -732,7 +742,8 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
         )->setLastname(
             self::LASTNAME
         )->setRegion(
-            (new Data\RegionBuilder())->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
+            $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                ->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
         )->setStreet(
             array(self::STREET)
         )->setTelephone(
@@ -772,7 +783,8 @@ class CustomerAddressServiceTest extends \PHPUnit_Framework_TestCase
         )->setLastname(
             self::LASTNAME
         )->setRegion(
-            (new Data\RegionBuilder())->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
+            $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                ->setRegionId(self::REGION_ID)->setRegion(self::REGION)->create()
         )->setStreet(
             array(self::STREET)
         )->setTelephone(
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
index 402b86858ee7e8312d15d135cf7049da6282ea00..f17609b64b959842326fb04e27be9128c51953fb 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/CustomerMetadataServiceTest.php
@@ -58,6 +58,11 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
     /** @var array */
     private $_validateRules = array();
 
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    private $objectManager;
+
     public function setUp()
     {
         $this->_eavConfigMock = $this->getMockBuilder(
@@ -103,6 +108,8 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
                 'getFrontend' => $frontendMock
             )
         );
+
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
     }
 
     public function testGetAttributeMetadata()
@@ -138,12 +145,13 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Store\Model\StoreManager'
         )->disableOriginalConstructor()->getMock();
 
-        $optionBuilder = new \Magento\Customer\Service\V1\Data\Eav\OptionBuilder();
-        $validationRuleBuilder = new \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder();
+        $optionBuilder = $this->objectManager->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder');
+        $validationRuleBuilder = $this->objectManager
+            ->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder');
 
-        $attributeMetadataBuilder = new \Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder(
-            $optionBuilder,
-            $validationRuleBuilder
+        $attributeMetadataBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            ['optionBuilder' => $optionBuilder, 'validationRuleBuilder' => $validationRuleBuilder]
         );
 
         $service = new CustomerMetadataService(
@@ -177,12 +185,13 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Store\Model\StoreManager'
         )->disableOriginalConstructor()->getMock();
 
-        $optionBuilder = new \Magento\Customer\Service\V1\Data\Eav\OptionBuilder();
-        $validationRuleBuilder = new \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder();
+        $optionBuilder = $this->objectManager->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder');
+        $validationRuleBuilder = $this->objectManager
+            ->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder');
 
-        $attributeMetadataBuilder = new \Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder(
-            $optionBuilder,
-            $validationRuleBuilder
+        $attributeMetadataBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            ['optionBuilder' => $optionBuilder, 'validationRuleBuilder' => $validationRuleBuilder]
         );
 
         $service = new CustomerMetadataService(
@@ -232,12 +241,13 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Store\Model\StoreManager'
         )->disableOriginalConstructor()->getMock();
 
-        $optionBuilder = new \Magento\Customer\Service\V1\Data\Eav\OptionBuilder();
-        $validationRuleBuilder = new \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder();
+        $optionBuilder = $this->objectManager->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder');
+        $validationRuleBuilder = $this->objectManager
+            ->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder');
 
-        $attributeMetadataBuilder = new \Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder(
-            $optionBuilder,
-            $validationRuleBuilder
+        $attributeMetadataBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            ['optionBuilder' => $optionBuilder, 'validationRuleBuilder' => $validationRuleBuilder]
         );
 
         $service = new CustomerMetadataService(
@@ -275,12 +285,13 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Store\Model\StoreManager'
         )->disableOriginalConstructor()->getMock();
 
-        $optionBuilder = new \Magento\Customer\Service\V1\Data\Eav\OptionBuilder();
-        $validationRuleBuilder = new \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder();
+        $optionBuilder = $this->objectManager->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder');
+        $validationRuleBuilder = $this->objectManager
+            ->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder');
 
-        $attributeMetadataBuilder = new \Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder(
-            $optionBuilder,
-            $validationRuleBuilder
+        $attributeMetadataBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            ['optionBuilder' => $optionBuilder, 'validationRuleBuilder' => $validationRuleBuilder]
         );
 
         $service = new CustomerMetadataService(
@@ -310,12 +321,13 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Store\Model\StoreManager'
         )->disableOriginalConstructor()->getMock();
 
-        $optionBuilder = new \Magento\Customer\Service\V1\Data\Eav\OptionBuilder();
-        $validationRuleBuilder = new \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder();
+        $optionBuilder = $this->objectManager->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder');
+        $validationRuleBuilder = $this->objectManager
+            ->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder');
 
-        $attributeMetadataBuilder = new \Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder(
-            $optionBuilder,
-            $validationRuleBuilder
+        $attributeMetadataBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            ['optionBuilder' => $optionBuilder, 'validationRuleBuilder' => $validationRuleBuilder]
         );
 
         $service = new CustomerMetadataService(
@@ -349,12 +361,13 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Store\Model\StoreManager'
         )->disableOriginalConstructor()->getMock();
 
-        $optionBuilder = new \Magento\Customer\Service\V1\Data\Eav\OptionBuilder();
-        $validationRuleBuilder = new \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder();
+        $optionBuilder = $this->objectManager->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder');
+        $validationRuleBuilder = $this->objectManager
+            ->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder');
 
-        $attributeMetadataBuilder = new \Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder(
-            $optionBuilder,
-            $validationRuleBuilder
+        $attributeMetadataBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            ['optionBuilder' => $optionBuilder, 'validationRuleBuilder' => $validationRuleBuilder]
         );
 
         $service = new CustomerMetadataService(
@@ -397,12 +410,13 @@ class CustomerMetadataServiceTest extends \PHPUnit_Framework_TestCase
             '\Magento\Store\Model\StoreManager'
         )->disableOriginalConstructor()->getMock();
 
-        $optionBuilder = new \Magento\Customer\Service\V1\Data\Eav\OptionBuilder();
-        $validationRuleBuilder = new \Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder();
+        $optionBuilder = $this->objectManager->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder');
+        $validationRuleBuilder = $this->objectManager
+            ->getObject('\Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder');
 
-        $attributeMetadataBuilder = new \Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder(
-            $optionBuilder,
-            $validationRuleBuilder
+        $attributeMetadataBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            ['optionBuilder' => $optionBuilder, 'validationRuleBuilder' => $validationRuleBuilder]
         );
 
         $service = new CustomerMetadataService(
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/AddressConverterTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/AddressConverterTest.php
index e19e605ae9859e7cb884963bda0a04431701b86e..fcbabe9023404404de029e866c613fcf1b8e8322 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/AddressConverterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/AddressConverterTest.php
@@ -121,7 +121,7 @@ class AddressConverterTest extends \PHPUnit_Framework_TestCase
             'Magento\Customer\Service\V1\Data\AddressBuilder',
             [
                 'valueBuilder' => $valueBuilder,
-                'regionBuilder' => new RegionBuilder(),
+                'regionBuilder' => $this->_objectManager->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder'),
                 'metadataService' => $this->_customerMetadataService
             ]
         );
@@ -136,7 +136,8 @@ class AddressConverterTest extends \PHPUnit_Framework_TestCase
      */
     protected function _sampleAddressDataObject()
     {
-        $regionBuilder = (new RegionBuilder())->setRegion('Texas')->setRegionId(1)->setRegionCode('TX');
+        $regionBuilder = $this->_objectManager->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+            ->setRegion('Texas')->setRegionId(1)->setRegionCode('TX');
         $valueBuilder = $this->_objectManager->getObject('Magento\Framework\Service\Data\Eav\AttributeValueBuilder');
         /** @var \Magento\Customer\Service\V1\Data\AddressBuilder $addressData */
         $addressData = $this->_objectManager->getObject(
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/AddressTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/AddressTest.php
index 1ddfe1eb67daf744929df4a53cca78e687f5311e..5caf847a8ed7913c6e6129cf37734affe254e712 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/AddressTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/AddressTest.php
@@ -104,8 +104,8 @@ class AddressTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $regionBuilder = $objectManagerHelper->getObject('Magento\Customer\Service\V1\Data\RegionBuilder');
+        $this->objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $regionBuilder = $this->objectManagerHelper->getObject('Magento\Customer\Service\V1\Data\RegionBuilder');
         /** @var \Magento\Customer\Service\V1\CustomerMetadataService $customerMetadataService */
         $this->_customerMetadataService = $this->getMockBuilder(
             'Magento\Customer\Service\V1\CustomerMetadataService'
@@ -124,9 +124,9 @@ class AddressTest extends \PHPUnit_Framework_TestCase
                 )
             )
         );
-        $this->_valueBuilder = $objectManagerHelper
+        $this->_valueBuilder = $this->objectManagerHelper
             ->getObject('Magento\Framework\Service\Data\Eav\AttributeValueBuilder');
-        $this->_addressBuilder = $objectManagerHelper->getObject(
+        $this->_addressBuilder = $this->objectManagerHelper->getObject(
             'Magento\Customer\Service\V1\Data\AddressBuilder',
             [
                 'valueBuilder' => $this->_valueBuilder,
@@ -156,7 +156,8 @@ class AddressTest extends \PHPUnit_Framework_TestCase
                 'getStreet' => $this->_expectedValues['street'],
                 'getCity' => $this->_expectedValues['city'],
                 'getCountryId' => $this->_expectedValues['country_id'],
-                'getRegion' => (new RegionBuilder())->setRegionId(0)->setRegion('Texas')->create(),
+                'getRegion' => $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                        ->setRegionId(0)->setRegion('Texas')->create(),
                 'getPostcode' => $this->_expectedValues['postcode'],
                 'getTelephone' => $this->_expectedValues['telephone']
             )
@@ -225,7 +226,7 @@ class AddressTest extends \PHPUnit_Framework_TestCase
         $addressBuilder->setCity($this->_expectedValues['city']);
         $addressBuilder->setCountryId($this->_expectedValues['country_id']);
         $addressBuilder->setRegion(
-            (new RegionBuilder())->setRegionId(
+            $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')->setRegionId(
                 $this->_expectedValues['region']['region_id']
             )->setRegion(
                 $this->_expectedValues['region']['region']
@@ -264,7 +265,7 @@ class AddressTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->_expectedValues['city'], $address->getCity());
         $this->assertEquals($this->_expectedValues['country_id'], $address->getCountryId());
         $this->assertEquals(
-            (new RegionBuilder())->setRegionId(
+            $this->objectManagerHelper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')->setRegionId(
                 $this->_expectedValues['region']['region_id']
             )->setRegion(
                 $this->_expectedValues['region']['region']
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/CustomerBuilderTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/CustomerBuilderTest.php
index dcd27dadff0b1855e752afb9f972080788cf708b..a6ba8c23725868b2f9f577fec970919e221d3a00 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/CustomerBuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/CustomerBuilderTest.php
@@ -166,7 +166,7 @@ class CustomerBuilderTest extends \PHPUnit_Framework_TestCase
             'Magento\Customer\Service\V1\Data\AddressBuilder',
             [
                 'valueBuilder' => $this->_valueBuilder,
-                'regionBuilder' => new RegionBuilder(),
+                'regionBuilder' => $this->_objectManager->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder'),
                 'metadataService' => $this->_customerMetadataService
             ]
         )->create();
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/CustomerDetailsBuilderTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/CustomerDetailsBuilderTest.php
index 8093aaf4df266ec4132f99546f57d739d283a489..0b5c66166b5cd4ad6ef30a99e65db6d892c3bd14 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/CustomerDetailsBuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/CustomerDetailsBuilderTest.php
@@ -53,6 +53,11 @@ class CustomerDetailsBuilderTest extends \PHPUnit_Framework_TestCase
      */
     protected $_addressMock;
 
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    private $objectManager;
+
     protected function setUp()
     {
         $this->_customerBuilderMock = $this->getMockBuilder(
@@ -67,12 +72,17 @@ class CustomerDetailsBuilderTest extends \PHPUnit_Framework_TestCase
         $this->_addressMock = $this->getMockBuilder(
             '\Magento\Customer\Service\V1\Data\Address'
         )->disableOriginalConstructor()->getMock();
+
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
     }
 
     public function testConstructor()
     {
         $this->_customerBuilderMock->expects($this->once())->method('create')->will($this->returnValue('customer'));
-        $customerDetailsBuilder = new CustomerDetailsBuilder($this->_customerBuilderMock, $this->_addressBuilderMock);
+        $customerDetailsBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\CustomerDetailsBuilder',
+            ['customerBuilder' => $this->_customerBuilderMock, 'addressBuilder' => $this->_addressBuilderMock]
+        );
         $customerDetails = $customerDetailsBuilder->create();
         $this->assertEquals('customer', $customerDetails->getCustomer());
         $this->assertEquals(null, $customerDetails->getAddresses());
@@ -81,7 +91,10 @@ class CustomerDetailsBuilderTest extends \PHPUnit_Framework_TestCase
     public function testSetCustomer()
     {
         $this->_customerBuilderMock->expects($this->never())->method('create')->will($this->returnValue('customer'));
-        $customerDetailsBuilder = new CustomerDetailsBuilder($this->_customerBuilderMock, $this->_addressBuilderMock);
+        $customerDetailsBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\CustomerDetailsBuilder',
+            ['customerBuilder' => $this->_customerBuilderMock, 'addressBuilder' => $this->_addressBuilderMock]
+        );
         $customerDetails = $customerDetailsBuilder->setCustomer($this->_customerMock)->create();
         $this->assertEquals($this->_customerMock, $customerDetails->getCustomer());
         $this->assertEquals(null, $customerDetails->getAddresses());
@@ -90,7 +103,10 @@ class CustomerDetailsBuilderTest extends \PHPUnit_Framework_TestCase
     public function testSetAddresses()
     {
         $this->_customerBuilderMock->expects($this->once())->method('create')->will($this->returnValue('customer'));
-        $customerDetailsBuilder = new CustomerDetailsBuilder($this->_customerBuilderMock, $this->_addressBuilderMock);
+        $customerDetailsBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\CustomerDetailsBuilder',
+            ['customerBuilder' => $this->_customerBuilderMock, 'addressBuilder' => $this->_addressBuilderMock]
+        );
         $customerDetails = $customerDetailsBuilder->setAddresses(
             array($this->_addressMock, $this->_addressMock)
         )->create();
@@ -106,7 +122,6 @@ class CustomerDetailsBuilderTest extends \PHPUnit_Framework_TestCase
      */
     public function testPopulateWithArray($data, $expectedCustomerStr, $expectedAddressesStr)
     {
-
         $expectedCustomer = $expectedCustomerStr == 'customerMock' ? $this->_customerMock : $expectedCustomerStr;
         $expectedAddresses = null;
         if (isset($expectedAddressesStr)) {
@@ -145,7 +160,10 @@ class CustomerDetailsBuilderTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($this->_addressMock)
         );
 
-        $customerDetailsBuilder = new CustomerDetailsBuilder($this->_customerBuilderMock, $this->_addressBuilderMock);
+        $customerDetailsBuilder = $this->objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\CustomerDetailsBuilder',
+            ['customerBuilder' => $this->_customerBuilderMock, 'addressBuilder' => $this->_addressBuilderMock]
+        );
         $customerDetails = $customerDetailsBuilder->populateWithArray($data)->create();
         $this->assertEquals($expectedCustomer, $customerDetails->getCustomer());
         $this->assertEquals($expectedAddresses, $customerDetails->getAddresses());
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataTest.php
index 44ea1b6fdf115db2686e9c6ac3a2c9aa635f244f..716325cba1e064051c671160773214a427e3935b 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/Eav/AttributeMetadataTest.php
@@ -51,10 +51,10 @@ class AttributeMetadataTest extends \PHPUnit_Framework_TestCase
             'Magento\Customer\Service\V1\Data\Eav\ValidationRuleBuilder'
         );
 
-        $attributeMetadataBuilder = (new AttributeMetadataBuilder(
-            $optionBuilder,
-            $validationRuleBuilder
-        ))->populateWithArray(
+        $attributeMetadataBuilder = $objectManager->getObject(
+            '\Magento\Customer\Service\V1\Data\Eav\AttributeMetadataBuilder',
+            ['optionBuilder' => $optionBuilder, 'validationRuleBuilder' => $validationRuleBuilder]
+        )->populateWithArray(
             array(
                 'attribute_code' => self::ATTRIBUTE_CODE,
                 'frontend_input' => self::FRONTEND_INPUT,
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/Eav/OptionTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/Eav/OptionTest.php
index 5f895fe827285735bf492fe249f4fbf42b1d7261..44dd81e8af8fbef95fe9c734fc20a932c9692e60 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/Eav/OptionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/Eav/OptionTest.php
@@ -34,7 +34,9 @@ class OptionTest extends \PHPUnit_Framework_TestCase
 
     public function testConstructorAndGetters()
     {
-        $optionBuilder = (new OptionBuilder())->setLabel(self::LABEL)->setValue(self::VALUE);
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $optionBuilder = $helper->getObject('\Magento\Customer\Service\V1\Data\Eav\OptionBuilder')
+            ->setLabel(self::LABEL)->setValue(self::VALUE);
         $option = new Option($optionBuilder);
         $this->assertSame(self::LABEL, $option->getLabel());
         $this->assertSame(self::VALUE, $option->getValue());
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/RegionTest.php b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/RegionTest.php
index 977d480c0e1b604e3e3fe3de6c8b2bdf49bbee78..ccfeffd627cfdec7ac5e67fb68532342b7bfa75a 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/RegionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Service/V1/Data/RegionTest.php
@@ -32,7 +32,10 @@ class RegionTest extends \PHPUnit_Framework_TestCase
 {
     public function testRegion()
     {
-        $region = new Region((new RegionBuilder())->setRegion('Alabama')->setRegionId(1)->setRegionCode('AL'));
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $region = new Region($helper->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+            ->setRegion('Alabama')->setRegionId(1)->setRegionCode('AL')
+        );
 
         $this->assertEquals(1, $region->getRegionId());
         $this->assertEquals('AL', $region->getRegionCode());
diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Block/Catalog/Product/LinksTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Block/Catalog/Product/LinksTest.php
index 5aee86121e1730634880927bee2c69b9d6ae1891..345e4b87e8f9bde1d3ee2f74dcf87cbb5c2b58e2 100644
--- a/dev/tests/unit/testsuite/Magento/Downloadable/Block/Catalog/Product/LinksTest.php
+++ b/dev/tests/unit/testsuite/Magento/Downloadable/Block/Catalog/Product/LinksTest.php
@@ -43,7 +43,7 @@ class LinksTest extends \PHPUnit_Framework_TestCase
     protected $productMock;
 
     /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfo\Base|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $priceInfoMock;
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9cc26b0518acbdc7fcd1b68f2c555a4c802bb70
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php
@@ -0,0 +1,212 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Action;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class ActionTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Framework\App\Action\ActionFake */
+    protected $action;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_requestMock;
+
+    /**
+     * @var \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_responseMock;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_eventManagerMock;
+
+    /**
+     * @var \Magento\Framework\App\ActionFlag|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_actionFlagMock;
+
+    /**
+     * @var \Magento\Framework\App\Response\RedirectInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_redirectMock;
+
+    /*
+     * Full action name
+     */
+    const FULL_ACTION_NAME = 'module/controller/someaction';
+
+    /**
+     * Route name
+     */
+    const ROUTE_NAME = 'module/controller/actionroute';
+
+    /**
+     * Action name
+     */
+    const ACTION_NAME = 'someaction';
+
+    /**
+     * Controller name
+     */
+    const CONTROLLER_NAME = 'controller';
+
+    /**
+     * Module name
+     */
+    const MODULE_NAME = 'module';
+
+    public static $actionParams = ['param' => 'value'];
+
+    protected function setUp()
+    {
+        $this->_eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface', [], [], '', false);
+        $this->_actionFlagMock = $this->getMock('Magento\Framework\App\ActionFlag', [], [], '', false);
+        $this->_redirectMock = $this->getMock('Magento\Framework\App\Response\RedirectInterface', [], [], '', false);
+        $this->_requestMock = $this->getMock(
+            'Magento\Framework\App\RequestInterface',
+            [
+                'getFullActionName',
+                'getRouteName',
+                'isDispatched',
+                'initForward',
+                'setParams',
+                'setControllerName',
+                'setDispatched',
+                'getModuleName',
+                'setModuleName',
+                'getActionName',
+                'setActionName',
+                'getParam'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->_responseMock = $this->getMock('Magento\Framework\App\ResponseInterface', [], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->action = $this->objectManagerHelper->getObject(
+            'Magento\Framework\App\Action\ActionFake',
+            [
+                'request' => $this->_requestMock,
+                'response' => $this->_responseMock,
+                'eventManager' => $this->_eventManagerMock,
+                'redirect' => $this->_redirectMock,
+                'actionFlag' => $this->_actionFlagMock,
+            ]
+        );
+        \Magento\Framework\Profiler::disable();
+    }
+
+    public function testDispatchPostDispatch()
+    {
+        $this->_requestMock->expects($this->exactly(3))->method('getFullActionName')->will(
+            $this->returnValue(self::FULL_ACTION_NAME)
+        );
+        $this->_requestMock->expects($this->exactly(2))->method('getRouteName')->will(
+            $this->returnValue(self::ROUTE_NAME)
+        );
+        $expectedEventParameters = ['controller_action' => $this->action, 'request' => $this->_requestMock];
+        $this->_eventManagerMock->expects($this->at(0))->method('dispatch')->with(
+            'controller_action_predispatch',
+            $expectedEventParameters
+        );
+        $this->_eventManagerMock->expects($this->at(1))->method('dispatch')->with(
+            'controller_action_predispatch_' . self::ROUTE_NAME,
+            $expectedEventParameters
+        );
+        $this->_eventManagerMock->expects($this->at(2))->method('dispatch')->with(
+            'controller_action_predispatch_' . self::FULL_ACTION_NAME,
+            $expectedEventParameters
+        );
+
+        $this->_requestMock->expects($this->once())->method('isDispatched')->will($this->returnValue(true));
+        $this->_actionFlagMock->expects($this->at(0))->method('get')->with('', Action::FLAG_NO_DISPATCH)->will(
+            $this->returnValue(false)
+        );
+
+        $this->_requestMock->expects($this->once())->method('getActionName')->will(
+            $this->returnValue(self::ACTION_NAME)
+        );
+
+        // _forward expectations
+        $this->_requestMock->expects($this->once())->method('initForward');
+        $this->_requestMock->expects($this->once())->method('setParams')->with(self::$actionParams);
+        $this->_requestMock->expects($this->once())->method('setControllerName')->with(self::CONTROLLER_NAME);
+        $this->_requestMock->expects($this->once())->method('setModuleName')->with(self::MODULE_NAME);
+        $this->_requestMock->expects($this->once())->method('setActionName')->with(self::ACTION_NAME);
+        $this->_requestMock->expects($this->once())->method('setDispatched')->with(false);
+
+        // _redirect expectations
+        $this->_redirectMock->expects($this->once())->method('redirect')->with(
+            $this->_responseMock,
+            self::FULL_ACTION_NAME,
+            self::$actionParams
+        );
+
+        $this->_actionFlagMock->expects($this->at(1))->method('get')->with('', Action::FLAG_NO_POST_DISPATCH)->will(
+            $this->returnValue(false)
+        );
+
+        $this->_eventManagerMock->expects($this->at(3))->method('dispatch')->with(
+            'controller_action_postdispatch_' . self::FULL_ACTION_NAME,
+            $expectedEventParameters
+        );
+        $this->_eventManagerMock->expects($this->at(4))->method('dispatch')->with(
+            'controller_action_postdispatch_' . self::ROUTE_NAME,
+            $expectedEventParameters
+        );
+        $this->_eventManagerMock->expects($this->at(5))->method('dispatch')->with(
+            'controller_action_postdispatch',
+            $expectedEventParameters
+        );
+
+        $this->assertEquals($this->_responseMock, $this->action->dispatch($this->_requestMock));
+    }
+}
+
+class ActionFake extends Action
+{
+    /**
+     * Fake action to check a method call from a parent
+     */
+    public function someactionAction()
+    {
+        $this->_forward(
+            ActionTest::ACTION_NAME,
+            ActionTest::CONTROLLER_NAME,
+            ActionTest::MODULE_NAME,
+            ActionTest::$actionParams);
+        $this->_redirect(ActionTest::FULL_ACTION_NAME, ActionTest::$actionParams);
+        return;
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Cache/TypeListTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Cache/TypeListTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..491fbcf55a439ccc3730178c600e8931c2334bb9
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/Cache/TypeListTest.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\App\Cache;
+
+/**
+ * Test class for \Magento\Framework\App\Cache\TypeList
+ */
+class TypeListTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\Cache\TypeList
+     */
+    protected $_typeList;
+
+    /**
+     * @var \Magento\Framework\App\CacheInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_cache;
+
+    /**
+     * @var array
+     */
+    protected $_typesArray;
+
+    /**
+     * @var \Magento\Framework\Cache\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_config;
+
+    /**
+     * Type key for type list
+     */
+    const TYPE_KEY = 'type';
+
+    /**
+     * Expectation for type cache
+     */
+    const IS_CACHE_ENABLED = true;
+
+    /**
+     * Expected cache type
+     */
+    const CACHE_TYPE = 'Magento\Framework\Cache\FrontendInterface';
+
+    protected function setUp()
+    {
+        $this->_typesArray = [
+            self::TYPE_KEY => [
+                'label' => 'Type Label',
+                'description' => 'Type Description'
+            ]
+        ];
+        $this->_config = $this->getMock(
+            'Magento\Framework\Cache\ConfigInterface',
+            ['getTypes', 'getType'],
+            [],
+            '',
+            false
+        );
+        $this->_config->expects($this->any())->method('getTypes')->will($this->returnValue($this->_typesArray));
+
+        $cacheState = $this->getMock(
+            'Magento\Framework\App\Cache\StateInterface',
+            ['isEnabled', 'setEnabled', 'persist'],
+            [],
+            '',
+            false
+        );
+        $cacheState->expects($this->any())->method('isEnabled')->will($this->returnValue(self::IS_CACHE_ENABLED));
+        $cacheBlockMock = $this->getMock(self::CACHE_TYPE, [], [], '', false);
+        $factory = $this->getMock('Magento\Framework\App\Cache\InstanceFactory', ['get'], [], '', false);
+        $factory->expects($this->any())->method('get')->with(self::CACHE_TYPE)->will(
+            $this->returnValue($cacheBlockMock)
+        );
+        $this->_cache = $this->getMock(
+            'Magento\Framework\App\CacheInterface',
+            ['load', 'getFrontend', 'save', 'remove', 'clean'],
+            [],
+            '',
+            false
+        );
+
+        $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_typeList = $objectHelper->getObject(
+            'Magento\Framework\App\Cache\TypeList',
+            [
+                'config' => $this->_config,
+                'cacheState' => $cacheState,
+                'factory' => $factory,
+                'cache' => $this->_cache
+            ]
+        );
+    }
+
+    public function testGetTypes()
+    {
+        $expectation = [
+            self::TYPE_KEY => $this->_getPreparedType()
+        ];
+        $this->assertEquals($expectation, $this->_typeList->getTypes());
+    }
+
+    public function testGetInvalidated()
+    {
+        $expectation = [self::TYPE_KEY => $this->_getPreparedType()];
+        $this->_cache->expects($this->once())->method('load')->with(TypeList::INVALIDATED_TYPES)->will(
+            $this->returnValue(serialize($this->_typesArray))
+        );
+        $this->assertEquals($expectation, $this->_typeList->getInvalidated());
+    }
+
+    public function testInvalidate()
+    {
+        // there are no invalidated types
+        $this->_cache->expects($this->once())->method('load')->with(TypeList::INVALIDATED_TYPES)->will(
+            $this->returnValue([])
+        );
+        $expectedInvalidated = [
+            self::TYPE_KEY => 1
+        ];
+        $this->_cache->expects($this->once())->method('save')->with(
+            serialize($expectedInvalidated),
+            TypeList::INVALIDATED_TYPES
+        );
+        $this->_typeList->invalidate(self::TYPE_KEY);
+    }
+
+    public function testInvalidateList()
+    {
+        $this->_cache->expects($this->once())->method('load')->with(TypeList::INVALIDATED_TYPES)->will(
+            $this->returnValue([])
+        );
+        $expectedInvalidated = [
+            self::TYPE_KEY => 1
+        ];
+        $this->_cache->expects($this->once())->method('save')->with(
+            serialize($expectedInvalidated),
+            TypeList::INVALIDATED_TYPES
+        );
+        $this->_typeList->invalidate([self::TYPE_KEY]);
+    }
+
+    public function testCleanType()
+    {
+        $this->_cache->expects($this->once())->method('load')->with(TypeList::INVALIDATED_TYPES)->will(
+            $this->returnValue(serialize($this->_typesArray))
+        );
+        $this->_config->expects($this->once())->method('getType')->with(self::TYPE_KEY)->will(
+            $this->returnValue(['instance' => self::CACHE_TYPE])
+        );
+        unset($this->_typesArray[self::TYPE_KEY]);
+        $this->_cache->expects($this->once())->method('save')->with(
+            serialize($this->_typesArray),
+            TypeList::INVALIDATED_TYPES
+        );
+        $this->_typeList->cleanType(self::TYPE_KEY);
+    }
+
+    /**
+     * Returns prepared type
+     *
+     * @return \Magento\Framework\Object
+     */
+    private function _getPreparedType()
+    {
+        return new \Magento\Framework\Object(
+            [
+                'id' => self::TYPE_KEY,
+                'cache_type' => $this->_typesArray[self::TYPE_KEY]['label'],
+                'description' => $this->_typesArray[self::TYPE_KEY]['description'],
+                'tags' => '',
+                'status' => self::IS_CACHE_ENABLED
+            ]
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Config/Initial/ReaderTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Config/Initial/ReaderTest.php
index d9d0df301e93bf55594ec54b826098193d851ee2..50752518f771565ab363e49ceb5016cc182f94a2 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/Config/Initial/ReaderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/Config/Initial/ReaderTest.php
@@ -92,17 +92,6 @@ class ReaderTest extends \PHPUnit_Framework_TestCase
             $this->at(0)
         )->method(
             'get'
-        )->with(
-            'config.xml',
-            'primary'
-        )->will(
-            $this->returnValue(array())
-        );
-
-        $this->_fileResolverMock->expects(
-            $this->at(1)
-        )->method(
-            'get'
         )->with(
             'config.xml',
             'global'
@@ -128,17 +117,6 @@ class ReaderTest extends \PHPUnit_Framework_TestCase
             $this->at(0)
         )->method(
             'get'
-        )->with(
-            'config.xml',
-            'primary'
-        )->will(
-            $this->returnValue(array())
-        );
-
-        $this->_fileResolverMock->expects(
-            $this->at(1)
-        )->method(
-            'get'
         )->with(
             'config.xml',
             'global'
diff --git a/dev/tests/unit/testsuite/Magento/Framework/ArchiveTest.php b/dev/tests/unit/testsuite/Magento/Framework/ArchiveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b45838ec361605ce8fe30abccb16b3d1c3b0b6d3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/ArchiveTest.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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;
+
+class ArchiveTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Archive
+     */
+    protected $archive;
+
+    /**
+     * @var string
+     */
+    protected $sourceFilePath;
+
+    /**
+     * @var string
+     */
+    protected $destinationDir;
+
+    /**
+     * @var string
+     */
+    protected $packed;
+
+    /**
+     * @var string
+     */
+    protected $unpacked;
+
+    protected function setUp()
+    {
+        $this->archive = new Archive();
+        $this->sourceFilePath = __DIR__ . '/_files/Archive/source.txt';
+        $this->destinationDir = __DIR__ . '/_files/Archive/archives/';
+    }
+
+    protected function tearDown()
+    {
+        if (!empty($this->packed) && file_exists($this->packed)) {
+            unlink($this->packed);
+            $this->packed = null;
+        }
+        if (!empty($this->unpacked) && file_exists($this->unpacked)) {
+            unlink($this->unpacked);
+            $this->unpacked = null;
+        }
+    }
+
+    /**
+     * @dataProvider isArchiveProvider
+     * @param string $file
+     * @param bool $isArchive
+     */
+    public function testIsArchive($file, $isArchive)
+    {
+        $this->assertEquals($isArchive, $this->archive->isArchive($file));
+    }
+
+    public function isArchiveProvider()
+    {
+        return [
+            ['archive.tar', true],
+            ['archive.gz', true],
+            ['archive.gzip', true],
+            ['archive.tgz', true],
+            ['archive.tgzip', true],
+            ['archive.bz', true],
+            ['archive.bzip', true],
+            ['archive.bzip2', true],
+            ['archive.bz2', true],
+            ['archive.tbz', true],
+            ['archive.tbzip', true],
+            ['archive.tbz2', true],
+            ['archive.tbzip2', true],
+            ['archive.txt', false],
+            ['archive.php', false],
+            ['archive.phtml', false],
+            ['archive.js', false],
+            ['archive.log', false],
+        ];
+    }
+
+    /**
+     * @dataProvider isTarProvider
+     * @param string $file
+     * @param bool $isArchive
+     */
+    public function testIsTar($file, $isArchive)
+    {
+        $this->assertEquals($isArchive, $this->archive->isTar($file));
+    }
+
+    public function isTarProvider()
+    {
+        return [
+            ['archive.tar', true],
+            ['archive.gz', false],
+            ['archive.gzip', false],
+            ['archive.tgz', false],
+            ['archive.tgzip', false],
+            ['archive.bz', false],
+            ['archive.bzip', false],
+            ['archive.bzip2', false],
+            ['archive.bz2', false],
+            ['archive.tbz', false],
+            ['archive.tbzip', false],
+            ['archive.tbz2', false],
+            ['archive.tbzip2', false],
+            ['archive.txt', false],
+            ['archive.php', false],
+            ['archive.phtml', false],
+            ['archive.js', false],
+            ['archive.log', false],
+        ];
+    }
+
+    /**
+     * @dataProvider destinationProvider
+     * @param string $destinationFile
+     */
+    public function testPackUnpackGzBz($destinationFile)
+    {
+        $this->packed = $this->archive->pack($this->sourceFilePath, $this->destinationDir . $destinationFile);
+
+        $this->assertFileExists($this->packed);
+        $this->assertEquals($this->destinationDir . $destinationFile, $this->packed);
+
+        $this->unpacked = $this->archive->unpack($this->packed, $this->destinationDir);
+
+        $this->assertFileExists($this->unpacked);
+        $this->assertStringStartsWith($this->destinationDir, $this->unpacked);
+    }
+
+    public function destinationProvider()
+    {
+        return [
+            ['archive.gz', false],
+            ['archive.gzip', false],
+            ['archive.bz', false],
+            ['archive.bzip', false],
+            ['archive.bzip2', false],
+            ['archive.bz2', false]
+        ];
+    }
+
+    /**
+     * @dataProvider tarProvider
+     * @param string $destinationFile
+     */
+    public function testPackUnpackTar($destinationFile)
+    {
+        $this->packed = $this->archive->pack($this->sourceFilePath, $this->destinationDir . $destinationFile);
+
+        $this->assertFileExists($this->packed);
+        $this->assertEquals($this->destinationDir . $destinationFile, $this->packed);
+
+        $unpacked = $this->archive->unpack($this->packed, $this->destinationDir);
+
+        $this->unpacked = $unpacked . pathinfo($this->sourceFilePath, PATHINFO_BASENAME);
+
+        $this->assertFileExists($this->unpacked);
+        $this->assertStringStartsWith($this->destinationDir, $this->unpacked);
+    }
+
+    /**
+     * @dataProvider tarProvider
+     * @param string $destinationFile
+     */
+    public function testExtract($destinationFile)
+    {
+        $this->packed = $this->archive->pack($this->sourceFilePath, $this->destinationDir . $destinationFile);
+
+        $this->assertFileExists($this->packed);
+        $this->assertEquals($this->destinationDir . $destinationFile, $this->packed);
+
+        $filename = pathinfo($this->sourceFilePath, PATHINFO_BASENAME);
+        $this->unpacked = $this->archive->extract($filename, $this->packed, $this->destinationDir);
+
+        $this->assertFileExists($this->unpacked);
+        $this->assertStringStartsWith($this->destinationDir, $this->unpacked);
+    }
+
+    public function tarProvider()
+    {
+        return [
+            ['archive.tar', true],
+            ['archive.tgz', false],
+            ['archive.tgzip', false],
+            ['archive.tbz', false],
+            ['archive.tbzip', false],
+            ['archive.tbz2', false],
+            ['archive.tbzip2', false]
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Backup/MediaTest.php b/dev/tests/unit/testsuite/Magento/Framework/Backup/MediaTest.php
index a9cc92909c773997103047f1ebfce051afa35bc3..442cc1e875da52f718970c7b7657d6f18f635683 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Backup/MediaTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Backup/MediaTest.php
@@ -23,8 +23,6 @@
  */
 namespace Magento\Framework\Backup;
 
-require_once __DIR__ . '/_files/Gz.php';
-require_once __DIR__ . '/_files/Tar.php';
 require_once __DIR__ . '/_files/Fs.php';
 require_once __DIR__ . '/_files/Helper.php';
 require_once __DIR__ . '/_files/io.php';
@@ -90,18 +88,26 @@ class MediaTest extends \PHPUnit_Framework_TestCase
 
         $model = new \Magento\Framework\Backup\Media($this->_filesystemMock, $this->_backupFactoryMock);
         $model->setRootDir($rootDir);
+        $model->setBackupsDir($rootDir);
         $model->{$action}();
         $this->assertTrue($model->getIsSuccess());
 
         $this->assertTrue($model->{$action}());
 
-        $paths = $model->getIgnorePaths();
-        $path1 = str_replace('\\', '/', $paths[0]);
-        $path2 = str_replace('\\', '/', $paths[1]);
+        $ignorePaths = $model->getIgnorePaths();
+
         $rootDir = str_replace('\\', '/', $rootDir);
 
-        $this->assertEquals($rootDir . '/code', $path1);
-        $this->assertEquals($rootDir . '/var/log', $path2);
+        foreach ($ignorePaths as &$path) {
+            if (strpos($path, '~tmp-') || strpos($path, '_media')) {
+                unlink($path);
+            }
+            $path = str_replace('\\', '/', $path);
+        }
+
+        $this->assertTrue(in_array($rootDir, $ignorePaths));
+        $this->assertTrue(in_array($rootDir . '/code', $ignorePaths));
+        $this->assertTrue(in_array($rootDir . '/var/log', $ignorePaths));
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Backup/NomediaTest.php b/dev/tests/unit/testsuite/Magento/Framework/Backup/NomediaTest.php
index 1525d0ca2e001aab8bf0ccbae5a35ab75ac58b58..6ba27c2e09dddd20e23e1ae0126d11db041438f8 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Backup/NomediaTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Backup/NomediaTest.php
@@ -23,8 +23,6 @@
  */
 namespace Magento\Framework\Backup;
 
-require_once __DIR__ . '/_files/Gz.php';
-require_once __DIR__ . '/_files/Tar.php';
 require_once __DIR__ . '/_files/Fs.php';
 require_once __DIR__ . '/_files/Helper.php';
 require_once __DIR__ . '/_files/io.php';
@@ -90,10 +88,11 @@ class NomediaTest extends \PHPUnit_Framework_TestCase
 
         $model = new \Magento\Framework\Backup\Nomedia($this->_filesystemMock, $this->_backupFactoryMock);
         $model->setRootDir($rootDir);
+        $model->setBackupsDir($rootDir);
         $model->{$action}();
         $this->assertTrue($model->getIsSuccess());
 
-        $this->assertEquals(array($rootDir . '/media', $rootDir . '/pub/media'), $model->getIgnorePaths());
+        $this->assertEquals(array($rootDir, $rootDir . '/media', $rootDir . '/pub/media'), $model->getIgnorePaths());
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Backup/_files/data/.gitignore b/dev/tests/unit/testsuite/Magento/Framework/Backup/_files/data/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..22e83649f7d5219bb31ce45bd7e986e57ea4e72e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Backup/_files/data/.gitignore
@@ -0,0 +1 @@
+/*
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Code/ValidatorTest.php b/dev/tests/unit/testsuite/Magento/Framework/Code/ValidatorTest.php
index e283eb92a783c1f13d2644d6588dc035e05dad43..78fecfe607a0364527517053ffe6711f9611d13c 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Code/ValidatorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Code/ValidatorTest.php
@@ -18,9 +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.
  *
- * @category    Magento
- * @package     Magento_Code
- * @subpackage  unit_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)
  */
diff --git a/dev/tests/unit/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php b/dev/tests/unit/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php
index fd8544aaec17c49b1fe1f3f9e168f4496095dc75..2294b08e31a4c48f77f2b5684a3d791b5380136b 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/DB/Adapter/Pdo/MysqlTest.php
@@ -67,7 +67,16 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
 
         $this->_adapter = $this->getMock(
             'Magento\Framework\DB\Adapter\Pdo\Mysql',
-            array('_connect', '_beginTransaction', '_commit', '_rollBack', 'query', '_debugWriteToFile', 'fetchRow'),
+            array(
+                'getCreateTable',
+                '_connect',
+                '_beginTransaction',
+                '_commit',
+                '_rollBack',
+                'query',
+                '_debugWriteToFile',
+                'fetchRow'
+            ),
             array(
                 'dbname' => 'not_exists',
                 'username' => 'not_valid',
@@ -529,4 +538,88 @@ class MysqlTest extends \PHPUnit_Framework_TestCase
             )
         );
     }
+
+    /**
+     * @dataProvider getForeignKeysProvider
+     * @param string $tableName
+     * @param string $schemaName
+     * @param string $constraint
+     * @param array $expected
+     */
+    public function testGetForeignKeys($tableName, $schemaName, $constraint, $expected)
+    {
+        $constraint = ",\n" . $constraint;
+        $this->_adapter->expects($this->once())
+            ->method('getCreateTable')
+            ->will($this->returnValue($constraint));
+        $this->assertEquals($expected, $this->_adapter->getForeignKeys($tableName, $schemaName));
+    }
+
+    public function getForeignKeysProvider()
+    {
+        return [
+            [
+                'table1',
+                'schema1',
+                'CONSTRAINT `FK_SALES_FLAT_ORDER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID` FOREIGN KEY '
+                . '(`customer_id`) REFERENCES `customer_entity` (`entity_id`) ON DELETE SET NULL ON UPDATE CASCADE',
+                [
+                    'FK_SALES_FLAT_ORDER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID' => [
+                        'FK_NAME'           => 'FK_SALES_FLAT_ORDER_CUSTOMER_ID_CUSTOMER_ENTITY_ENTITY_ID',
+                        'SCHEMA_NAME'       => 'schema1',
+                        'TABLE_NAME'        => 'table1',
+                        'COLUMN_NAME'       => 'customer_id',
+                        'REF_SHEMA_NAME'    => '',
+                        'REF_TABLE_NAME'    => 'customer_entity',
+                        'REF_COLUMN_NAME'   => 'entity_id',
+                        'ON_DELETE'         => 'SET NULL',
+                        'ON_UPDATE'         => 'CASCADE'
+                    ]
+                ]
+            ],
+            [
+                'table1',
+                'schema1',
+                'CONSTRAINT `FK_SALES_FLAT_ORDER_STORE_ID_STORE_STORE_ID` FOREIGN KEY (`store_id`) '
+                . 'REFERENCES `store` (`store_id`) ON DELETE SET NULL ON UPDATE CASCADE',
+                [
+                    'FK_SALES_FLAT_ORDER_STORE_ID_STORE_STORE_ID' => [
+                        'FK_NAME'           => 'FK_SALES_FLAT_ORDER_STORE_ID_STORE_STORE_ID',
+                        'SCHEMA_NAME'       => 'schema1',
+                        'TABLE_NAME'        => 'table1',
+                        'COLUMN_NAME'       => 'store_id',
+                        'REF_SHEMA_NAME'    => '',
+                        'REF_TABLE_NAME'    => 'store',
+                        'REF_COLUMN_NAME'   => 'store_id',
+                        'ON_DELETE'         => 'SET NULL',
+                        'ON_UPDATE'         => 'CASCADE'
+                    ]
+                ]
+            ],
+            [
+                'table1',
+                'schema1',
+                '`entity_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT \'Entity Id\'',
+                []
+            ],
+            [
+                'table1',
+                'schema1',
+                'CONSTRAINT `refdata_ibfk_1` FOREIGN KEY (`refcol`) REFERENCES `test_ref`.`usefuldata` (`col`)',
+                [
+                    'REFDATA_IBFK_1' => [
+                        'FK_NAME'           => 'refdata_ibfk_1',
+                        'SCHEMA_NAME'       => 'schema1',
+                        'TABLE_NAME'        => 'table1',
+                        'COLUMN_NAME'       => 'refcol',
+                        'REF_SHEMA_NAME'    => 'test_ref',
+                        'REF_TABLE_NAME'    => 'usefuldata',
+                        'REF_COLUMN_NAME'   => 'col',
+                        'ON_DELETE'         => '',
+                        'ON_UPDATE'         => ''
+                    ]
+                ]
+            ],
+        ];
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/EscaperTest.php b/dev/tests/unit/testsuite/Magento/Framework/EscaperTest.php
index e5ceeb33edb5000e18d9ae0772f292691a3da992..ae928e68db32b102f3ccd0b6a5f40a34b7ce7b95 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/EscaperTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/EscaperTest.php
@@ -42,9 +42,9 @@ class EscaperTest extends \PHPUnit_Framework_TestCase
      * @covers \Magento\Framework\Escaper::escapeHtml
      * @dataProvider escapeHtmlDataProvider
      */
-    public function testEscapeHtml($data, $expected)
+    public function testEscapeHtml($data, $expected, $allowedTags = null)
     {
-        $actual = $this->_escaper->escapeHtml($data);
+        $actual = $this->_escaper->escapeHtml($data, $allowedTags);
         $this->assertEquals($expected, $actual);
     }
 
@@ -53,17 +53,24 @@ class EscaperTest extends \PHPUnit_Framework_TestCase
      */
     public function escapeHtmlDataProvider()
     {
-        return array(
-            'array data' => array(
-                'data' => array('one', '<two>three</two>'),
-                'expected' => array('one', '&lt;two&gt;three&lt;/two&gt;')
-            ),
-            'string data conversion' => array(
+        return [
+            'array data' => [
+                'data' => ['one', '<two>three</two>'],
+                'expected' => ['one', '&lt;two&gt;three&lt;/two&gt;'],
+                null
+            ],
+            'string data conversion' => [
                 'data' => '<two>three</two>',
-                'expected' => '&lt;two&gt;three&lt;/two&gt;'
-            ),
-            'string data no conversion' => array('data' => 'one', 'expected' => 'one')
-        );
+                'expected' => '&lt;two&gt;three&lt;/two&gt;',
+                null
+            ],
+            'string data no conversion' => ['data' => 'one', 'expected' => 'one'],
+            'string data with allowed tags' => [
+                'data' => '<span><b>some text in tags</b></span>',
+                'expected' => '<span><b>some text in tags</b></span>',
+                'allowedTags' => ['span', 'b']
+            ]
+        ];
     }
 
     /**
@@ -82,8 +89,8 @@ class EscaperTest extends \PHPUnit_Framework_TestCase
      */
     public function testEscapeJsQuote()
     {
-        $data = array("Don't do that.", 'lost_key' => "Can't do that.");
-        $expected = array("Don\\'t do that.", "Can\\'t do that.");
+        $data = ["Don't do that.", 'lost_key' => "Can't do that."];
+        $expected = ["Don\\'t do that.", "Can\\'t do that."];
         $this->assertEquals($expected, $this->_escaper->escapeJsQuote($data));
         $this->assertEquals($expected[0], $this->_escaper->escapeJsQuote($data[0]));
     }
@@ -94,10 +101,10 @@ class EscaperTest extends \PHPUnit_Framework_TestCase
     public function testEscapeQuote()
     {
         $data = "Text with 'single' and \"double\" quotes";
-        $expected = array(
+        $expected = [
             "Text with &#039;single&#039; and &quot;double&quot; quotes",
             "Text with \\&#039;single\\&#039; and \\&quot;double\\&quot; quotes"
-        );
+        ];
         $this->assertEquals($expected[0], $this->_escaper->escapeQuote($data));
         $this->assertEquals($expected[1], $this->_escaper->escapeQuote($data, true));
     }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/EventTest.php b/dev/tests/unit/testsuite/Magento/Framework/EventTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b58facf4211e331d1c2b32ea61a8759747ebd85f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/EventTest.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework;
+
+use Magento\Framework\Event\Observer\Collection;
+use Magento\Framework\Event\Observer;
+
+/**
+ * Class Event
+ *
+ * @package Magento\Framework
+ */
+class EventTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Event
+     */
+    protected $event;
+
+    /**
+     * @var Collection
+     */
+    protected $observers;
+
+    /**
+     * @var \Magento\Framework\Event\Observer
+     */
+    protected $observer;
+
+    public function setUp()
+    {
+        $data = [
+            'name' => 'ObserverName',
+            'block' => 'testBlockName'
+        ];
+        $this->event = new Event($data);
+        $this->observers = new Collection();
+        $this->observer = new Observer($data);
+        $this->observers->addObserver($this->observer);
+    }
+
+    protected function tearDown()
+    {
+        unset($this->event);
+    }
+
+    public function testGetObservers()
+    {
+        $this->event->addObserver($this->observer);
+        $expected = $this->observers;
+        $result = $this->event->getObservers();
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testAddObservers()
+    {
+        $data = ['name' => 'Add New Observer'];
+        $observer = new Observer($data);
+        $this->event->addObserver($observer);
+        $actual = $this->event->getObservers()->getObserverByName($data['name']);
+        $this->assertSame($observer, $actual);
+    }
+
+    public function testRemoveObserverByName()
+    {
+        $data = [
+            'name' => 'ObserverName',
+        ];
+        $this->event->addObserver($this->observer);
+        $expected = 'Magento\Framework\Event\Observer\Collection';
+        $actual = $this->event->getObservers()->removeObserverByName($data['name']);
+        $this->assertInstanceOf($expected, $actual);
+    }
+
+    public function testDispatch()
+    {
+        $this->assertInstanceOf('Magento\Framework\Event', $this->event->dispatch());
+    }
+
+    public function testGetName()
+    {
+        $data = 'ObserverName';
+        $this->assertEquals($data, $this->event->getName());
+        $this->event = new Event();
+        $this->assertNull($this->event->getName());
+    }
+
+    public function testGetBlock()
+    {
+        $block = 'testBlockName';
+        $this->assertEquals($block, $this->event->getBlock());
+    }
+} 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/FlagTest.php b/dev/tests/unit/testsuite/Magento/Framework/FlagTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b05138a5148d63255a806bb6118d77a4b7153937
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/FlagTest.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\Framework;
+
+/**
+ * Class FlagTest
+ *
+ * @package Magento\Framework
+ */
+class FlagTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Flag
+     */
+    protected $flag;
+
+    public function setUp()
+    {
+        $data = ['flag_code' => 'synchronize'];
+        $this->createInstance($data);
+    }
+
+    protected function createInstance(array $data = [])
+    {
+        $eventManager = $this->getMock('Magento\Framework\Event\Manager', ['dispatch'], [], '', false, false);
+        $context = $this->getMock('Magento\Framework\Model\Context', [], [], '', false, false);
+        $context->expects($this->once())
+            ->method('getEventDispatcher')
+            ->will($this->returnValue($eventManager));
+        $registry = $this->getMock('Magento\Framework\Registry', [], [], '', false, false);
+
+        $adapter = $this->getMock('Magento\Framework\DB\Adapter\Adapter', ['beginTransaction'], [], '', false, false);
+        $adapter->expects($this->any())
+            ->method('beginTransaction')
+            ->will($this->returnSelf());
+        $appResource = $this->getMock(
+            'Magento\Framework\App\Resource',
+            ['beginTransaction', 'getConnection'],
+            [],
+            '',
+            false,
+            false
+        );
+        $appResource->expects($this->any())
+            ->method('getConnection')
+            ->will($this->returnValue($adapter));
+
+        $resource = $this->getMockBuilder('Magento\Framework\Flag\Resource')
+            ->setMethods(['__wakeup', 'load', 'save', 'addCommitCallback', 'commit', 'rollBack'])
+            ->setConstructorArgs(['resource' => $appResource])
+            ->getMockForAbstractClass();
+        $resource->expects($this->any())
+            ->method('addCommitCallback')
+            ->will($this->returnSelf());
+
+        $resourceCollection = $this->getMock('Magento\Framework\Data\Collection\Db', [], [], '', false, false);
+
+
+        $this->flag = new \Magento\Framework\Flag(
+            $context,
+            $registry,
+            $resource,
+            $resourceCollection,
+            $data
+        );
+    }
+
+    public function tearDown()
+    {
+        unset($this->flag);
+    }
+
+    public function testConstruct()
+    {
+        $flagCode = 'synchronize';
+        $this->createInstance();
+        $this->flag->setFlagCode('synchronize');
+        $this->assertEquals($flagCode, $this->flag->getFlagCode());
+    }
+
+    public function testGetFlagData()
+    {
+        $result = $this->flag->getFlagData();
+        $this->assertNull($result);
+        $flagData = serialize('data');
+        $this->flag->setData('flag_data', $flagData);
+        $result = $this->flag->getFlagData();
+        $this->assertEquals(unserialize($flagData), $result);
+    }
+
+    public function testSetFlagData()
+    {
+        $flagData = 'data';
+        $this->flag->setFlagData($flagData);
+        $result = unserialize($this->flag->getData('flag_data'));
+        $this->assertEquals($flagData, $result);
+    }
+
+    public function testLoadSelf()
+    {
+        $this->assertInstanceOf('Magento\Framework\Flag', $this->flag->loadSelf());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage Please define flag code.
+     */
+    public function testLoadSelfException()
+    {
+        $this->createInstance();
+        $this->flag->loadSelf();
+    }
+
+    public function testBeforeSave()
+    {
+        $this->flag->setData('block', 'blockNmae');
+        $result = $this->flag->save();
+        $this->assertSame($this->flag, $result);
+        $this->assertEquals('synchronize', $this->flag->getFlagCode());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage Please define flag code.
+     */
+    public function testBeforeSaveException()
+    {
+        $this->createInstance();
+        $this->flag->setData('block', 'blockNmae');
+        $this->flag->save();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Less/PreProcessor/Instruction/ImportTest.php b/dev/tests/unit/testsuite/Magento/Framework/Less/PreProcessor/Instruction/ImportTest.php
index be53920108c6fd6ad86e7b31e3f5951cb29b3345..0b265415178596f72344e379efe2285190a23be1 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Less/PreProcessor/Instruction/ImportTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Less/PreProcessor/Instruction/ImportTest.php
@@ -124,7 +124,7 @@ class ImportTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @covers resetRelatedFiles
+     * @covers \Magento\Framework\Less\PreProcessor\Instruction\Import::resetRelatedFiles
      */
     public function testGetRelatedFiles()
     {
diff --git a/dev/tests/unit/testsuite/Magento/Framework/LoggerTest.php b/dev/tests/unit/testsuite/Magento/Framework/LoggerTest.php
index ec47ad479369015a045fc93d391d77b9667c09f8..76509bb84a0edac41b2926a29f91ff90a90703f9 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/LoggerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/LoggerTest.php
@@ -30,39 +30,34 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_model = null;
+    protected $model = null;
 
     /**
      * @var \ReflectionProperty
      */
-    protected $_loggersProperty = null;
+    protected $loggersProperty = null;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_filesystemMock;
+    protected $filesystemMock;
 
     /**
      * @var Write | \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_directory;
+    protected $directory;
 
     protected function setUp()
     {
         $logDir = TESTS_TEMP_DIR . '/var/log';
-        $this->_filesystemMock = $this->getMock('Magento\Framework\App\Filesystem', array(), array(), '', false);
-        $this->_directory = $this->getMock('Magento\Framework\Filesystem\Directory\Write', array(), array(), '', false);
-        $this->_filesystemMock->expects(
-            $this->any()
-        )->method(
-                'getDirectoryWrite'
-            )->with(
-                \Magento\Framework\App\Filesystem::LOG_DIR
-            )->will(
-                $this->returnValue($this->_directory)
-            );
-        $this->_directory->expects($this->any())->method('create')->will($this->returnValue(true));
-        $this->_directory->expects($this->any())->method('getAbsolutePath')->will(
+        $this->filesystemMock = $this->getMock('Magento\Framework\App\Filesystem', [], [], '', false);
+        $this->directory = $this->getMock('Magento\Framework\Filesystem\Directory\Write', [], [], '', false);
+        $this->filesystemMock->expects($this->any())
+            ->method('getDirectoryWrite')
+            ->with(\Magento\Framework\App\Filesystem::LOG_DIR)
+            ->will($this->returnValue($this->directory));
+        $this->directory->expects($this->any())->method('create')->will($this->returnValue(true));
+        $this->directory->expects($this->any())->method('getAbsolutePath')->will(
             $this->returnCallback(
                 function ($path) use ($logDir) {
                     $path = ltrim($path, '\/');
@@ -75,9 +70,9 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
             mkdir($logDir, 0777, true);
         }
 
-        $this->_model = new \Magento\Framework\Logger($this->_filesystemMock);
-        $this->_loggersProperty = new \ReflectionProperty($this->_model, '_loggers');
-        $this->_loggersProperty->setAccessible(true);
+        $this->model = new \Magento\Framework\Logger($this->filesystemMock);
+        $this->loggersProperty = new \ReflectionProperty($this->model, '_loggers');
+        $this->loggersProperty->setAccessible(true);
     }
 
     /**
@@ -87,11 +82,11 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
      */
     public function testAddStreamLog($key, $fileOrWrapper)
     {
-        $this->assertFalse($this->_model->hasLog($key));
-        $this->_model->addStreamLog($key, $fileOrWrapper);
-        $this->assertTrue($this->_model->hasLog($key));
+        $this->assertFalse($this->model->hasLog($key));
+        $this->model->addStreamLog($key, $fileOrWrapper);
+        $this->assertTrue($this->model->hasLog($key));
 
-        $loggers = $this->_loggersProperty->getValue($this->_model);
+        $loggers = $this->loggersProperty->getValue($this->model);
         $this->assertArrayHasKey($key, $loggers);
         $zendLog = $loggers[$key];
         $this->assertInstanceOf('Zend_Log', $zendLog);
@@ -115,7 +110,7 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
      */
     public function addStreamLogDataProvider()
     {
-        return array(array('test', 'php://output'), array('test', 'custom_file.log'), array('test', ''));
+        return [['test', 'php://output'], ['test', 'custom_file.log'], ['test', '']];
     }
 
     /**
@@ -124,8 +119,8 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
     public function testAddLogWithSpecificKey()
     {
         $key = uniqid();
-        $this->_model->addStreamLog($key);
-        $this->assertTrue($this->_model->hasLog($key));
+        $this->model->addStreamLog($key);
+        $this->assertTrue($this->model->hasLog($key));
     }
 
     public function testLog()
@@ -136,33 +131,39 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
         $this->expectOutputRegex(
             '/' . 'DEBUG \(7\).+?' . $messageTwo . '.+?' . 'CRIT \(2\).+?' . $messageThree . '/s'
         );
-        $this->_model->addStreamLog('test', 'php://output');
-        $this->_model->log($messageOne);
-        $this->_model->log($messageTwo, \Zend_Log::DEBUG, 'test');
-        $this->_model->log($messageThree, \Zend_Log::CRIT, 'test');
+        $this->model->addStreamLog('test', 'php://output');
+        $this->model->log($messageOne);
+        $this->model->log($messageTwo, \Zend_Log::DEBUG, 'test');
+        $this->model->log($messageThree, \Zend_Log::CRIT, 'test');
     }
 
     public function testLogComplex()
     {
         $this->expectOutputRegex('/Array\s\(\s+\[0\] => 1\s\).+stdClass Object/s');
-        $this->_model->addStreamLog(\Magento\Framework\Logger::LOGGER_SYSTEM, 'php://output');
-        $this->_model->log(array(1));
-        $this->_model->log(new \StdClass());
+        $this->model->addStreamLog(\Magento\Framework\Logger::LOGGER_SYSTEM, 'php://output');
+        $this->model->log([1]);
+        $this->model->log(new \StdClass());
+        $this->model->log('key');
+    }
+
+    public function testLogNoKey()
+    {
+        $key = 'key';
+        $this->model->log($key);
+        $this->assertFalse($this->model->hasLog($key));
     }
 
     public function testLogDebug()
     {
         $message = uniqid();
         /** @var $model \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
-        $model = $this->getMock('Magento\Framework\Logger', array('log'), array(), '', false);
+        $model = $this->getMock('Magento\Framework\Logger', ['log'], [], '', false);
         $model->expects($this->at(0))
             ->method('log')
             ->with($message, \Zend_Log::DEBUG, \Magento\Framework\Logger::LOGGER_SYSTEM);
-        $model->expects(
-            $this->at(1)
-        )->method(
-                'log'
-            )->with(
+        $model->expects($this->at(1))
+            ->method('log')
+            ->with(
                 $message,
                 \Zend_Log::DEBUG,
                 \Magento\Framework\Logger::LOGGER_EXCEPTION
@@ -176,16 +177,33 @@ class LoggerTest extends \PHPUnit_Framework_TestCase
         $exception = new \Exception();
         $expected = "\n{$exception}";
         /** @var $model \Magento\Framework\Logger|\PHPUnit_Framework_MockObject_MockObject */
-        $model = $this->getMock('Magento\Framework\Logger', array('log'), array(), '', false);
-        $model->expects(
-            $this->at(0)
-        )->method(
-                'log'
-            )->with(
+        $model = $this->getMock('Magento\Framework\Logger', ['log'], [], '', false);
+        $model->expects($this->at(0))
+            ->method('log')
+            ->with(
                 $expected,
                 \Zend_Log::ERR,
                 \Magento\Framework\Logger::LOGGER_EXCEPTION
             );
         $model->logException($exception);
     }
-}
+
+    public function testUnsetLoggers()
+    {
+        $key = 'test';
+        $fileOrWrapper = 'custom_file.log';
+        $this->model->addStreamLog($key, $fileOrWrapper);
+        $this->assertTrue($this->model->hasLog($key));
+        $this->model->unsetLoggers();
+        $this->assertFalse($this->model->hasLog($key));
+    }
+
+    public function testLogFile()
+    {
+        $message = ['Wrong file name', 'Avoid using special chars'];
+        $filename = 'custom_file.log';
+        $this->model->logFile($message, \Zend_Log::DEBUG);
+        $this->model->logFile($message, \Zend_Log::DEBUG, $filename);
+        $this->assertTrue($this->model->hasLog($filename));
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Pricing/Adjustment/CalculatorTest.php b/dev/tests/unit/testsuite/Magento/Framework/Pricing/Adjustment/CalculatorTest.php
index 11276b58df6331c335e64e174c8bf450feec3dae..0192c410993ea6a5178c653b6867eb3b944927f8 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Pricing/Adjustment/CalculatorTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Pricing/Adjustment/CalculatorTest.php
@@ -108,9 +108,8 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
 
         $adjustments = [$taxAdjustmentMock, $weeeAdjustmentMock];
 
-        $priceInfoMock = $this->getMockBuilder('\Magento\Framework\Pricing\PriceInfoInterface')
+        $priceInfoMock = $this->getMockBuilder('\Magento\Framework\Pricing\PriceInfo\Base')
             ->disableOriginalConstructor()
-            //->setMethods(['getPriceInfo'])
             ->getMock();
         $priceInfoMock->expects($this->any())
             ->method('getAdjustments')
@@ -177,9 +176,8 @@ class CalculatorTest extends \PHPUnit_Framework_TestCase
 
         $adjustments = [$taxAdjustmentMock, $weeeAdjustmentMock];
 
-        $priceInfoMock = $this->getMockBuilder('\Magento\Framework\Pricing\PriceInfoInterface')
+        $priceInfoMock = $this->getMockBuilder('\Magento\Framework\Pricing\PriceInfo\Base')
             ->disableOriginalConstructor()
-            //->setMethods(['getPriceInfo'])
             ->getMock();
         $priceInfoMock->expects($this->any())
             ->method('getAdjustments')
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Pricing/Price/AbstractPriceTest.php b/dev/tests/unit/testsuite/Magento/Framework/Pricing/Price/AbstractPriceTest.php
index d478d29d4a905790ddbcb4036f45ab613759223b..35134d134f9952dc999d8e4e4649bf7e8e8fec8d 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Pricing/Price/AbstractPriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Pricing/Price/AbstractPriceTest.php
@@ -35,7 +35,7 @@ class AbstractPriceTest extends \PHPUnit_Framework_TestCase
     protected $price;
 
     /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface |\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfo\Base |\PHPUnit_Framework_MockObject_MockObject
      */
     protected $priceInfoMock;
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Pricing/PriceInfo/FactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/Pricing/PriceInfo/FactoryTest.php
index 093a30d2985b0f107f4723af320e016522813dc3..b0fc60ad4dfde59b7c13b60f485c6bd5999ceeff 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Pricing/PriceInfo/FactoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Pricing/PriceInfo/FactoryTest.php
@@ -56,7 +56,7 @@ class FactoryTest extends \PHPUnit_Framework_TestCase
     protected $saleableItemMock;
 
     /**
-     * @var \Magento\Framework\Pricing\PriceInfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Framework\Pricing\PriceInfo\Base|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $priceInfoMock;
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Pricing/Render/PriceBoxTest.php b/dev/tests/unit/testsuite/Magento/Framework/Pricing/Render/PriceBoxTest.php
index 10a58279528283f13b4e39273c2deba229796f2b..4a8f5212a10588fc8639b342cccf647650601cd8 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Pricing/Render/PriceBoxTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Pricing/Render/PriceBoxTest.php
@@ -155,7 +155,7 @@ class PriceBoxTest extends \PHPUnit_Framework_TestCase
 
         $price = $this->getMock('Magento\Framework\Pricing\Price\PriceInterface');
 
-        $priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfoInterface');
+        $priceInfo = $this->getMock('Magento\Framework\Pricing\PriceInfo\Base', [], [], '', false);
         $priceInfo->expects($this->once())
             ->method('getPrice')
             ->with($priceCode)
diff --git a/dev/tests/unit/testsuite/Magento/Framework/RegistryTest.php b/dev/tests/unit/testsuite/Magento/Framework/RegistryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d47897a3a4f7454961d2f4d2daee4b5826d9208e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/RegistryTest.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework;
+
+/**
+ * Registry model test. Test cases for managing values in registry
+ */
+class RegistryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
+
+    /**
+     * @var array
+     */
+    protected $data;
+
+    public function setUp()
+    {
+        $this->registry = new Registry();
+        $this->data = [
+            'key' => 'customer',
+            'value' => '\Magento\Customer\Model\Customer'
+        ];
+        $this->registry->register($this->data['key'], $this->data['value']);
+    }
+
+    public function tearDown()
+    {
+        unset($this->registry);
+    }
+
+    public function testRegistry()
+    {
+        $this->assertEquals($this->data['value'], $this->registry->registry($this->data['key']));
+        $this->assertNull($this->registry->registry($this->data['value']));
+    }
+
+    public function testRegister()
+    {
+        $key = 'email';
+        $value = 'test@magento.com';
+        $this->registry->register($key, $value);
+        $this->assertEquals($value, $this->registry->registry($key));
+        $key = 'name';
+        $graceful = true;
+        $this->registry->register($key, $value, $graceful);
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     */
+    public function testRegisterKeyExists()
+    {
+        $this->registry->register($this->data['key'], $this->data['value']);
+    }
+
+    public function testUnregister()
+    {
+        $key = 'csv_adapter';
+        $valueObj = $this->getMock('\Magento\ImportExport\Model\Export\Adapter\Csv', [], [], '', false, false);
+        $this->registry->register($key, $valueObj);
+        $this->assertEquals($valueObj, $this->registry->registry($key));
+        $this->registry->unregister($key);
+        $this->assertNull($this->registry->registry($key));
+        $this->registry->unregister($this->data['key']);
+        $this->assertNull($this->registry->registry($this->data['key']));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Service/Data/Eav/AttributeValueTest.php b/dev/tests/unit/testsuite/Magento/Framework/Service/Data/Eav/AttributeValueTest.php
index 4d6a55d515962c6ae31d8f7c61cb2dc681e9053d..9534bf01a7318c9415c4fbf1d78e65f87f942271 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Service/Data/Eav/AttributeValueTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Service/Data/Eav/AttributeValueTest.php
@@ -31,7 +31,8 @@ class AttributeValueTest extends \PHPUnit_Framework_TestCase
 
     public function testConstructorAndGetters()
     {
-        $attributeBuilder = (new AttributeValueBuilder())
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $attributeBuilder = $helper->getObject('\Magento\Framework\Service\Data\Eav\AttributeValueBuilder')
             ->setAttributeCode(self::ATTRIBUTE_CODE)
             ->setValue(self::VALUE);
         $attribute = new AttributeValue($attributeBuilder);
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Service/DataObjectConverterTest.php b/dev/tests/unit/testsuite/Magento/Framework/Service/DataObjectConverterTest.php
index 0f94cc8a6938323ebe1ca7e68812e7a62d1dd5c8..da12eefa256cdfb98800d93ac46e9213bc392925 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Service/DataObjectConverterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Service/DataObjectConverterTest.php
@@ -25,7 +25,6 @@
 namespace Magento\Framework\Service;
 
 use Magento\Customer\Service\V1\Data\Customer;
-use Magento\Customer\Service\V1\Data\RegionBuilder;
 
 /**
  * Class implements tests for DataObjectConverterTest class.
@@ -164,8 +163,11 @@ class DataObjectConverterTest extends \PHPUnit_Framework_TestCase
             ->setDefaultShipping(true)
             ->setPostcode('75477')
             ->setRegion(
-                (new RegionBuilder())->setRegionCode(self::REGION_CODE)->setRegion(self::REGION)
-                    ->setRegionId(self::REGION_ID)->create()
+                $objectManager->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                    ->setRegionCode(self::REGION_CODE)
+                    ->setRegion(self::REGION)
+                    ->setRegionId(self::REGION_ID)
+                    ->create()
             )
             ->setStreet($street1)
             ->setTelephone('3468676')
@@ -181,8 +183,11 @@ class DataObjectConverterTest extends \PHPUnit_Framework_TestCase
             ->setDefaultShipping(false)
             ->setPostcode('47676')
             ->setRegion(
-                (new RegionBuilder())->setRegionCode(self::REGION_CODE)->setRegion(self::REGION)
-                    ->setRegionId(self::REGION_ID)->create()
+                $objectManager->getObject('\Magento\Customer\Service\V1\Data\RegionBuilder')
+                    ->setRegionCode(self::REGION_CODE)
+                    ->setRegion(self::REGION)
+                    ->setRegionId(self::REGION_ID)
+                    ->create()
             )
             ->setStreet($street2)
             ->setCity('CityX')
diff --git a/dev/tests/unit/testsuite/Magento/Framework/TranslateTest.php b/dev/tests/unit/testsuite/Magento/Framework/TranslateTest.php
index cc5ddf0d7c0ea8e2bb727f526e4d9e14ed2e30cf..56ffb6e2186ba9430208a4121f99a0d61cccb6a4 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/TranslateTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/TranslateTest.php
@@ -27,7 +27,6 @@ use Magento\TestFramework\Matcher\MethodInvokedAtIndex;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- *
  */
 class TranslateTest extends \PHPUnit_Framework_TestCase
 {
@@ -90,7 +89,9 @@ class TranslateTest extends \PHPUnit_Framework_TestCase
         $this->_appState = $this->getMock('\Magento\Framework\App\State', [], [], '', false);
         $this->_request = $this->getMock('\Magento\Framework\App\RequestInterface', [], [], '', false);
         $this->_csvParser = $this->getMock('\Magento\Framework\File\Csv', [], [], '', false);
-
+        $this->_config->expects($this->once())
+            ->method('getHierarchy')
+            ->will($this->returnValue(['en_US' => ['en_GB']]));
         $this->_directory = $this->getMock('\Magento\Framework\Filesystem\Directory\ReadInterface', [], [], '', false);
         $filesystem = $this->getMock('\Magento\Framework\App\Filesystem', [], [], '', false);
         $filesystem->expects($this->once())->method('getDirectoryRead')->will($this->returnValue($this->_directory));
@@ -117,10 +118,11 @@ class TranslateTest extends \PHPUnit_Framework_TestCase
      * @param bool $forceReload
      * @param array $cachedData
      * @dataProvider dataProviderForTestLoadData
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function testLoadData($area, $forceReload, $cachedData)
     {
-        $this->_expectsSetConfig();
+        $this->_expectsSetConfig('themeId');
 
         $this->_cache->expects($this->exactly($forceReload ? 0 : 1))
             ->method('load')
@@ -137,21 +139,28 @@ class TranslateTest extends \PHPUnit_Framework_TestCase
         // _loadModuleTranslation()
         $modules = [['name' => 'module']];
         $this->_moduleList->expects($this->once())->method('getModules')->will($this->returnValue($modules));
-        $moduleData = ['module original' => 'module translated'];
+        $moduleData = [
+            'module original' => 'module translated',
+            'module original2' => 'module original2'
+        ];
         $this->_modulesReader->expects($this->any())->method('getModuleDir')->will($this->returnValue('/app/module'));
-        $this->_csvParser->expects(new MethodInvokedAtIndex(0))
+        $themeData = ['theme original' => 'theme translated'];
+        $this->_csvParser->expects($this->any())
             ->method('getDataPairs')
-            ->with('/app/module/en_US.csv')
-            ->will($this->returnValue($moduleData));
+            ->will(
+                $this->returnValueMap(
+                    [
+                        ['/app/module/en_US.csv', 0, 1, $moduleData],
+                        ['/app/module/en_GB.csv', 0, 1, $moduleData],
+                        ['/theme.csv', 0, 1, $themeData],
+                    ]
+                )
+            );
 
         // _loadThemeTranslation()
-        $themeData = ['theme original' => 'theme translated'];
-        $this->_viewFileSystem->expects($this->once())->method('getLocaleFileName')
+        $this->_viewFileSystem->expects($this->any())
+            ->method('getLocaleFileName')
             ->will($this->returnValue('/theme.csv'));
-        $this->_csvParser->expects(new MethodInvokedAtIndex(1))
-            ->method('getDataPairs')
-            ->with('/theme.csv')
-            ->will($this->returnValue($themeData));
 
         // _loadDbTranslation()
         $dbData = ['db original' => 'db translated'];
@@ -162,7 +171,12 @@ class TranslateTest extends \PHPUnit_Framework_TestCase
 
         $this->_translate->loadData($area, $forceReload);
 
-        $expected = $moduleData + $themeData + $dbData;
+        $condition = ($area == 'adminhtml' && !$forceReload) ? true : false;
+        $expected = [
+            'module original' => 'module translated',
+            ($condition ? 'themethemeId::' : '') . 'theme original' => 'theme translated',
+            ($condition ? 'adminCode::' : '') . 'db original' => 'db translated'
+        ];
         $this->assertEquals($expected, $this->_translate->getData());
     }
 
@@ -175,19 +189,33 @@ class TranslateTest extends \PHPUnit_Framework_TestCase
             ['frontend', true, false],
             ['frontend', false, $cachedData],
             [null, true, false],
-            [null, false, $cachedData]
+            [null, false, $cachedData],
+            ['adminhtml', false, false]
         ];
     }
 
-    public function testGetData()
+    /**
+     * @param $data
+     * @param $result
+     * @dataProvider dataProviderForTestGetData
+     */
+    public function testGetData($data, $result)
     {
-        $data = array('original 1' => 'translated 1', 'original 2' => 'translated 2');
         $this->_cache->expects($this->once())
             ->method('load')
             ->will($this->returnValue(serialize($data)));
-        $this->_expectsSetConfig();
+        $this->_expectsSetConfig('themeId');
         $this->_translate->loadData('frontend');
-        $this->assertEquals($data, $this->_translate->getData());
+        $this->assertEquals($result, $this->_translate->getData());
+    }
+
+    public function dataProviderForTestGetData()
+    {
+        $data = ['original 1' => 'translated 1', 'original 2' => 'translated 2'];
+        return [
+            [$data, $data],
+            [null, []]
+        ];
     }
 
     public function testGetLocale()
@@ -222,15 +250,35 @@ class TranslateTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals('themeTheme Title', $this->_translate->getTheme());
     }
 
+    public function testLoadDataNoTheme()
+    {
+        $forceReload = true;
+        $this->_expectsSetConfig(null, null);
+        $this->_moduleList->expects($this->once())->method('getModules')->will($this->returnValue([]));
+        $this->_appState->expects($this->once())->method('getAreaCode')->will($this->returnValue('frontend'));
+        $this->_resource->expects($this->any())->method('getTranslationArray')->will($this->returnValue([]));
+        $this->assertEquals($this->_translate, $this->_translate->loadData(null, $forceReload));
+    }
+
     /**
      * Declare calls expectation for setConfig() method
      */
-    protected function _expectsSetConfig()
+    protected function _expectsSetConfig($themeId, $localeCode = 'en_US')
     {
-        $this->_locale->expects($this->any())->method('getLocaleCode')->will($this->returnValue('en_US'));
+        $this->_locale->expects($this->any())->method('getLocaleCode')->will($this->returnValue($localeCode));
         $scope = new \Magento\Framework\Object();
-        $this->_scopeResolver->expects($this->any())->method('getScope')->will($this->returnValue($scope));
-        $designTheme = new \Magento\Framework\Object(['id' => 'themeId']);
+        $scopeAdmin = new \Magento\Framework\Object(['code' => 'adminCode', 'id' => 1]);
+        $this->_scopeResolver->expects($this->any())
+            ->method('getScope')
+            ->will(
+                $this->returnValueMap(
+                    [
+                        [null, $scope],
+                        ['admin', $scopeAdmin]
+                    ]
+                )
+            );
+        $designTheme = new \Magento\Framework\Object(['id' => $themeId]);
         $this->_viewDesign->expects($this->any())->method('getDesignTheme')->will($this->returnValue($designTheme));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/UtilTest.php b/dev/tests/unit/testsuite/Magento/Framework/UtilTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a13ebbe1cade464455ffe4fb3734da57cd2805d8
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/UtilTest.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Collection of various useful functions
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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;
+
+class UtilTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetTrimmedPhpVersion()
+    {
+        $util = new \Magento\Framework\Util();
+        $version = implode('.', [PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION]);
+        $this->assertEquals($version, $util->getTrimmedPhpVersion());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/_files/Archive/archives/.gitignore b/dev/tests/unit/testsuite/Magento/Framework/_files/Archive/archives/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..22e83649f7d5219bb31ce45bd7e986e57ea4e72e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/_files/Archive/archives/.gitignore
@@ -0,0 +1 @@
+/*
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Framework/_files/Archive/source.txt b/dev/tests/unit/testsuite/Magento/Framework/_files/Archive/source.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1d3a06547c706bd0f75b130edecf4832295bba6b
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/_files/Archive/source.txt
@@ -0,0 +1 @@
+source
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php b/dev/tests/unit/testsuite/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php
similarity index 53%
rename from dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php
rename to dev/tests/unit/testsuite/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php
index 22cdac721d7786777ee52875e7fe86d26bc88e9d..a08f93f209c30a67c7e862bc0aff02612b663bf6 100644
--- a/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php
+++ b/dev/tests/unit/testsuite/Magento/GroupedProduct/Model/Product/Initialization/Helper/ProductLinks/Plugin/GroupedTest.php
@@ -22,20 +22,17 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\GroupedProduct\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks\Plugin;
+namespace Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin;
+
+use Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin\Grouped;
 
 class GroupedTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\GroupedProduct\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks\Plugin\Grouped
+     * @var \Magento\GroupedProduct\Model\Product\Initialization\Helper\ProductLinks\Plugin\Grouped
      */
     protected $model;
 
-    /**
-     * @var \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected $requestMock;
-
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
@@ -48,7 +45,6 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->requestMock = $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false);
         $this->productMock = $this->getMock(
             'Magento\Catalog\Model\Product',
             array('getGroupedReadonly', 'setGroupedLinkData', '__wakeup'),
@@ -57,71 +53,33 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
             false
         );
         $this->subjectMock = $this->getMock(
-            'Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\ProductLinks',
+            'Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks',
             array(),
             array(),
             '',
             false
         );
-        $this->model = new Grouped($this->requestMock);
+        $this->model = new Grouped();
     }
 
-    public function testAfterInitializeLinksRequestDoesNotHaveGrouped()
+    public function testBeforeInitializeLinksRequestDoesNotHaveGrouped()
     {
-        $this->requestMock->expects(
-            $this->once()
-        )->method(
-            'getPost'
-        )->with(
-            'links'
-        )->will(
-            $this->returnValue(array())
-        );
         $this->productMock->expects($this->never())->method('getGroupedReadonly');
         $this->productMock->expects($this->never())->method('setGroupedLinkData');
-        $this->assertEquals(
-            $this->productMock,
-            $this->model->afterInitializeLinks($this->subjectMock, $this->productMock)
-        );
+        $this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, array());
     }
 
-    public function testAfterInitializeLinksRequestHasGrouped()
+    public function testBeforeInitializeLinksRequestHasGrouped()
     {
-        $this->requestMock->expects(
-            $this->once()
-        )->method(
-            'getPost'
-        )->with(
-            'links'
-        )->will(
-            $this->returnValue(array('grouped' => 'value'))
-        );
-
         $this->productMock->expects($this->once())->method('getGroupedReadonly')->will($this->returnValue(false));
         $this->productMock->expects($this->once())->method('setGroupedLinkData')->with(array('value'));
-        $this->assertEquals(
-            $this->productMock,
-            $this->model->afterInitializeLinks($this->subjectMock, $this->productMock)
-        );
+        $this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, array('associated' => 'value'));
     }
 
-    public function testAfterInitializeLinksProductIsReadonly()
+    public function testBeforeInitializeLinksProductIsReadonly()
     {
-        $this->requestMock->expects(
-            $this->once()
-        )->method(
-            'getPost'
-        )->with(
-            'links'
-        )->will(
-            $this->returnValue(array('grouped' => 'value'))
-        );
-
         $this->productMock->expects($this->once())->method('getGroupedReadonly')->will($this->returnValue(true));
         $this->productMock->expects($this->never())->method('setGroupedLinkData');
-        $this->assertEquals(
-            $this->productMock,
-            $this->model->afterInitializeLinks($this->subjectMock, $this->productMock)
-        );
+        $this->model->beforeInitializeLinks($this->subjectMock, $this->productMock, array('associated' => 'value'));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/GroupedTest.php b/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/GroupedTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b52e70fa6b80541ad1bc94b6c7cee5eba514b137
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/CollectionProvider/GroupedTest.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\CollectionProvider;
+
+class GroupedTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetLinkedProducts()
+    {
+        $typeInstance = $this->getMock('\Magento\GroupedProduct\Model\Product\Type\Grouped', [], [], '', false);
+        $product = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
+        $expected = [$product];
+
+        $product->expects($this->once())->method('getTypeInstance')->will($this->returnValue($typeInstance));
+        $typeInstance->expects($this->once())
+            ->method('getAssociatedProducts')
+            ->with($product)
+            ->will($this->returnValue($expected));
+
+        $model = new Grouped();
+        $this->assertEquals($expected, $model->getLinkedProducts($product));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/DataMapper/GroupedProductTest.php b/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/DataMapper/GroupedProductTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..56084e6ba9962d44b318859407714a95ae2b787e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/DataMapper/GroupedProductTest.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\DataMapper;
+
+
+class GroupedProductTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers \Magento\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\DataMapper\GroupedProduct::map
+     */
+    public function testMap()
+    {
+        $data = [
+            [
+                'name' => 'item1',
+                'custom_attributes' => ['qty' => ['value' => 5]]
+            ],
+            [
+                'name' => 'item2'
+            ]
+        ];
+
+        $model = new GroupedProduct();
+        $mappedData = $model->map($data);
+
+        $this->assertEquals(5, $mappedData[0]['qty']);
+        $this->assertFalse(isset($mappedData[1]['qty']));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterTest.php b/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..534ee3b490693259eb9b074d1e73640bd09b91ff
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/GroupedProduct/Service/V1/Product/Link/Data/ProductLink/ProductEntity/ConverterTest.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\ProductEntity;
+
+use \Magento\Catalog\Service\V1\Product\Link\Data\ProductLink;
+use \Magento\Framework\Service\Data\Eav\AttributeValue;
+
+class ConverterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers \Magento\GroupedProduct\Service\V1\Product\Link\Data\ProductLink\ProductEntity\Converter::convert
+     */
+    public function testConvert()
+    {
+        $productMock = $this->getMock(
+            '\Magento\Catalog\Model\Product',
+            ['getTypeId', 'getPosition', 'getSku', 'getQty', '__wakeup', '__sleep'],
+            [], '', false
+        );
+
+        $expected = [
+            ProductLink::TYPE             => 1,
+            ProductLink::SKU              => 3,
+            ProductLink::POSITION         => 4,
+            ProductLink::CUSTOM_ATTRIBUTES_KEY => [
+                [AttributeValue::ATTRIBUTE_CODE => 'qty',AttributeValue::VALUE => 5]
+            ]
+        ];
+
+        $productMock->expects($this->once())->method('getTypeId')->will($this->returnValue(1));
+        $productMock->expects($this->once())->method('getSku')->will($this->returnValue(3));
+        $productMock->expects($this->once())->method('getPosition')->will($this->returnValue(4));
+        $productMock->expects($this->once())->method('getQty')->will($this->returnValue(5));
+
+        $model = new Converter();
+        $this->assertEquals($expected, $model->convert($productMock));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/ImportExport/Model/Import/Entity/Product/_files/product_with_custom_options.csv b/dev/tests/unit/testsuite/Magento/ImportExport/Model/Import/Entity/Product/_files/product_with_custom_options.csv
index 8920106716fad810b21348f59159c463b162cfb7..6dd31ced170f4037061046b914e29d5c244cc484 100644
--- a/dev/tests/unit/testsuite/Magento/ImportExport/Model/Import/Entity/Product/_files/product_with_custom_options.csv
+++ b/dev/tests/unit/testsuite/Magento/ImportExport/Model/Import/Entity/Product/_files/product_with_custom_options.csv
@@ -1,4 +1,4 @@
-sku,_store,_attribute_set,_type,_category,_root_category,_product_websites,color,cost,country_of_manufacture,created_at,custom_design,custom_design_from,custom_design_to,custom_layout_update,description,enable_googlecheckout,gallery,gift_message_available,gift_wrapping_available,gift_wrapping_price,has_options,image,image_label,is_returnable,manufacturer,media_gallery,meta_description,meta_keyword,meta_title,minimal_price,msrp,msrp_display_actual_price_type,msrp_enabled,name,news_from_date,news_to_date,options_container,page_layout,price,related_tgtr_position_behavior,related_tgtr_position_limit,required_options,short_description,small_image,small_image_label,special_from_date,special_price,special_to_date,status,tax_class_id,thumbnail,thumbnail_label,updated_at,upsell_tgtr_position_behavior,upsell_tgtr_position_limit,url_key,url_path,visibility,weight,qty,min_qty,use_config_min_qty,is_qty_decimal,backorders,use_config_backorders,min_sale_qty,use_config_min_sale_qty,max_sale_qty,use_config_max_sale_qty,is_in_stock,notify_stock_qty,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,_links_related_sku,_links_related_position,_links_crosssell_sku,_links_crosssell_position,_links_upsell_sku,_links_upsell_position,_associated_sku,_associated_default_qty,_associated_position,_tier_price_website,_tier_price_customer_group,_tier_price_qty,_tier_price_price,_group_price_website,_group_price_customer_group,_group_price_price,_media_attribute_id,_media_image,_media_label,_media_position,_media_is_disabled,_custom_option_store,_custom_option_type,_custom_option_title,_custom_option_is_required,_custom_option_price,_custom_option_sku,_custom_option_max_characters,_custom_option_sort_order,_custom_option_row_title,_custom_option_row_price,_custom_option_row_sku,_custom_option_row_sort
+sku,_store,_attribute_set,_type,_category,_root_category,_product_websites,color,cost,country_of_manufacture,created_at,custom_design,custom_design_from,custom_design_to,custom_layout_update,description,enable_googlecheckout,gallery,gift_message_available,gift_wrapping_available,gift_wrapping_price,has_options,image,image_label,is_returnable,manufacturer,media_gallery,meta_description,meta_keyword,meta_title,minimal_price,msrp,msrp_display_actual_price_type,msrp_enabled,name,news_from_date,news_to_date,options_container,page_layout,price,related_tgtr_position_behavior,related_tgtr_position_limit,required_options,short_description,small_image,small_image_label,special_from_date,special_price,special_to_date,status,tax_class_id,thumbnail,thumbnail_label,updated_at,upsell_tgtr_position_behavior,upsell_tgtr_position_limit,url_key,url_path,visibility,weight,qty,min_qty,use_config_min_qty,is_qty_decimal,backorders,use_config_backorders,min_sale_qty,use_config_min_sale_qty,max_sale_qty,use_config_max_sale_qty,is_in_stock,notify_stock_qty,use_config_notify_stock_qty,manage_stock,use_config_manage_stock,use_config_qty_increments,qty_increments,use_config_enable_qty_inc,enable_qty_increments,is_decimal_divided,_related_sku,_related_position,_crosssell_sku,_crosssell_position,_upsell_sku,_upsell_position,_associated_sku,_associated_default_qty,_associated_position,_tier_price_website,_tier_price_customer_group,_tier_price_qty,_tier_price_price,_group_price_website,_group_price_customer_group,_group_price_price,_media_attribute_id,_media_image,_media_label,_media_position,_media_is_disabled,_custom_option_store,_custom_option_type,_custom_option_title,_custom_option_is_required,_custom_option_price,_custom_option_sku,_custom_option_max_characters,_custom_option_sort_order,_custom_option_row_title,_custom_option_row_price,_custom_option_row_sku,_custom_option_row_sort
 simple,,Default,simple,,,base,,,,,,,,,,1,,,,,1,,,"Use config",,,,,,,,,,"New Product",,,"Block after Info Column",,10.0000,,,1,,,,,,,1,,,,"2012-07-13 12:04:17",,,new-product,new-product.html,4,,100.0000,0.0000,1,0,0,1,1.0000,1,0.0000,1,1,,1,0,1,1,0.0000,1,0,0,,,,,,,,,,,,,,,,,,,,,,,field,"Test Field Title",1,,1-text,100,0,,,,
 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,date_time,"Test Date and Time Title",1,2.0000,2-date,,0,,,,
 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,drop_down,"Test Select",1,,,,0,"Option 1",3.0000,3-1-select,0
@@ -6,4 +6,4 @@ simple,,Default,simple,,,base,,,,,,,,,,1,,,,,1,,,"Use config",,,,,,,,,,"New Prod
 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,default,,,,,,,,"Option 2",,,
 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,radio,"Test Radio",1,,,,0,"Option 1",3.0000,4-1-radio,0
 ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"Option 2",3.0000,4-2-radio,0
-,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,default,,,,,,,,"Option 2",,,
\ No newline at end of file
+,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,default,,,,,,,,"Option 2",,,
diff --git a/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php b/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
index 57aed72cb162b66ac0494020406ec6706f6acaa5..50edbe9aa7c8cafcf0f1458b0e68f6f819ebd0af 100644
--- a/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
+++ b/dev/tests/unit/testsuite/Magento/Ogone/Model/ApiTest.php
@@ -25,11 +25,6 @@ namespace Magento\Ogone\Model;
 
 class ApiTest extends \PHPUnit_Framework_TestCase
 {
-    protected function setUp()
-    {
-        $this->markTestSkipped('Api tests were skipped');
-    }
-
     /**
      * Test protected method, which converts Magento internal charset (UTF-8) to the one, understandable
      * by Ogone (ISO-8859-1), and then encodes html entities
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseCheckoutTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseCheckoutTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..afbfea37e1411d056fc372a5a42254919e4b1182
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseCheckoutTest.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\Payment\Model\Checks;
+
+class CanUseCheckoutTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var CanUseCheckout
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_model = new CanUseCheckout();
+    }
+
+    /**
+     * @dataProvider paymentMethodDataProvider
+     * @param bool $expectation
+     */
+    public function testIsApplicable($expectation)
+    {
+        $quote = $this->getMockBuilder('Magento\Sales\Model\Quote')->disableOriginalConstructor()->setMethods(
+            []
+        )->getMock();
+        $paymentMethod = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\PaymentMethodChecksInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $paymentMethod->expects($this->once())->method('canUseCheckout')->will(
+            $this->returnValue($expectation)
+        );
+        $this->assertEquals($expectation, $this->_model->isApplicable($paymentMethod, $quote));
+    }
+
+    /**
+     * @return array
+     */
+    public function paymentMethodDataProvider()
+    {
+        return [[true], [false]];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseForCountryTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseForCountryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b20ca5525d0104d442e839cce8cad31101c4f0cc
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseForCountryTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model\Checks;
+
+class CanUseForCountryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Expected country id
+     */
+    const EXPECTED_COUNTRY_ID = 1;
+
+    /**
+     * @var CanUseForCountry
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_model = new CanUseForCountry();
+    }
+
+    /**
+     * @dataProvider paymentMethodDataProvider
+     * @param bool $expectation
+     */
+    public function testIsApplicable($expectation)
+    {
+        $quoteMock = $this->getMockBuilder('Magento\Sales\Model\Quote')->disableOriginalConstructor()->setMethods(
+            []
+        )->getMock();
+        $billingAddressMock = $this->getMockBuilder(
+            'Magento\Sales\Model\Quote\Address'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $billingAddressMock->expects($this->once())->method('getCountry')->will(
+            $this->returnValue(self::EXPECTED_COUNTRY_ID)
+        );
+        $quoteMock->expects($this->once())->method('getBillingAddress')->will($this->returnValue($billingAddressMock));
+
+        $paymentMethod = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\PaymentMethodChecksInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $paymentMethod->expects($this->once())->method('canUseForCountry')->with(
+            self::EXPECTED_COUNTRY_ID
+        )->will($this->returnValue($expectation));
+
+        $this->assertEquals($expectation, $this->_model->isApplicable($paymentMethod, $quoteMock));
+    }
+
+    /**
+     * @return array
+     */
+    public function paymentMethodDataProvider()
+    {
+        return [[true], [false]];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseForCurrencyTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseForCurrencyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..32dba3395d027c219091698e2cc15ddb23e78901
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseForCurrencyTest.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model\Checks;
+
+class CanUseForCurrencyTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Expected currency code
+     */
+    const EXPECTED_CURRENCY_CODE = 'US';
+
+    /**
+     * @var CanUseForCurrency
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_model = new CanUseForCurrency();
+    }
+
+    /**
+     * @dataProvider paymentMethodDataProvider
+     * @param bool $expectation
+     */
+    public function testIsApplicable($expectation)
+    {
+        $paymentMethod = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\PaymentMethodChecksInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $paymentMethod->expects($this->once())->method('canUseForCurrency')->with(
+            self::EXPECTED_CURRENCY_CODE
+        )->will($this->returnValue($expectation));
+
+        $quoteMock = $this->getMockBuilder('Magento\Sales\Model\Quote')->disableOriginalConstructor()->setMethods(
+            []
+        )->getMock();
+        $store = $this->getMockBuilder(
+            'Magento\Store\Model\Store'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $store->expects($this->once())->method('getBaseCurrencyCode')->will(
+            $this->returnValue(self::EXPECTED_CURRENCY_CODE)
+        );
+        $quoteMock->expects($this->once())->method('getStore')->will($this->returnValue($store));
+
+        $this->assertEquals($expectation, $this->_model->isApplicable($paymentMethod, $quoteMock));
+    }
+
+    /**
+     * @return array
+     */
+    public function paymentMethodDataProvider()
+    {
+        return [[true], [false]];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseInternalTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseInternalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b85d22cc9f5641c7e12608f5d54fbb3ca14b032f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CanUseInternalTest.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\Payment\Model\Checks;
+
+class CanUseInternalTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var CanUseInternal
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_model = new CanUseInternal();
+    }
+
+    /**
+     * @dataProvider paymentMethodDataProvider
+     * @param bool $expectation
+     */
+    public function testIsApplicable($expectation)
+    {
+        $quote = $this->getMockBuilder('Magento\Sales\Model\Quote')->disableOriginalConstructor()->setMethods(
+            []
+        )->getMock();
+        $paymentMethod = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\PaymentMethodChecksInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $paymentMethod->expects($this->once())->method('canUseInternal')->will(
+            $this->returnValue($expectation)
+        );
+        $this->assertEquals($expectation, $this->_model->isApplicable($paymentMethod, $quote));
+    }
+
+    /**
+     * @return array
+     */
+    public function paymentMethodDataProvider()
+    {
+        return [[true], [false]];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CompositeTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CompositeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d71afc522af1492e322b0b8d7bab9123fd7ef04e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/CompositeTest.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model\Checks;
+
+class CompositeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider paymentMethodDataProvider
+     * @param bool $expectation
+     */
+    public function testIsApplicable($expectation)
+    {
+        $quote = $this->getMockBuilder('Magento\Sales\Model\Quote')->disableOriginalConstructor()->setMethods(
+            []
+        )->getMock();
+        $paymentMethod = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\PaymentMethodChecksInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+
+        $specification = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\SpecificationInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $specification->expects($this->once())->method('isApplicable')->with($paymentMethod, $quote)->will(
+            $this->returnValue($expectation)
+        );
+        $model = new Composite([$specification]);
+        $this->assertEquals($expectation, $model->isApplicable($paymentMethod, $quote));
+    }
+
+    /**
+     * @return array
+     */
+    public function paymentMethodDataProvider()
+    {
+        return [[true], [false]];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/SpecificationFactoryTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/SpecificationFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..396fddf512f0c2bcd9d833fac9e0c837183178b4
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/SpecificationFactoryTest.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model\Checks;
+
+class SpecificationFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Specification key
+     */
+    const SPECIFICATION_KEY = 'specification';
+
+    /**
+     * @var \Magento\Payment\Model\Checks\CompositeFactory | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_compositeFactory;
+
+    public function setUp()
+    {
+        $this->_compositeFactory = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\CompositeFactory'
+        )->disableOriginalConstructor()->setMethods(['create'])->getMock();
+    }
+
+    public function testCreate()
+    {
+        $specification = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\SpecificationInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $specificationMapping = [self::SPECIFICATION_KEY => $specification];
+
+        $expectedComposite = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\Composite'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $modelFactory = new SpecificationFactory($this->_compositeFactory, $specificationMapping);
+        $this->_compositeFactory->expects($this->once())->method('create')->with(
+            ['list' => $specificationMapping]
+        )->will($this->returnValue($expectedComposite));
+
+        $this->assertEquals($expectedComposite, $modelFactory->create([self::SPECIFICATION_KEY]));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/TotalMinMaxTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/TotalMinMaxTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..63db8c3add81291d463cb8a91111b7a087641567
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/TotalMinMaxTest.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\Payment\Model\Checks;
+
+class TotalMinMaxTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Payment min total value
+     */
+    const PAYMENT_MIN_TOTAL = 2;
+
+    /**
+     * Payment max total value
+     */
+    const PAYMENT_MAX_TOTAL = 5;
+
+    /**
+     * @dataProvider paymentMethodDataProvider
+     * @param int $baseGrandTotal
+     * @param bool $expectation
+     */
+    public function testIsApplicable($baseGrandTotal, $expectation)
+    {
+        $paymentMethod = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\PaymentMethodChecksInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $paymentMethod->expects($this->at(0))->method('getConfigData')->with(
+            TotalMinMax::MIN_ORDER_TOTAL
+        )->will($this->returnValue(self::PAYMENT_MIN_TOTAL));
+        $paymentMethod->expects($this->at(1))->method('getConfigData')->with(
+            TotalMinMax::MAX_ORDER_TOTAL
+        )->will($this->returnValue(self::PAYMENT_MAX_TOTAL));
+
+        $quote = $this->getMockBuilder('Magento\Sales\Model\Quote')->disableOriginalConstructor()->setMethods(
+            ['getBaseGrandTotal', '__wakeup']
+        )->getMock();
+        $quote->expects($this->once())->method('getBaseGrandTotal')->will($this->returnValue($baseGrandTotal));
+
+        $model = new TotalMinMax();
+        $this->assertEquals($expectation, $model->isApplicable($paymentMethod, $quote));
+    }
+
+    /**
+     * @return array
+     */
+    public function paymentMethodDataProvider()
+    {
+        return [[1, false], [6, false], [3, true]];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/ZeroTotalTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/ZeroTotalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..85be6b35962c88ddcc6a40413c2445693cbaf8df
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Checks/ZeroTotalTest.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\Payment\Model\Checks;
+
+class ZeroTotalTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider paymentMethodDataProvider
+     * @param string $code
+     * @param int $total
+     * @param bool $expectation
+     */
+    public function testIsApplicable($code, $total, $expectation)
+    {
+        $paymentMethod = $this->getMockBuilder(
+            'Magento\Payment\Model\Checks\PaymentMethodChecksInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        if (!$total) {
+            $paymentMethod->expects($this->once())->method('getCode')->will($this->returnValue($code));
+        }
+
+        $quote= $this->getMockBuilder('Magento\Sales\Model\Quote')->disableOriginalConstructor()->setMethods(
+            ['getBaseSubtotal', 'getShippingAddress', '__wakeup']
+        )->getMock();
+        $shippingAddress = $this->getMockBuilder(
+            'Magento\Sales\Model\Quote\Address'
+        )->disableOriginalConstructor()->setMethods(['getBaseShippingAmount', '__wakeup'])->getMock();
+        $shippingAddress->expects($this->once())->method('getBaseShippingAmount')->will(
+            $this->returnValue($total)
+        );
+        $quote->expects($this->once())->method('getBaseSubtotal')->will($this->returnValue($total));
+        $quote->expects($this->once())->method('getShippingAddress')->will($this->returnValue($shippingAddress));
+
+        $model = new ZeroTotal();
+        $this->assertEquals($expectation, $model->isApplicable($paymentMethod, $quote));
+    }
+
+    /**
+     * @return array
+     */
+    public function paymentMethodDataProvider()
+    {
+        return [['not_free', 0, false], ['free', 1, true]];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Config/SchemaLocatorTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Config/SchemaLocatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4d12d5afedbba612ff85722c19eb907368828aee
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Config/SchemaLocatorTest.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Payment\Model\Config;
+
+class SchemaLocatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Payment\Model\Config\SchemaLocator
+     */
+    protected $model;
+
+    const MODULE_DIR_PATH = '/path/to/payment/schema';
+
+    public function setUp()
+    {
+        $moduleReader = $this->getMockBuilder(
+            'Magento\Framework\Module\Dir\Reader'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $moduleReader->expects($this->exactly(2))->method('getModuleDir')->with('etc', 'Magento_Payment')->will(
+            $this->returnValue(self::MODULE_DIR_PATH)
+        );
+        $this->model = new SchemaLocator($moduleReader);
+    }
+
+    public function testGetSchema()
+    {
+        $this->assertEquals(
+            self::MODULE_DIR_PATH . '/' . SchemaLocator::MERGED_CONFIG_SCHEMA,
+            $this->model->getSchema()
+        );
+    }
+
+    public function testGetPerFileSchema()
+    {
+        $this->assertEquals(
+            self::MODULE_DIR_PATH . '/' . SchemaLocator::PER_FILE_VALIDATION_SCHEMA,
+            $this->model->getPerFileSchema()
+        );
+    }
+
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/AllmethodsTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/AllmethodsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1af7ce84a253393d6622b449de70c5749540a5c2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/AllmethodsTest.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\Payment\Model\Config\Source;
+
+class AllmethodsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Payment data
+     *
+     * @var \Magento\Payment\Helper\Data | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_paymentData;
+
+    /**
+     * @var Allmethods
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_paymentData = $this->getMockBuilder(
+            'Magento\Payment\Helper\Data'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+
+        $this->_model = new Allmethods($this->_paymentData);
+    }
+
+    public function testToOptionArray()
+    {
+        $expectedArray = ['key' => 'value'];
+        $this->_paymentData->expects($this->once())->method('getPaymentMethodList')->with(
+            true, true, true
+        )->will($this->returnValue($expectedArray));
+        $this->assertEquals($expectedArray, $this->_model->toOptionArray());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/AllspecificcountriesTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/AllspecificcountriesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc03ffacc7e5d2550a1d010a3036e7c23abccae2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/AllspecificcountriesTest.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\Payment\Model\Config\Source;
+
+class AllspecificcountriesTest extends \PHPUnit_Framework_TestCase
+{
+    public function testToOptionArray()
+    {
+        $expectedArray = [
+            ['value' => 0, 'label' => __('All Allowed Countries')],
+            ['value' => 1, 'label' => __('Specific Countries')]
+        ];
+        $model = new Allspecificcountries();
+        $this->assertEquals($expectedArray, $model->toOptionArray());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/CctypeTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/CctypeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8582c0c631910f791db20c4cc750f07023cadece
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Config/Source/CctypeTest.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model\Config\Source;
+
+class CctypeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Payment data
+     *
+     * @var \Magento\Payment\Model\Config | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_paymentConfig;
+
+    /**
+     * @var Cctype
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_paymentConfig = $this->getMockBuilder(
+            'Magento\Payment\Model\Config'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+
+        $this->_model = new Cctype($this->_paymentConfig);
+    }
+
+    public function testToOptionArray()
+    {
+        $cctypesArray = ['code' => 'name'];
+        $expectedArray = [
+            ['value' => 'code', 'label' => 'name']
+        ];
+        $this->_paymentConfig->expects($this->once())->method('getCcTypes')->will($this->returnValue($cctypesArray));
+        $this->assertEquals($expectedArray, $this->_model->toOptionArray());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ccfc8c105c0db5112250c9912b62fd15c4c68bee
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/ConfigTest.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Store\Model\ScopeInterface;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Payment\Model\Config */
+    protected $config;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $scopeConfig;
+
+    /** @var \Magento\Payment\Model\Method\Factory|\PHPUnit_Framework_MockObject_MockObject */
+    protected $paymentMethodFactory;
+
+    /** @var \Magento\Framework\Locale\ListsInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $localeLists;
+
+    /** @var \Magento\Framework\Config\DataInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $dataStorage;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\DateTime|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $date;
+
+    /**
+     * Test payments list
+     *
+     * @var array
+     */
+    protected $paymentMethodsList = [
+        'not_active_method' => ['active' => 0],
+        'active_method_no_model' => ['active' => 1],
+        'active_method' => ['active' => 1, 'model' => 'model_name']
+    ];
+
+    /**
+     * List of test month
+     *
+     * @var array
+     */
+    protected $monthList = [
+        1 => 'Marsabruary',
+        11 => 'Venusly'
+    ];
+
+    /**
+     * Expected months list
+     *
+     * @var array
+     */
+    protected $expectedMonthList = [
+        1 => '01 - Marsabruary',
+        11 => '11 - Venusly'
+    ];
+
+    /**
+     * Current year value in ISO
+     */
+    const CURRENT_YEAR = '2250';
+
+    protected function setUp()
+    {
+        $this->scopeConfig = $this->getMock(
+            'Magento\Framework\App\Config\ScopeConfigInterface',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->paymentMethodFactory = $this->getMock('Magento\Payment\Model\Method\Factory', [], [], '', false);
+        $this->localeLists = $this->getMock('Magento\Framework\Locale\ListsInterface', [], [], '', false);
+        $this->dataStorage = $this->getMock('Magento\Framework\Config\DataInterface', [], [], '', false);
+        $this->date = $this->getMock('Magento\Framework\Stdlib\DateTime\DateTime', [], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->config = $this->objectManagerHelper->getObject(
+            'Magento\Payment\Model\Config',
+            [
+                'scopeConfig' => $this->scopeConfig,
+                'paymentMethodFactory' => $this->paymentMethodFactory,
+                'localeLists' => $this->localeLists,
+                'dataStorage' => $this->dataStorage,
+                'date' => $this->date
+            ]
+        );
+    }
+
+    /**
+     * @param bool $isActive
+     * @dataProvider getActiveMethodsDataProvider
+     */
+    public function testGetActiveMethods($isActive)
+    {
+        $abstractMethod = $this->getMockBuilder(
+            'Magento\Payment\Model\Method\AbstractMethod'
+        )->disableOriginalConstructor()->setMethods(['setId', 'setStore', 'getConfigData'])->getMock();
+        $this->scopeConfig->expects($this->once())->method('getValue')->with(
+            'payment', ScopeInterface::SCOPE_STORE, null
+        )->will($this->returnValue($this->paymentMethodsList));
+        $this->paymentMethodFactory->expects($this->once())->method('create')->with(
+            $this->paymentMethodsList['active_method']['model']
+        )->will($this->returnValue($abstractMethod));
+        $abstractMethod->expects($this->any())->method('setId')->with('active_method')->will(
+            $this->returnValue($abstractMethod)
+        );
+        $abstractMethod->expects($this->any())->method('setStore')->with(null);
+        $abstractMethod->expects($this->any())
+            ->method('getConfigData')
+            ->with('active', $this->isNull())
+            ->will($this->returnValue($isActive));
+        $this->assertEquals($isActive ? ['active_method' => $abstractMethod] : [], $this->config->getActiveMethods());
+    }
+
+    public function getActiveMethodsDataProvider()
+    {
+        return [[true], [false]];
+    }
+
+    public function testGetCcTypes()
+    {
+        $expected = [];
+        $this->dataStorage->expects($this->once())->method('get')->with('credit_cards')->will(
+            $this->returnValue($expected)
+        );
+        $this->assertEquals($expected, $this->config->getCcTypes());
+    }
+
+    public function testGetMethodsInfo()
+    {
+        $expected = [];
+        $this->dataStorage->expects($this->once())->method('get')->with('methods')->will(
+            $this->returnValue($expected)
+        );
+        $this->assertEquals($expected, $this->config->getMethodsInfo());
+    }
+
+    public function testGetGroups()
+    {
+        $expected = [];
+        $this->dataStorage->expects($this->once())->method('get')->with('groups')->will(
+            $this->returnValue($expected)
+        );
+        $this->assertEquals($expected, $this->config->getGroups());
+    }
+
+    public function testGetMonths()
+    {
+        $this->localeLists->expects($this->once())->method('getTranslationList')->with('month')->will(
+            $this->returnValue($this->monthList)
+        );
+        $this->assertEquals($this->expectedMonthList, $this->config->getMonths());
+    }
+
+    public function testGetYears()
+    {
+        $this->date->expects($this->once())->method('date')->with('Y')->will($this->returnValue(self::CURRENT_YEAR));
+        $this->assertEquals($this->_getPreparedYearsList(), $this->config->getYears());
+    }
+
+    /**
+     * Generates expected years list
+     *
+     * @return array
+     */
+    private function _getPreparedYearsList()
+    {
+        $expectedYearsList = [];
+        for ($index = 0; $index <= Config::YEARS_RANGE; $index++) {
+            $year = (int)self::CURRENT_YEAR + $index;
+            $expectedYearsList[$year] = $year;
+        }
+        return $expectedYearsList;
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/InfoTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/InfoTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b68e249709334873e87c5fefb005b6f10411f61
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/InfoTest.php
@@ -0,0 +1,242 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class InfoTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Payment\Model\Info */
+    protected $info;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject */
+    protected $contextMock;
+
+    /** @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject */
+    protected $registryMock;
+
+    /** @var \Magento\Payment\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */
+    protected $paymentHelperMock;
+
+    /** @var \Magento\Framework\Encryption\EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $encryptorInterfaceMock;
+
+    protected function setUp()
+    {
+        $this->contextMock = $this->getMock('Magento\Framework\Model\Context', [], [], '', false);
+        $this->registryMock = $this->getMock('Magento\Framework\Registry');
+        $this->paymentHelperMock = $this->getMock('Magento\Payment\Helper\Data', [], [], '', false);
+        $this->encryptorInterfaceMock = $this->getMock(
+            'Magento\Framework\Encryption\EncryptorInterface',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->info = $this->objectManagerHelper->getObject(
+            'Magento\Payment\Model\Info',
+            [
+                'context' => $this->contextMock,
+                'registry' => $this->registryMock,
+                'paymentData' => $this->paymentHelperMock,
+                'encryptor' => $this->encryptorInterfaceMock
+            ]
+        );
+    }
+
+    /**
+     * @dataProvider ccKeysDataProvider
+     * @param string $keyCc
+     * @param string $keyCcEnc
+     */
+    public function testGetDataCcNumber($keyCc, $keyCcEnc)
+    {
+        // no data was set
+        $this->assertNull($this->info->getData($keyCc));
+
+        // we set encrypted data
+        $this->info->setData($keyCcEnc, $keyCcEnc);
+        $this->encryptorInterfaceMock->expects($this->once())->method('decrypt')->with($keyCcEnc)->will(
+            $this->returnValue($keyCc)
+        );
+        $this->assertEquals($keyCc, $this->info->getData($keyCc));
+    }
+
+    /**
+     * Returns array of Cc keys which needs prepare logic
+     *
+     * @return array
+     */
+    public function ccKeysDataProvider()
+    {
+        return [
+            ['cc_number', 'cc_number_enc'],
+            ['cc_cid', 'cc_cid_enc']
+        ];
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     */
+    public function testGetMethodInstanceException()
+    {
+        $this->info->getMethodInstance();
+    }
+
+    public function testGetMethodInstanceSubstitution()
+    {
+        $code = 'unreal_method';
+        $this->info->setData('method', $code);
+
+        $methodInstance = $this->getMockBuilder(
+            'Magento\Payment\Model\MethodInterface')->disableOriginalConstructor()->setMethods(
+                ['setInfoInstance', 'getCode', 'getFormBlockType', 'getTitle']
+            )->getMock();
+        $this->paymentHelperMock->expects($this->at(0))->method('getMethodInstance')->with($code)->will(
+            $this->returnValue(null)
+        );
+        $this->paymentHelperMock->expects($this->at(1))->method('getMethodInstance')->with(
+            Method\Substitution::CODE
+        )->will($this->returnValue($methodInstance));
+
+        $methodInstance->expects($this->once())->method('setInfoInstance')->with($this->info);
+        $this->assertSame($methodInstance, $this->info->getMethodInstance());
+    }
+
+    public function testGetMethodInstanceRequestedMethod()
+    {
+        $code = 'unreal_method';
+        $this->info->setData('method', $code);
+
+        $methodInstance = $this->getMockBuilder(
+            'Magento\Payment\Model\MethodInterface')->disableOriginalConstructor()->setMethods(
+                ['setInfoInstance', 'getCode', 'getFormBlockType', 'getTitle']
+            )->getMock();
+        $this->paymentHelperMock->expects($this->once())->method('getMethodInstance')->with($code)->will(
+            $this->returnValue($methodInstance)
+        );
+
+        $methodInstance->expects($this->once())->method('setInfoInstance')->with($this->info);
+        $this->assertSame($methodInstance, $this->info->getMethodInstance());
+
+        // as the method is already stored at Info, check that it's not initialized again
+        $this->assertSame($methodInstance, $this->info->getMethodInstance());
+    }
+
+    public function testEncrypt()
+    {
+        $data = 'data';
+        $encryptedData = 'd1a2t3a4';
+
+        $this->encryptorInterfaceMock->expects($this->once())->method('encrypt')->with($data)->will(
+            $this->returnValue($encryptedData)
+        );
+        $this->assertEquals($encryptedData, $this->info->encrypt($data));
+    }
+
+    public function testDecrypt()
+    {
+        $data = 'data';
+        $encryptedData = 'd1a2t3a4';
+
+        $this->encryptorInterfaceMock->expects($this->once())->method('decrypt')->with($encryptedData)->will(
+            $this->returnValue($data)
+        );
+        $this->assertEquals($data, $this->info->decrypt($encryptedData));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     */
+    public function testSetAdditionalInformationException()
+    {
+        $this->info->setAdditionalInformation('object', new \StdClass);
+    }
+
+    /**
+     * @dataProvider additionalInformationDataProvider
+     * @param mixed $key
+     * @param mixed $value
+     */
+    public function testSetAdditionalInformationMultipleTypes($key, $value = null)
+    {
+        $this->info->setAdditionalInformation($key, $value);
+        $this->assertEquals($value ? [$key => $value] : $key, $this->info->getAdditionalInformation());
+    }
+
+    /**
+     * Prepared data for testSetAdditionalInformationMultipleTypes
+     *
+     * @return array
+     */
+    public function additionalInformationDataProvider()
+    {
+        return [
+            [['key1' => 'data1', 'key2' => 'data2'], null],
+            ['key', 'data']
+        ];
+    }
+
+    public function testGetAdditionalInformationByKey()
+    {
+        $key = 'key';
+        $value = 'value';
+        $this->info->setAdditionalInformation($key, $value);
+        $this->assertEquals($value, $this->info->getAdditionalInformation($key));
+    }
+
+    public function testUnsAdditionalInformation()
+    {
+        // set array to additional
+        $data = ['key1' => 'data1', 'key2' => 'data2'];
+        $this->info->setAdditionalInformation($data);
+
+        // unset by key
+        $this->assertEquals(
+            ['key2' => 'data2'],
+            $this->info->unsAdditionalInformation('key1')->getAdditionalInformation()
+        );
+
+        // unset all
+        $this->assertEmpty($this->info->unsAdditionalInformation()->getAdditionalInformation());
+    }
+
+    public function testHasAdditionalInformation()
+    {
+        $this->assertFalse($this->info->hasAdditionalInformation());
+
+        $data = ['key1' => 'data1', 'key2' => 'data2'];
+        $this->info->setAdditionalInformation($data);
+        $this->assertFalse($this->info->hasAdditionalInformation('key3'));
+
+        $this->assertTrue($this->info->hasAdditionalInformation('key2'));
+        $this->assertTrue($this->info->hasAdditionalInformation());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/ObserverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..31688bf3fe407afef094a03451cd0541ca430525
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/ObserverTest.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class ObserverTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Payment\Model\Observer */
+    protected $observer;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    /** @var \Magento\Sales\Model\Order\Config|\PHPUnit_Framework_MockObject_MockObject */
+    protected $orderConfigMock;
+
+    /** @var \Magento\Payment\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
+    protected $paymentConfigMock;
+
+    /** @var \Magento\Core\Model\Resource\Config|\PHPUnit_Framework_MockObject_MockObject */
+    protected $coreResourceConfigMock;
+
+    /** @var \Magento\Framework\Event\Observer|\PHPUnit_Framework_MockObject_MockObject */
+    protected $observerMock;
+
+    /** @var \Magento\Framework\Event|\PHPUnit_Framework_MockObject_MockObject */
+    protected $eventMock;
+
+    const ORDER_STATUS = 'status';
+
+    const METHOD_CODE = 'method_code';
+
+    protected function setUp()
+    {
+        $this->orderConfigMock = $this->getMock('Magento\Sales\Model\Order\Config', [], [], '', false);
+        $this->paymentConfigMock = $this->getMock('Magento\Payment\Model\Config', [], [], '', false);
+        $this->coreResourceConfigMock = $this->getMock('Magento\Core\Model\Resource\Config', [], [], '', false);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->observer = $this->objectManagerHelper->getObject(
+            'Magento\Payment\Model\Observer',
+            [
+                'salesOrderConfig' => $this->orderConfigMock,
+                'paymentConfig' => $this->paymentConfigMock,
+                'resourceConfig' => $this->coreResourceConfigMock
+            ]
+        );
+
+        $this->observerMock = $this->getMockBuilder(
+            'Magento\Framework\Event\Observer'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+    }
+
+    public function testSalesOrderBeforeSaveMethodNotFree()
+    {
+        $this->_prepareEventMockWithMethods(['getOrder']);
+        $neverInvokedMethods = ['canUnhold', 'isCanceled', 'getState', 'hasForcedCanCreditMemo'];
+        $order = $this->_getPreparedOrderMethod(
+            'not_free',
+            $neverInvokedMethods
+        );
+        $this->_prepareNeverInvokedOrderMethods($order, $neverInvokedMethods);
+        $this->eventMock->expects($this->once())->method('getOrder')->will(
+            $this->returnValue($order)
+        );
+
+        $this->observer->salesOrderBeforeSave($this->observerMock);
+    }
+
+    public function testSalesOrderBeforeSaveCantUnhold()
+    {
+        $this->_prepareEventMockWithMethods(['getOrder']);
+        $neverInvokedMethods = ['isCanceled', 'getState', 'hasForcedCanCreditMemo'];
+        $order = $this->_getPreparedOrderMethod('free', ['canUnhold'] + $neverInvokedMethods);
+        $this->_prepareNeverInvokedOrderMethods($order, $neverInvokedMethods);
+        $this->eventMock->expects($this->once())->method('getOrder')->will(
+            $this->returnValue($order)
+        );
+        $order->expects($this->once())->method('canUnhold')->will($this->returnValue(true));
+        $this->observer->salesOrderBeforeSave($this->observerMock);
+    }
+
+    public function testSalesOrderBeforeSaveIsCanceled()
+    {
+        // check first canceled state
+        $this->_prepareEventMockWithMethods(['getOrder']);
+        $neverInvokedMethods = ['getState', 'hasForcedCanCreditMemo'];
+        $order = $this->_getPreparedOrderMethod('free', ['canUnhold', 'isCanceled'] + $neverInvokedMethods);
+        $this->_prepareNeverInvokedOrderMethods($order, $neverInvokedMethods);
+        $this->eventMock->expects($this->once())->method('getOrder')->will(
+            $this->returnValue($order)
+        );
+        $order->expects($this->once())->method('canUnhold')->will($this->returnValue(false));
+
+        $order->expects($this->once())->method('isCanceled')->will($this->returnValue(true));
+
+        $this->observer->salesOrderBeforeSave($this->observerMock);
+    }
+
+    public function testSalesOrderBeforeSaveIsClosed()
+    {
+        // check closed state at second
+        $this->_prepareEventMockWithMethods(['getOrder']);
+        $neverInvokedMethods = ['hasForcedCanCreditMemo'];
+        $order = $this->_getPreparedOrderMethod('free', ['canUnhold', 'isCanceled', 'getState'] + $neverInvokedMethods);
+        $this->_prepareNeverInvokedOrderMethods($order, $neverInvokedMethods);
+        $this->eventMock->expects($this->once())->method('getOrder')->will(
+            $this->returnValue($order)
+        );
+        $order->expects($this->once())->method('canUnhold')->will($this->returnValue(false));
+
+        $order->expects($this->once())->method('isCanceled')->will($this->returnValue(false));
+        $order->expects($this->once())->method('getState')->will(
+            $this->returnValue(\Magento\Sales\Model\Order::STATE_CLOSED)
+        );
+        $this->observer->salesOrderBeforeSave($this->observerMock);
+    }
+
+    public function testSalesOrderBeforeSaveSetForced()
+    {
+        // check closed state at second
+        $this->_prepareEventMockWithMethods(['getOrder']);
+        $order = $this->_getPreparedOrderMethod(
+            'free',
+            ['canUnhold', 'isCanceled', 'getState', 'setForcedCanCreditmemo', 'hasForcedCanCreditmemo']
+        );
+        $this->eventMock->expects($this->once())->method('getOrder')->will(
+            $this->returnValue($order)
+        );
+        $order->expects($this->once())->method('canUnhold')->will($this->returnValue(false));
+
+        $order->expects($this->once())->method('isCanceled')->will($this->returnValue(false));
+        $order->expects($this->once())->method('getState')->will(
+            $this->returnValue('not_closed_state')
+        );
+        $order->expects($this->once())->method('hasForcedCanCreditmemo')->will($this->returnValue(false));
+        $order->expects($this->once())->method('setForcedCanCreditmemo')->will($this->returnValue(true));
+
+        $this->observer->salesOrderBeforeSave($this->observerMock);
+    }
+
+    public function testUpdateOrderStatusForPaymentMethodsNotNewState()
+    {
+        $this->_prepareEventMockWithMethods(['getState']);
+        $this->eventMock->expects($this->once())->method('getState')->will($this->returnValue('NotNewState'));
+        $this->observer->updateOrderStatusForPaymentMethods($this->observerMock);
+    }
+
+    public function testUpdateOrderStatusForPaymentMethodsNewState()
+    {
+        $this->_prepareEventMockWithMethods(['getState', 'getStatus']);
+        $this->eventMock->expects($this->once())->method('getState')->will(
+            $this->returnValue(\Magento\Sales\Model\Order::STATE_NEW)
+        );
+        $this->eventMock->expects($this->once())->method('getStatus')->will(
+            $this->returnValue(self::ORDER_STATUS)
+        );
+
+        $defaultStatus = 'defaultStatus';
+        $this->orderConfigMock->expects($this->once())->method('getStateDefaultStatus')->with(
+            \Magento\Sales\Model\Order::STATE_NEW
+        )->will($this->returnValue($defaultStatus));
+
+        $this->paymentConfigMock->expects($this->once())->method('getActiveMethods')->will(
+            $this->returnValue($this->_getPreparedActiveMethods())
+        );
+
+        $this->coreResourceConfigMock->expects($this->once())->method('saveConfig')->with(
+            'payment/' . self::METHOD_CODE . '/order_status',
+            $defaultStatus,
+            'default',
+            0
+        );
+        $this->observer->updateOrderStatusForPaymentMethods($this->observerMock);
+    }
+
+    /**
+     * Prepares EventMock with set of methods
+     *
+     * @param $methodsList
+     */
+    private function _prepareEventMockWithMethods($methodsList)
+    {
+        $this->eventMock = $this->getMockBuilder(
+            'Magento\Framework\Event'
+        )->disableOriginalConstructor()->setMethods($methodsList)->getMock();
+        $this->observerMock->expects($this->any())->method('getEvent')->will($this->returnValue($this->eventMock));
+    }
+
+    /**
+     * Prepares Order with MethodInterface
+     *
+     * @param string $methodCode
+     * @param array $orderMethods
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    private function _getPreparedOrderMethod($methodCode, $orderMethods = [])
+    {
+        $order = $this->getMockBuilder('Magento\Sales\Model\Order')->disableOriginalConstructor()->setMethods(
+            array_merge(['__wakeup', 'getPayment'], $orderMethods)
+        )->getMock();
+        $paymentMock = $this->getMockBuilder(
+            'Magento\Sales\Model\Order\Payment'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $order->expects($this->once())->method('getPayment')->will($this->returnValue($paymentMock));
+        $methodInstance = $this->getMockBuilder(
+            'Magento\Payment\Model\MethodInterface'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $paymentMock->expects($this->once())->method('getMethodInstance')->will($this->returnValue($methodInstance));
+        $methodInstance->expects($this->once())->method('getCode')->will($this->returnValue($methodCode));
+        return $order;
+    }
+
+    /**
+     * Return mocked data of getActiveMethods
+     *
+     * @return array
+     */
+    private function _getPreparedActiveMethods()
+    {
+        $mockedMethods = ['getCode', 'getFormBlockType', 'getTitle', 'getConfigData'];
+        $method1 = $this->getMockBuilder(
+            'Magento\Payment\Model\MethodInterface'
+        )->disableOriginalConstructor()->setMethods($mockedMethods)->getMock();
+        $method1->expects($this->once())->method('getConfigData')->with('order_status')->will(
+            $this->returnValue(self::ORDER_STATUS)
+        );
+        $method1->expects($this->once())->method('getCode')->will(
+            $this->returnValue(self::METHOD_CODE)
+        );
+
+        $method2 = $this->getMockBuilder(
+            'Magento\Payment\Model\MethodInterface'
+        )->disableOriginalConstructor()->setMethods($mockedMethods)->getMock();
+        $method2->expects($this->once())->method('getConfigData')->with('order_status')->will(
+            $this->returnValue('not_a_status')
+        );
+
+        return [$method1, $method2];
+    }
+
+    /**
+     * Sets never expectation for order methods listed in $method
+     *
+     * @param \PHPUnit_Framework_MockObject_MockObject $order
+     * @param array $methods
+     */
+    private function _prepareNeverInvokedOrderMethods(\PHPUnit_Framework_MockObject_MockObject $order, $methods = [])
+    {
+        foreach ($methods as $method) {
+            $order->expects($this->never())->method($method);
+        }
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Source/CctypeTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Source/CctypeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..82fafc7357bd23c2a22f2c03869fe72d8283b048
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Source/CctypeTest.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\Payment\Model\Source;
+
+class CctypeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Payment config model
+     *
+     * @var \Magento\Payment\Model\Config | \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_paymentConfig;
+
+    /**
+     * @var Cctype
+     */
+    protected $_model;
+
+    /**
+     * List of allowed Cc types
+     *
+     * @var array
+     */
+    protected $_allowedTypes = ['allowed_cc_type'];
+
+    /**
+     * Cc type array
+     *
+     * @var array
+     */
+    protected $_cctypesArray = ['allowed_cc_type' => 'name'];
+
+    /**
+     * Expected cctype array after toOptionArray call
+     *
+     * @var array
+     */
+    protected $_expectedToOptionsArray = [['value' => 'allowed_cc_type', 'label' => 'name']];
+
+    public function setUp()
+    {
+        $this->_paymentConfig = $this->getMockBuilder(
+            'Magento\Payment\Model\Config'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+
+        $this->_model = new Cctype($this->_paymentConfig);
+    }
+
+    public function testSetAndGetAllowedTypes()
+    {
+        $model = $this->_model->setAllowedTypes($this->_allowedTypes);
+        $this->assertEquals($this->_allowedTypes, $model->getAllowedTypes());
+    }
+
+    public function testToOptionArrayEmptyAllowed()
+    {
+        $this->_preparePaymentConfig();
+        $this->assertEquals($this->_expectedToOptionsArray, $this->_model->toOptionArray());
+    }
+
+    public function testToOptionArrayNotEmptyAllowed()
+    {
+        $this->_preparePaymentConfig();
+        $this->_model->setAllowedTypes($this->_allowedTypes);
+        $this->assertEquals($this->_expectedToOptionsArray, $this->_model->toOptionArray());
+    }
+
+    private function _preparePaymentConfig()
+    {
+        $this->_paymentConfig->expects($this->once())->method('getCcTypes')->will(
+            $this->returnValue($this->_cctypesArray)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Payment/Model/Source/InvoiceTest.php b/dev/tests/unit/testsuite/Magento/Payment/Model/Source/InvoiceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff7c47fe5ca000f239809542a1b9425d56ea3f71
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Payment/Model/Source/InvoiceTest.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Payment\Model\Source;
+
+class InvoiceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Invoice
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $this->_model = new Invoice();
+    }
+
+    public function testToOptionArray()
+    {
+        $expectedResult = array(
+            array(
+                'value' => \Magento\Payment\Model\Method\AbstractMethod::ACTION_AUTHORIZE_CAPTURE,
+                'label' => __('Yes')
+            ),
+            array('value' => '', 'label' => __('No'))
+        );
+
+        $this->assertEquals($expectedResult, $this->_model->toOptionArray());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/Store/SwitcherPluginTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/Store/SwitcherPluginTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e37385c2279ee069281effd0561de3fe10340f4
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/Store/SwitcherPluginTest.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\Paypal\Block\Adminhtml\Store;
+
+class SwitcherPluginTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var SwitcherPlugin
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $this->_model = new SwitcherPlugin();
+    }
+
+    /**
+     * @param null|string $countryParam
+     * @param array $getUrlParams
+     * @dataProvider aroundGetUrlDataProvider
+     */
+    public function testAroundGetUrl($countryParam, $getUrlParams)
+    {
+        $subjectRequest = $this->getMockForAbstractClass('Magento\Framework\App\RequestInterface');
+        $subjectRequest->expects($this->once())
+            ->method('getParam')
+            ->with(\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY)
+            ->will($this->returnValue($countryParam));
+        $subject = $this->getMock('Magento\Backend\Block\Store\Switcher', ['getRequest'], [], '', false);
+        $subject->expects($this->any())->method('getRequest')->will($this->returnValue($subjectRequest));
+        $getUrl = function ($route, $params) {
+            return [$route, $params];
+        };
+        $this->assertEquals(['', $getUrlParams], $this->_model->aroundGetUrl($subject, $getUrl, '', []));
+    }
+
+    public function aroundGetUrlDataProvider()
+    {
+        return [
+            ['any value', [\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY => null]],
+            [null, []]
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Field/CountryTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Field/CountryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..401be38904deb97181c658a900352794b0ef1481
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Field/CountryTest.php
@@ -0,0 +1,147 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Block\Adminhtml\System\Config\Field;
+
+class CountryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Country
+     */
+    protected $_model;
+
+    /**
+     * @var \Magento\Framework\Data\Form\Element\AbstractElement
+     */
+    protected $_element;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_request;
+
+    /**
+     * @var \Magento\Framework\View\Helper\Js|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_jsHelper;
+
+    /**
+     * @var \Magento\Backend\Model\Url|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_url;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_element = $this->getMockForAbstractClass(
+            'Magento\Framework\Data\Form\Element\AbstractElement',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getHtmlId', 'getElementHtml', 'getName']
+        );
+        $this->_element->expects($this->any())
+            ->method('getHtmlId')
+            ->will($this->returnValue('html id'));
+        $this->_element->expects($this->any())
+            ->method('getElementHtml')
+            ->will($this->returnValue('element html'));
+        $this->_element->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue('name'));
+        $this->_request = $this->getMockForAbstractClass('Magento\Framework\App\RequestInterface');
+        $this->_jsHelper = $this->getMock('Magento\Framework\View\Helper\Js', [], [], '', false);
+        $this->_url = $this->getMock('Magento\Backend\Model\Url', [], [], '', false);
+        $this->_model = $helper->getObject(
+            'Magento\Paypal\Block\Adminhtml\System\Config\Field\Country',
+            ['request' => $this->_request, 'jsHelper' => $this->_jsHelper, 'url' => $this->_url]
+        );
+    }
+
+    /**
+     * @param null|string $requestCountry
+     * @param null|string $requestDefaultCountry
+     * @param bool $canUseDefault
+     * @param bool $inherit
+     * @dataProvider renderDataProvider
+     */
+    public function testRender($requestCountry, $requestDefaultCountry, $canUseDefault, $inherit)
+    {
+        $this->_request->expects($this->any())
+            ->method('getParam')
+            ->will($this->returnCallback(function ($param) use ($requestCountry, $requestDefaultCountry) {
+                if ($param == \Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY) {
+                    return $requestCountry;
+                }
+                if ($param == Country::REQUEST_PARAM_DEFAULT_COUNTRY) {
+                    return $requestDefaultCountry;
+                }
+                return $param;
+            }));
+        $this->_element->setInherit($inherit);
+        $this->_element->setCanUseDefaultValue($canUseDefault);
+        $constraints = [
+            new \PHPUnit_Framework_Constraint_StringContains('document.observe("dom:loaded", function() {'),
+            new \PHPUnit_Framework_Constraint_StringContains(
+                '$("' . $this->_element->getHtmlId() . '").observe("change", function () {'
+            )
+        ];
+        if ($canUseDefault && ($requestCountry == 'US') && $requestDefaultCountry) {
+            $constraints[] = new \PHPUnit_Framework_Constraint_StringContains(
+                '$("' . $this->_element->getHtmlId() . '_inherit").observe("click", function () {'
+            );
+        }
+        $this->_jsHelper->expects($this->once())
+            ->method('getScript')
+            ->with(new \PHPUnit_Framework_Constraint_And($constraints));
+        $this->_url->expects($this->once())
+            ->method('getUrl')
+            ->with(
+                '*/*/*',
+                [
+                    'section' => 'section',
+                    'website' => 'website',
+                    'store' => 'store',
+                    \Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY => '__country__'
+                ]
+            );
+        $this->_model->render($this->_element);
+    }
+
+    public function renderDataProvider()
+    {
+        return [
+            [null, null, false, false],
+            [null, null, true, true],
+            [null, null, true, false],
+            ['IT', null, true, false],
+            ['IT', null, true, true],
+            ['IT', 'GB', true, false],
+            ['US', 'GB', true, true],
+            ['US', 'GB', true, false],
+            ['US', null, true, false],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/GroupTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/GroupTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..61c40926e1e1e3b7f9482680bfd5ce49a3a62cb9
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/GroupTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Block\Adminhtml\System\Config\Fieldset;
+
+class GroupTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Group
+     */
+    protected $_model;
+
+    /**
+     * @var \Magento\Framework\Data\Form\Element\AbstractElement
+     */
+    protected $_element;
+
+    /**
+     * @var \Magento\Backend\Model\Auth\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_authSession;
+
+    /**
+     * @var \Magento\User\Model\User|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_user;
+
+    /**
+     * @var \Magento\Backend\Model\Config\Structure\Element\Group|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_group;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_group = $this->getMock('Magento\Backend\Model\Config\Structure\Element\Group', [], [], '', false);
+        $this->_element = $this->getMockForAbstractClass(
+            'Magento\Framework\Data\Form\Element\AbstractElement',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getHtmlId', 'getElementHtml', 'getName', 'getElements', 'getId']
+        );
+        $this->_element->expects($this->any())
+            ->method('getHtmlId')
+            ->will($this->returnValue('html id'));
+        $this->_element->expects($this->any())
+            ->method('getElementHtml')
+            ->will($this->returnValue('element html'));
+        $this->_element->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue('name'));
+        $this->_element->expects($this->any())
+            ->method('getElements')
+            ->will($this->returnValue([]));
+        $this->_element->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue('id'));
+        $this->_user = $this->getMock('Magento\User\Model\User', [], [], '', false);
+        $this->_authSession = $this->getMock('Magento\Backend\Model\Auth\Session', [], [], '', false);
+        $this->_authSession->expects($this->any())
+            ->method('__call')
+            ->with('getUser')
+            ->will($this->returnValue($this->_user));
+        $this->_model = $helper->getObject(
+            'Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Group',
+            ['authSession' => $this->_authSession]
+        );
+        $this->_model->setGroup($this->_group);
+    }
+
+    /**
+     * @param mixed $expanded
+     * @param int $expected
+     * @dataProvider isCollapseStateDataProvider
+     */
+    public function testIsCollapseState($expanded, $expected)
+    {
+        $this->_user->setExtra(['configState' => []]);
+        $this->_element->setGroup(isset($expanded) ? ['expanded' => $expanded] : []);
+        $html = $this->_model->render($this->_element);
+        $this->assertContains(
+            '<input id="' . $this->_element->getHtmlId() . '-state" name="config_state['
+                . $this->_element->getId() . ']" type="hidden" value="' . $expected . '" />',
+            $html
+        );
+    }
+
+    public function isCollapseStateDataProvider()
+    {
+        return [
+            [null, 0],
+            [false, 0],
+            ['', 0],
+            [1, 1],
+            ['1', 1],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/PaymentTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/PaymentTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..50f5dd643998577d0a92ff681d31d2027bc74d8d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Block/Adminhtml/System/Config/Fieldset/PaymentTest.php
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Block\Adminhtml\System\Config\Fieldset;
+
+class PaymentTest extends \PHPUnit_Framework_TestCase
+{
+    /**#@+
+     * Activity config path
+     */
+    const CONFIG_PATH_ACTIVE = 'payment/path/active';
+    const CONFIG_PATH_NOT_ACTIVE = 'payment/path/not-active';
+    /**#@-*/
+
+    /**
+     * @var Payment
+     */
+    protected $_model;
+
+    /**
+     * @var \Magento\Framework\Data\Form\Element\AbstractElement
+     */
+    protected $_element;
+
+    /**
+     * @var \Magento\Backend\Model\Config\Structure\Element\Group|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_group;
+
+    /**
+     * @var \Magento\Backend\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_backendConfig;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_group = $this->getMock('Magento\Backend\Model\Config\Structure\Element\Group', [], [], '', false);
+        $this->_element = $this->getMockForAbstractClass(
+            'Magento\Framework\Data\Form\Element\AbstractElement',
+            [],
+            '',
+            false,
+            true,
+            true,
+            ['getHtmlId', 'getElementHtml', 'getName', 'getElements', 'getId']
+        );
+        $this->_element->expects($this->any())
+            ->method('getHtmlId')
+            ->will($this->returnValue('html id'));
+        $this->_element->expects($this->any())
+            ->method('getElementHtml')
+            ->will($this->returnValue('element html'));
+        $this->_element->expects($this->any())
+            ->method('getName')
+            ->will($this->returnValue('name'));
+        $this->_element->expects($this->any())
+            ->method('getElements')
+            ->will($this->returnValue([]));
+        $this->_element->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue('id'));
+        $this->_backendConfig = $this->getMock('Magento\Backend\Model\Config', [], [], '', false);
+        $this->_model = $helper->getObject(
+            'Magento\Paypal\Block\Adminhtml\System\Config\Fieldset\Payment',
+            ['backendConfig' => $this->_backendConfig]
+        );
+        $this->_model->setGroup($this->_group);
+    }
+
+    /**
+     * @dataProvider isPaymentEnabledDataProvider
+     */
+    public function testIsPaymentEnabled($groupConfig, $expected)
+    {
+        $this->_element->setGroup($groupConfig);
+        $this->_backendConfig->expects($this->any())
+            ->method('getConfigDataValue')
+            ->will($this->returnValueMap(
+                [[self::CONFIG_PATH_ACTIVE, null, null, '1'], [self::CONFIG_PATH_NOT_ACTIVE, null, null, '0']]
+            ));
+        $html = $this->_model->render($this->_element);
+        $this->assertContains($expected, $html);
+    }
+
+    public function isPaymentEnabledDataProvider()
+    {
+        return [
+            [[], ' class="section-config with-button">'],
+            [['fieldset_css' => 'any-css'], ' class="section-config any-css with-button">'],
+            [['activity_path' => self::CONFIG_PATH_ACTIVE], ' class="section-config with-button enabled">'],
+            [['activity_path' => self::CONFIG_PATH_NOT_ACTIVE], ' class="section-config with-button">'],
+            [['activity_path' => [self::CONFIG_PATH_ACTIVE]], ' class="section-config with-button enabled">'],
+            [['activity_path' => [self::CONFIG_PATH_NOT_ACTIVE]], ' class="section-config with-button">'],
+            [
+                ['activity_path' => [self::CONFIG_PATH_ACTIVE, self::CONFIG_PATH_NOT_ACTIVE]],
+                ' class="section-config with-button enabled">'
+            ],
+            [
+                ['activity_path' => self::CONFIG_PATH_ACTIVE, 'fieldset_css' => 'any-css'],
+                ' class="section-config any-css with-button enabled">'
+            ],
+            [
+                ['activity_path' => self::CONFIG_PATH_NOT_ACTIVE, 'fieldset_css' => 'any-css'],
+                ' class="section-config any-css with-button">'
+            ],
+            [
+                ['activity_path' => [self::CONFIG_PATH_ACTIVE], 'fieldset_css' => 'any-css'],
+                ' class="section-config any-css with-button enabled">'
+            ],
+            [
+                ['activity_path' => [self::CONFIG_PATH_NOT_ACTIVE], 'fieldset_css' => 'any-css'],
+                ' class="section-config any-css with-button">'
+            ],
+            [
+                [
+                    'activity_path' => [self::CONFIG_PATH_ACTIVE, self::CONFIG_PATH_NOT_ACTIVE],
+                    'fieldset_css' => 'any-css'
+                ],
+                ' class="section-config any-css with-button enabled">'
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Helper/BackendTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Helper/BackendTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..92e487637b75ae19bd69fb888283051532c2e9ca
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Helper/BackendTest.php
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Helper;
+
+class BackendTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_request;
+
+    /**
+     * @var \Magento\Core\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_coreHelper;
+
+    /**
+     * @var \Magento\Backend\Model\Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_backendConfig;
+
+    /**
+     * @var \Magento\Paypal\Helper\Backend
+     */
+    protected $_helper;
+
+    public function setUp()
+    {
+        $this->_request = $this->getMockForAbstractClass('Magento\Framework\App\RequestInterface');
+        $this->_coreHelper = $this->getMock('Magento\Core\Helper\Data', [], [], '', false);
+        $this->_backendConfig = $this->getMock('Magento\Backend\Model\Config', [], [], '', false);
+
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_helper = $objectManager->getObject(
+            'Magento\Paypal\Helper\Backend',
+            [
+                'httpRequest' => $this->_request,
+                'coreHelper' => $this->_coreHelper,
+                'backendConfig' => $this->_backendConfig
+            ]
+        );
+    }
+
+    public function testGetConfigurationCountryCodeFromRequest()
+    {
+        $this->_configurationCountryCodePrepareRequest('US');
+        $this->_configurationCountryCodeAssertResult('US');
+    }
+
+    /**
+     * @param string|null $request
+     * @dataProvider getConfigurationCountryCodeFromConfigDataProvider
+     */
+    public function testGetConfigurationCountryCodeFromConfig($request)
+    {
+        $this->_configurationCountryCodePrepareRequest($request);
+        $this->_configurationCountryCodePrepareConfig('GB');
+        $this->_configurationCountryCodeAssertResult('GB');
+    }
+
+    public function getConfigurationCountryCodeFromConfigDataProvider()
+    {
+        return [
+            [null],
+            ['not country code'],
+        ];
+    }
+
+    /**
+     * @param string|null $request
+     * @param string|null|false $config
+     * @param string|null $default
+     * @dataProvider getConfigurationCountryCodeFromDefaultDataProvider
+     */
+    public function testGetConfigurationCountryCodeFromDefault($request, $config, $default)
+    {
+        $this->_configurationCountryCodePrepareRequest($request);
+        $this->_configurationCountryCodePrepareConfig($config);
+        $this->_coreHelper->expects($this->once())
+            ->method('getDefaultCountry')
+            ->will($this->returnValue($default));
+        $this->_configurationCountryCodeAssertResult($default);
+    }
+
+    public function getConfigurationCountryCodeFromDefaultDataProvider()
+    {
+        return [
+            [null, false, 'DE'],
+            ['not country code', false, 'DE'],
+            ['not country code', '', 'any final result']
+        ];
+    }
+
+    /**
+     * Prepare request for test
+     *
+     * @param string|null $request
+     */
+    private function _configurationCountryCodePrepareRequest($request)
+    {
+        $this->_request->expects($this->once())
+            ->method('getParam')
+            ->with(\Magento\Paypal\Model\Config\StructurePlugin::REQUEST_PARAM_COUNTRY)
+            ->will($this->returnValue($request));
+    }
+
+    /**
+     * Prepare backend config for test
+     *
+     * @param string|null|false $config
+     */
+    private function _configurationCountryCodePrepareConfig($config)
+    {
+        $this->_backendConfig->expects($this->once())
+            ->method('getConfigDataValue')
+            ->with(\Magento\Paypal\Block\Adminhtml\System\Config\Field\Country::FIELD_CONFIG_PATH)
+            ->will($this->returnValue($config));
+    }
+
+    /**
+     * Assert result of getConfigurationCountryCode method
+     *
+     * @param string $expected
+     */
+    private function _configurationCountryCodeAssertResult($expected)
+    {
+        $this->assertEquals($expected, $this->_helper->getConfigurationCountryCode());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/Config/Structure/Element/FieldPluginTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/Config/Structure/Element/FieldPluginTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e77bb080da7c0e8aa250d68103bfd4f540deb17c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/Config/Structure/Element/FieldPluginTest.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\Paypal\Model\Config\Structure\Element;
+
+class FieldPluginTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var FieldPlugin */
+    protected $model;
+
+    /** @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject */
+    protected $request;
+
+    /** @var  \Magento\Backend\Model\Config\Structure\Element\Field|\PHPUnit_Framework_MockObject_MockObject */
+    protected $subject;
+
+    protected function setUp()
+    {
+        $this->request = $this->getMockForAbstractClass('Magento\Framework\App\RequestInterface');
+        $this->subject = $this->getMock('Magento\Backend\Model\Config\Structure\Element\Field', [], [], '', false);
+
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->model = $helper->getObject(
+            'Magento\Paypal\Model\Config\Structure\Element\FieldPlugin',
+            ['request' => $this->request]
+        );
+    }
+
+    public function testAroundGetConfigPathHasResult()
+    {
+        $someResult = 'some result';
+        $callback = function () use ($someResult) {
+            return $someResult;
+        };
+        $this->assertEquals($someResult, $this->model->aroundGetConfigPath($this->subject, $callback));
+    }
+
+    public function testAroundGetConfigPathNonPaymentSection()
+    {
+        $callback = function () {
+            return null;
+        };
+        $this->request->expects($this->once())
+            ->method('getParam')
+            ->with('section')
+            ->will($this->returnValue('non-payment'));
+        $this->assertNull($this->model->aroundGetConfigPath($this->subject, $callback));
+    }
+
+    /**
+     * @param string $subjectPath
+     * @param string $expectedConfigPath
+     * @dataProvider aroundGetConfigPathDataProvider
+     */
+    public function testAroundGetConfigPath($subjectPath, $expectedConfigPath)
+    {
+        $callback = function () {
+            return null;
+        };
+        $this->request->expects($this->once())
+            ->method('getParam')
+            ->with('section')
+            ->will($this->returnValue('payment'));
+        $this->subject->expects($this->once())
+            ->method('getPath')
+            ->will($this->returnValue($subjectPath));
+        $this->assertEquals($expectedConfigPath, $this->model->aroundGetConfigPath($this->subject, $callback));
+    }
+
+    public function aroundGetConfigPathDataProvider()
+    {
+        return [
+            ['payment_us/group/field', 'payment/group/field'],
+            ['payment_other/group/field', 'payment/group/field'],
+            ['payment_us', 'payment_us'],
+            ['payment_wrong_country/group/field', 'payment_wrong_country/group/field'],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/Config/StructurePluginTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/Config/StructurePluginTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..413ae0e44934b4c9705bd6cf8080fce669e65735
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/Config/StructurePluginTest.php
@@ -0,0 +1,222 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Paypal\Model\Config;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class StructurePluginTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Paypal\Model\Config\StructurePlugin */
+    protected $_model;
+
+    /** @var \Magento\Backend\Model\Config\ScopeDefiner|\PHPUnit_Framework_MockObject_MockObject */
+    protected $_scopeDefiner;
+
+    /** @var \Magento\Paypal\Helper\Backend|\PHPUnit_Framework_MockObject_MockObject */
+    protected $_helper;
+
+    protected function setUp()
+    {
+        $this->_scopeDefiner = $this->getMock('Magento\Backend\Model\Config\ScopeDefiner', [], [], '', false);
+        $this->_helper = $this->getMock('Magento\Paypal\Helper\Backend', [], [], '', false);
+
+        $objectManagerHelper = new ObjectManagerHelper($this);
+        $this->_model = $objectManagerHelper->getObject(
+            'Magento\Paypal\Model\Config\StructurePlugin',
+            ['scopeDefiner' => $this->_scopeDefiner, 'helper' => $this->_helper]
+        );
+    }
+
+    public function testGetPaypalConfigCountriesWithOther()
+    {
+        $countries = StructurePlugin::getPaypalConfigCountries(true);
+        $this->assertContains('payment_us', $countries);
+        $this->assertContains('payment_other', $countries);
+    }
+
+    public function testGetPaypalConfigCountries()
+    {
+        $countries = StructurePlugin::getPaypalConfigCountries(false);
+        $this->assertContains('payment_us', $countries);
+        $this->assertNotContains('payment_other', $countries);
+    }
+
+    /**
+     * @param array $pathParts
+     * @param bool $returnResult
+     * @dataProvider aroundGetElementByPathPartsNonPaymentDataProvider
+     */
+    public function testAroundGetElementByPathPartsNonPayment($pathParts, $returnResult)
+    {
+        $result = $returnResult
+            ? $this->getMockForAbstractClass('Magento\Backend\Model\Config\Structure\ElementInterface')
+            : null;
+        $this->_aroundGetElementByPathPartsAssertResult(
+            $result,
+            $this->_getElementByPathPartsCallback($pathParts, $result),
+            $pathParts
+        );
+    }
+
+    public function aroundGetElementByPathPartsNonPaymentDataProvider()
+    {
+        return [
+            [['non-payment', 'group1', 'group2', 'field'], true],
+            [['non-payment'], true],
+            [['non-payment', 'group1', 'group2', 'field'], false],
+            [['non-payment'], false],
+        ];
+    }
+
+    /**
+     * @param array $pathParts
+     * @param string $countryCode
+     * @param array $expectedPathParts
+     * @dataProvider aroundGetElementByPathPartsDataProvider
+     */
+    public function testAroundGetElementByPathPartsNoResult($pathParts, $countryCode, $expectedPathParts)
+    {
+        $this->_getElementByPathPartsPrepareHelper($countryCode);
+        $this->_aroundGetElementByPathPartsAssertResult(
+            null,
+            $this->_getElementByPathPartsCallback($expectedPathParts, null),
+            $pathParts
+        );
+    }
+
+    /**
+     * @param array $pathParts
+     * @param string $countryCode
+     * @param array $expectedPathParts
+     * @dataProvider aroundGetElementByPathPartsDataProvider
+     */
+    public function testAroundGetElementByPathParts($pathParts, $countryCode, $expectedPathParts)
+    {
+        $this->_getElementByPathPartsPrepareHelper($countryCode);
+        $result = $this->getMockForAbstractClass('Magento\Backend\Model\Config\Structure\ElementInterface');
+        $this->_aroundGetElementByPathPartsAssertResult(
+            $result,
+            $this->_getElementByPathPartsCallback($expectedPathParts, $result),
+            $pathParts
+        );
+    }
+
+    public function aroundGetElementByPathPartsDataProvider()
+    {
+        return [
+            [
+                ['payment', 'group1', 'group2', 'field'],
+                'any',
+                ['payment_other', 'group1', 'group2', 'field']
+            ],
+            [
+                ['payment', 'group1', 'group2', 'field'],
+                'DE',
+                ['payment_de', 'group1', 'group2', 'field']
+            ],
+        ];
+    }
+
+    /**
+     * @param array $pathParts
+     * @param string $countryCode
+     * @param array $expectedPathParts
+     * @dataProvider aroundGetSectionByPathPartsDataProvider
+     */
+    public function testAroundGetSectionByPathParts($pathParts, $countryCode, $expectedPathParts)
+    {
+        $this->_getElementByPathPartsPrepareHelper($countryCode);
+        $result = $this->getMock('Magento\Backend\Model\Config\Structure\Element\Section', [], [], '', false);
+        $self = $this;
+        $getElementByPathParts = function ($pathParts) use ($self, $expectedPathParts, $result) {
+            $self->assertEquals($expectedPathParts, $pathParts);
+            $scope = 'any scope';
+            $self->_scopeDefiner->expects($self->once())
+                ->method('getScope')
+                ->will($self->returnValue($scope));
+            $result->expects($self->once())
+                ->method('getData')
+                ->will($self->returnValue([]));
+            $result->expects($self->once())
+                ->method('setData')
+                ->with(['showInDefault' => true, 'showInWebsite' => true, 'showInStore' => true], $scope)
+                ->will($self->returnSelf());
+            return $result;
+        };
+        $this->_aroundGetElementByPathPartsAssertResult($result, $getElementByPathParts, $pathParts);
+    }
+
+    public function aroundGetSectionByPathPartsDataProvider()
+    {
+        return [
+            [['payment'], 'GB', ['payment_gb']],
+            [['payment'], 'any', ['payment_other']],
+        ];
+    }
+
+    /**
+     * Assert result of aroundGetElementByPathParts method
+     *
+     * @param \PHPUnit_Framework_MockObject_MockObject|null $result
+     * @param \Closure $getElementByPathParts
+     * @param array $pathParts
+     */
+    private function _aroundGetElementByPathPartsAssertResult($result, $getElementByPathParts, $pathParts)
+    {
+        $this->assertEquals($result, $this->_model->aroundGetElementByPathParts(
+            $this->getMock('Magento\Backend\Model\Config\Structure', [], [], '', false),
+            $getElementByPathParts,
+            $pathParts
+        ));
+    }
+
+    /**
+     * Get callback for aroundGetElementByPathParts method
+     *
+     * @param array $expectedPathParts
+     * @param \PHPUnit_Framework_MockObject_MockObject|null $result
+     * @return \Closure
+     */
+    private function _getElementByPathPartsCallback($expectedPathParts, $result)
+    {
+        $self = $this;
+        return function ($pathParts) use ($self, $expectedPathParts, $result) {
+            $self->assertEquals($expectedPathParts, $pathParts);
+            return $result;
+        };
+    }
+
+    /**
+     * Prepare helper for test
+     *
+     * @param string $countryCode
+     */
+    private function _getElementByPathPartsPrepareHelper($countryCode)
+    {
+        $this->_helper->expects($this->once())
+            ->method('getConfigurationCountryCode')
+            ->will($this->returnValue($countryCode));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e64f6667d711c32d557f0e9228d5ee39fb38eeb7
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/ConfigTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Model;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Config
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_model = $helper->getObject('Magento\Paypal\Model\Config');
+    }
+
+    public function testGetCountryMethods()
+    {
+        $this->assertNotContains('payflow_direct', $this->_model->getCountryMethods('GB'));
+        $this->assertContains(Config::METHOD_WPP_PE_EXPRESS, $this->_model->getCountryMethods('CA'));
+        $this->assertNotContains(Config::METHOD_WPP_PE_EXPRESS, $this->_model->getCountryMethods('GB'));
+        $this->assertContains(Config::METHOD_WPP_PE_EXPRESS, $this->_model->getCountryMethods('CA'));
+        $this->assertContains(Config::METHOD_WPP_EXPRESS, $this->_model->getCountryMethods('DE'));
+        $this->assertContains(Config::METHOD_BILLING_AGREEMENT, $this->_model->getCountryMethods('DE'));
+    }
+
+    public function testGetBuildNotationCode()
+    {
+        $this->_model->setMethod('payflow_direct');
+        $this->assertEquals('Magento_Cart_WPP_some-country', $this->_model->getBuildNotationCode('some-country'));
+    }
+
+    public function testIsMethodActive()
+    {
+        $this->assertFalse($this->_model->isMethodActive('payflow_direct'));
+    }
+
+    public function testIsMethodAvailable()
+    {
+        $this->assertFalse($this->_model->isMethodAvailable('payflow_direct'));
+    }
+
+    public function testIsCreditCardMethod()
+    {
+        $this->assertFalse($this->_model->getIsCreditCardMethod('payflow_direct'));
+    }
+
+    public function testGetSpecificConfigPath()
+    {
+        $this->_model->setMethod('payflow_direct');
+        $this->assertNull($this->_model->getConfigValue('useccv'));
+        $this->assertNull($this->_model->getConfigValue('vendor'));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/InfoTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/InfoTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b32051c8e100d5ee83636b7686d201d575a3484
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/InfoTest.php
@@ -0,0 +1,278 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Paypal\Model;
+
+use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
+
+class InfoTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var \Magento\Paypal\Model\Info */
+    protected $info;
+
+    /** @var ObjectManagerHelper */
+    protected $objectManagerHelper;
+
+    protected function setUp()
+    {
+        
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->info = $this->objectManagerHelper->getObject(
+            'Magento\Paypal\Model\Info'
+        );
+    }
+
+    /**
+     * @dataProvider additionalInfoDataProvider
+     * @param array $additionalInfo
+     * @param array $expectation
+     */
+    public function testGetPaymentInfo($additionalInfo, $expectation)
+    {
+        /** @var \Magento\Payment\Model\Info $paymentInfo */
+        $paymentInfo = $this->objectManagerHelper->getObject('Magento\Payment\Model\Info');
+        $paymentInfo->setAdditionalInformation($additionalInfo);
+        $this->assertEquals($expectation, $this->info->getPaymentInfo($paymentInfo));
+    }
+
+    /**
+     * @dataProvider additionalInfoDataProvider
+     * @param array $additionalInfo
+     * @param array $expectation
+     */
+    public function testGetPaymentInfoLabelValues($additionalInfo, $expectation)
+    {
+        /** @var \Magento\Payment\Model\Info $paymentInfo */
+        $paymentInfo = $this->objectManagerHelper->getObject('Magento\Payment\Model\Info');
+        $paymentInfo->setAdditionalInformation($additionalInfo);
+        $this->assertEquals(
+            $this->_prepareLabelValuesExpectation($expectation),
+            $this->info->getPaymentInfo($paymentInfo, true)
+        );
+    }
+
+    /**
+     * @dataProvider additionalInfoPublicDataProvider
+     * @param array $additionalInfo
+     * @param array $expectation
+     */
+    public function testGetPublicPaymentInfo($additionalInfo, $expectation)
+    {
+        /** @var \Magento\Payment\Model\Info $paymentInfo */
+        $paymentInfo = $this->objectManagerHelper->getObject('Magento\Payment\Model\Info');
+        $paymentInfo->setAdditionalInformation($additionalInfo);
+        $this->assertEquals(
+            $this->_prepareLabelValuesExpectation($expectation),
+            $this->info->getPublicPaymentInfo($paymentInfo, true)
+        );
+    }
+
+    /**
+     * @dataProvider additionalInfoPublicDataProvider
+     * @param array $additionalInfo
+     * @param array $expectation
+     */
+    public function testGetPublicPaymentInfoLabelValues($additionalInfo, $expectation)
+    {
+        /** @var \Magento\Payment\Model\Info $paymentInfo */
+        $paymentInfo = $this->objectManagerHelper->getObject('Magento\Payment\Model\Info');
+        $paymentInfo->setAdditionalInformation($additionalInfo);
+        $this->assertEquals($expectation, $this->info->getPublicPaymentInfo($paymentInfo));
+    }
+
+    /**
+     * @dataProvider importToPaymentDataProvider
+     * @param array $mapping
+     * @param array $expectation
+     */
+    public function testImportToPayment($mapping, $expectation)
+    {
+        // we create $from object, based on mapping
+        $from = new \Magento\Framework\Object($mapping);
+        /** @var \Magento\Payment\Model\Info $paymentInfo */
+        $paymentInfo = $this->objectManagerHelper->getObject('Magento\Payment\Model\Info');
+        $this->info->importToPayment($from, $paymentInfo);
+        $this->assertEquals($expectation, $paymentInfo->getAdditionalInformation());
+    }
+
+    /**
+     * @dataProvider importToPaymentDataProvider
+     * @param array $mapping
+     * @param array $expectation
+     */
+    public function testExportFromPayment($mapping, $expectation)
+    {
+        /** @var \Magento\Payment\Model\Info $paymentInfo */
+        $paymentInfo = $this->objectManagerHelper->getObject('Magento\Payment\Model\Info');
+        $paymentInfo->setAdditionalInformation($expectation);
+
+        // we create $to empty object
+        $to = new \Magento\Framework\Object();
+        $this->info->exportFromPayment($paymentInfo, $to);
+        $this->assertEquals($mapping, $to->getData());
+    }
+
+    /**
+     * @dataProvider importToPaymentDataProvider
+     * @param array $mapping
+     * @param array $expectation
+     */
+    public function testExportFromPaymentCustomMapping($mapping, $expectation)
+    {
+        /** @var \Magento\Payment\Model\Info $paymentInfo */
+        $paymentInfo = $this->objectManagerHelper->getObject('Magento\Payment\Model\Info');
+        $paymentInfo->setAdditionalInformation($expectation);
+
+        // we create $to empty object
+        $to = new \Magento\Framework\Object();
+        $this->info->exportFromPayment($paymentInfo, $to, array_flip($mapping));
+        $this->assertEquals($mapping, $to->getData());
+    }
+
+    /**
+     * Converts expectation result from ['key' => ['label' => 'Label', 'value' => 'Value']] to ['Label' => 'Value']
+     *
+     * @param $expectation
+     * @return array
+     */
+    private function _prepareLabelValuesExpectation($expectation)
+    {
+        $labelValueExpectation = [];
+        foreach ($expectation as $data) {
+            $labelValueExpectation[$data['label']] = $data['value'];
+        }
+        return $labelValueExpectation;
+    }
+
+    /**
+     * List of Labels
+     *
+     * @return array
+     */
+    public function additionalInfoDataProvider()
+    {
+        return include __DIR__ . '/_files/additional_info_data.php';
+    }
+
+    /**
+     *List of public labels
+     *
+     * @return array
+     */
+    public function additionalInfoPublicDataProvider()
+    {
+        return [
+            [
+                [
+                    Info::PAYPAL_PAYER_EMAIL => Info::PAYPAL_PAYER_EMAIL,
+                    Info::BUYER_TAX_ID => Info::BUYER_TAX_ID,
+                    Info::BUYER_TAX_ID_TYPE => Info::BUYER_TAX_ID_TYPE_CNPJ
+                ],
+                [
+                    Info::PAYPAL_PAYER_EMAIL => [
+                        'label' => 'Payer Email',
+                        'value' => Info::PAYPAL_PAYER_EMAIL,
+                    ],
+                    Info::BUYER_TAX_ID => [
+                        'label' => 'Buyer\'s Tax ID',
+                        'value' => Info::BUYER_TAX_ID,
+                    ],
+                    Info::BUYER_TAX_ID_TYPE => [
+                        'label' => 'Buyer\'s Tax ID Type',
+                        'value' => 'CNPJ',
+                    ]
+                ]
+            ],
+            [
+                [
+                    Info::PAYPAL_PAYER_EMAIL => Info::PAYPAL_PAYER_EMAIL,
+                    Info::BUYER_TAX_ID => Info::BUYER_TAX_ID,
+                    Info::BUYER_TAX_ID_TYPE => Info::BUYER_TAX_ID_TYPE
+                ],
+                [
+                    Info::PAYPAL_PAYER_EMAIL => [
+                        'label' => 'Payer Email',
+                        'value' => Info::PAYPAL_PAYER_EMAIL,
+                    ],
+                    Info::BUYER_TAX_ID => [
+                        'label' => 'Buyer\'s Tax ID',
+                        'value' => Info::BUYER_TAX_ID,
+                    ]
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * Mapping and expectation
+     *
+     * @return array
+     */
+    public function importToPaymentDataProvider()
+    {
+        return [
+            [
+                [
+                    Info::PAYER_ID => Info::PAYPAL_PAYER_ID,
+                    Info::PAYER_EMAIL => Info::PAYPAL_PAYER_EMAIL,
+                    Info::PAYER_STATUS => Info::PAYPAL_PAYER_STATUS,
+                    Info::ADDRESS_ID => Info::PAYPAL_ADDRESS_ID,
+                    Info::ADDRESS_STATUS => Info::PAYPAL_ADDRESS_STATUS,
+                    Info::PROTECTION_EL => Info::PAYPAL_PROTECTION_ELIGIBILITY,
+                    Info::FRAUD_FILTERS => Info::PAYPAL_FRAUD_FILTERS,
+                    Info::CORRELATION_ID => Info::PAYPAL_CORRELATION_ID,
+                    Info::AVS_CODE => Info::PAYPAL_AVS_CODE,
+                    Info::CVV2_MATCH => Info::PAYPAL_CVV2_MATCH,
+                    Info::CENTINEL_VPAS => Info::CENTINEL_VPAS,
+                    Info::CENTINEL_ECI => Info::CENTINEL_ECI,
+                    Info::BUYER_TAX_ID => Info::BUYER_TAX_ID,
+                    Info::BUYER_TAX_ID_TYPE => Info::BUYER_TAX_ID_TYPE,
+                    Info::PAYMENT_STATUS => Info::PAYMENT_STATUS_GLOBAL,
+                    Info::PENDING_REASON => Info::PENDING_REASON_GLOBAL,
+                    Info::IS_FRAUD => Info::IS_FRAUD_GLOBAL
+                ],
+                [
+                    Info::PAYPAL_PAYER_ID => Info::PAYPAL_PAYER_ID,
+                    Info::PAYPAL_PAYER_EMAIL => Info::PAYPAL_PAYER_EMAIL,
+                    Info::PAYPAL_PAYER_STATUS => Info::PAYPAL_PAYER_STATUS,
+                    Info::PAYPAL_ADDRESS_ID => Info::PAYPAL_ADDRESS_ID,
+                    Info::PAYPAL_ADDRESS_STATUS => Info::PAYPAL_ADDRESS_STATUS,
+                    Info::PAYPAL_PROTECTION_ELIGIBILITY => Info::PAYPAL_PROTECTION_ELIGIBILITY,
+                    Info::PAYPAL_FRAUD_FILTERS => Info::PAYPAL_FRAUD_FILTERS,
+                    Info::PAYPAL_CORRELATION_ID => Info::PAYPAL_CORRELATION_ID,
+                    Info::PAYPAL_AVS_CODE => Info::PAYPAL_AVS_CODE,
+                    Info::PAYPAL_CVV2_MATCH => Info::PAYPAL_CVV2_MATCH,
+                    Info::CENTINEL_VPAS => Info::CENTINEL_VPAS,
+                    Info::CENTINEL_ECI => Info::CENTINEL_ECI,
+                    Info::BUYER_TAX_ID => Info::BUYER_TAX_ID,
+                    Info::BUYER_TAX_ID_TYPE => Info::BUYER_TAX_ID_TYPE,
+                    Info::PAYMENT_STATUS_GLOBAL => Info::PAYMENT_STATUS_GLOBAL,
+                    Info::PENDING_REASON_GLOBAL => Info::PENDING_REASON_GLOBAL,
+                    Info::IS_FRAUD_GLOBAL => Info::IS_FRAUD_GLOBAL
+                ]
+            ]
+        ];
+    }
+
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
index a987d9765da3b279a26dfcc6912bcbebaddcd992..3945c6e4e91f5391d0adfc76b8ddf6de1385e8d5 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/IpnTest.php
@@ -29,91 +29,125 @@ namespace Magento\Paypal\Model;
 
 class IpnTest extends \PHPUnit_Framework_TestCase
 {
-    const REQUEST_MC_GROSS = 38.12;
-
     /**
      * @var \Magento\Paypal\Model\Ipn
      */
     protected $_ipn;
 
-    protected function setUp()
-    {
-        $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_ipn = $objectHelper->getObject('Magento\Paypal\Model\Ipn');
-    }
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_orderMock;
 
     /**
-     * Prepare order property for ipn model
-     *
-     * @param \Magento\Paypal\Model\Ipn|\PHPUnit_Framework_MockObject_MockObject $ipn
-     * @return \PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected function _prepareIpnOrderProperty($ipn)
+    protected $_paypalInfo;
+
+    protected function setUp()
     {
-        // Create payment and order mocks
-        $payment = $this->getMockBuilder('Magento\Sales\Model\Order\Payment')->disableOriginalConstructor()->getMock();
-        $order = $this->getMockBuilder('Magento\Sales\Model\Order')->disableOriginalConstructor()->getMock();
-        $order->expects($this->any())->method('getPayment')->will($this->returnValue($payment));
+        $methods = [
+            'create',
+            'loadByIncrementId',
+            'canFetchPaymentReviewUpdate',
+            'getId',
+            'getPayment',
+            'getMethod',
+            'getStoreId',
+            'registerPaymentReviewAction',
+            'getAdditionalInformation',
+            'getEmailSent',
+            'save'
+        ];
+        $this->_orderMock = $this->getMock('Magento\Sales\Model\OrderFactory', $methods, [], '', false);
+        $this->_orderMock->expects($this->any())->method('create')->will($this->returnSelf());
+        $this->_orderMock->expects($this->any())->method('loadByIncrementId')->will($this->returnSelf());
+        $this->_orderMock->expects($this->any())->method('getId')->will($this->returnSelf());
+        $this->_orderMock->expects($this->any())->method('getMethod')->will($this->returnSelf());
+        $this->_orderMock->expects($this->any())->method('getStoreId')->will($this->returnSelf());
+        $this->_orderMock->expects($this->any())->method('getEmailSent')->will($this->returnValue(true));
 
-        // Set order to ipn
-        $orderProperty = new \ReflectionProperty('Magento\Paypal\Model\Ipn', '_order');
-        $orderProperty->setAccessible(true);
-        $orderProperty->setValue($ipn, $order);
+        $configFactory = $this->getMock(
+            'Magento\Paypal\Model\ConfigFactory',
+            ['create', 'isMethodActive', 'isMethodAvailable', 'getConfigValue', 'getPaypalUrl'],
+            [],
+            '',
+            false
+        );
+        $configFactory->expects($this->any())->method('create')->will($this->returnSelf());
+        $configFactory->expects($this->any())->method('isMethodActive')->will($this->returnValue(true));
+        $configFactory->expects($this->any())->method('isMethodAvailable')->will($this->returnValue(true));
+        $configFactory->expects($this->any())->method('getConfigValue')->will($this->returnValue(null));
+        $configFactory->expects($this->any())->method('getPaypalUrl')->will($this->returnValue('http://paypal_url'));
 
-        return $order;
+        $curlFactory = $this->getMock(
+            'Magento\Framework\HTTP\Adapter\CurlFactory',
+            ['create', 'setConfig', 'write', 'read'],
+            [],
+            '',
+            false
+        );
+        $curlFactory->expects($this->any())->method('create')->will($this->returnSelf());
+        $curlFactory->expects($this->any())->method('setConfig')->will($this->returnSelf());
+        $curlFactory->expects($this->any())->method('write')->will($this->returnSelf());
+        $curlFactory->expects($this->any())->method('read')->will($this->returnValue(
+            '
+                VERIFIED'
+        ));
+        $this->_paypalInfo = $this->getMock(
+            'Magento\Paypal\Model\Info',
+            ['importToPayment', 'getMethod', 'getAdditionalInformation'],
+            [],
+            '',
+            false
+        );
+        $this->_paypalInfo->expects($this->any())->method('getMethod')->will($this->returnValue('some_method'));
+        $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_ipn = $objectHelper->getObject('Magento\Paypal\Model\Ipn',
+            [
+                'configFactory' => $configFactory,
+                'logAdapterFactory' => $this->getMock('Magento\Framework\Logger\AdapterFactory', [], [], '', false),
+                'curlFactory' => $curlFactory,
+                'orderFactory' => $this->_orderMock,
+                'paypalInfo' => $this->_paypalInfo,
+                'data' => ['payment_status' => 'Pending', 'pending_reason' => 'authorization']
+            ]
+        );
     }
 
     public function testLegacyRegisterPaymentAuthorization()
     {
-        $order = $this->_prepareIpnOrderProperty($this->_ipn);
-        $order->expects($this->once())->method('canFetchPaymentReviewUpdate')->will($this->returnValue(false));
-        $payment = $order->getPayment();
-        $payment->expects(
-            $this->once()
-        )->method(
-            'registerAuthorizationNotification'
-        )->with(
-            $this->equalTo(self::REQUEST_MC_GROSS)
+        $this->_orderMock->expects($this->any())->method('canFetchPaymentReviewUpdate')->will(
+            $this->returnValue(false)
         );
-        $payment->expects($this->any())->method('__call')->will($this->returnSelf());
-
-        // Create info mock
-        $info = $this->getMock('Magento\Paypal\Model\Info');
-        $info->expects($this->once())->method('importToPayment');
-
-        // Set request to ipn
-        $requestProperty = new \ReflectionProperty('Magento\Paypal\Model\Ipn', '_ipnRequest');
-        $requestProperty->setAccessible(true);
-        $requestProperty->setValue($this->_ipn, array('mc_gross' => self::REQUEST_MC_GROSS));
-
-        // Set info to ipn
-        $infoProperty = new \ReflectionProperty('Magento\Paypal\Model\Ipn', '_paypalInfo');
-        $infoProperty->setAccessible(true);
-        $infoProperty->setValue($this->_ipn, $info);
+        $methods = [
+            'setPreparedMessage',
+            '__wakeup',
+            'setTransactionId',
+            'setParentTransactionId',
+            'setIsTransactionClosed',
+            'registerAuthorizationNotification'
+        ];
+        $payment = $this->getMock('Magento\Sales\Model\Order\Payment', $methods, [], '', false);
+        $payment->expects($this->any())->method('setPreparedMessage')->will($this->returnSelf());
+        $payment->expects($this->any())->method('setTransactionId')->will($this->returnSelf());
+        $payment->expects($this->any())->method('setParentTransactionId')->will($this->returnSelf());
+        $payment->expects($this->any())->method('setIsTransactionClosed')->will($this->returnSelf());
+        $this->_orderMock->expects($this->any())->method('getPayment')->will($this->returnValue($payment));
+        $this->_orderMock->expects($this->any())->method('getAdditionalInformation')->will($this->returnValue(array()));
 
-        $testMethod = new \ReflectionMethod('Magento\Paypal\Model\Ipn', '_registerPaymentAuthorization');
-        $testMethod->setAccessible(true);
-        $this->markTestIncomplete(
-            'MAGETWO-23755: "Fatal error: Using $this when not in object context" is observed under PHPUnit4'
-        );
-        $testMethod->invoke($this->_ipn);
+        $this->_paypalInfo->expects($this->once())->method('importToPayment');
+        $this->_ipn->processIpnRequest();
     }
 
     public function testPaymentReviewRegisterPaymentAuthorization()
     {
-        $order = $this->_prepareIpnOrderProperty($this->_ipn);
-        $order->expects($this->once())->method('canFetchPaymentReviewUpdate')->will($this->returnValue(true));
-        $order->getPayment()->expects(
-            $this->once()
-        )->method(
-            'registerPaymentReviewAction'
-        )->with(
-            $this->equalTo(\Magento\Sales\Model\Order\Payment::REVIEW_ACTION_UPDATE),
-            $this->equalTo(true)
-        );
-
-        $testMethod = new \ReflectionMethod('Magento\Paypal\Model\Ipn', '_registerPaymentAuthorization');
-        $testMethod->setAccessible(true);
-        $testMethod->invoke($this->_ipn);
+        $this->_orderMock->expects($this->any())->method('getPayment')->will($this->returnSelf());
+        $this->_orderMock->expects($this->any())->method('canFetchPaymentReviewUpdate')->will($this->returnValue(true));
+        $this->_orderMock->expects($this->once())->method('registerPaymentReviewAction')->with(
+            'update',
+            true
+        )->will($this->returnSelf());
+        $this->_ipn->processIpnRequest();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/Method/AgreementTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/Method/AgreementTest.php
index 657470e930af721532470ab385f90e76e4241bb6..f92d1e643f16bed77e0d8b6d6f4812a5c53eba16 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Model/Method/AgreementTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/Method/AgreementTest.php
@@ -47,7 +47,7 @@ class AgreementTest extends \PHPUnit_Framework_TestCase
         $paypalConfigMock = $this->getMockBuilder(
             '\Magento\Paypal\Model\Config'
         )->disableOriginalConstructor()->setMethods(
-            array('__get')
+            array('getConfigValue')
         )->getMock();
         $this->_apiNvpMock = $this->getMockBuilder(
             '\Magento\Paypal\Model\Api\Nvp'
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowExpressTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowExpressTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ddcf127db8a4418a72d40f06d1980d47f69a019
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/PayflowExpressTest.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Paypal\Model;
+
+use Magento\Sales\Model\Order\Payment\Transaction;
+
+class PayflowExpressTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Paypal\Model\PayflowExpress
+     */
+    protected $_model;
+
+    /**
+     * Payflow pro transaction key
+     */
+    const TRANSPORT_PAYFLOW_TXN_ID = 'Payflow pro transaction key';
+
+    public function setUp()
+    {
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $proFactory = $this->getMockBuilder(
+            'Magento\Paypal\Model\ProFactory'
+        )->disableOriginalConstructor()->setMethods(['create'])->getMock();
+        $paypalPro = $this->getMockBuilder(
+            'Magento\Paypal\Model\Pro'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+
+        $proFactory->expects($this->once())->method('create')->will($this->returnValue($paypalPro));
+
+        $this->_model = $objectManager->getObject('Magento\Paypal\Model\PayflowExpress', ['proFactory' => $proFactory]);
+    }
+
+    public function testCanRefundCaptureNotExist()
+    {
+        $paymentInfo = $this->_getPreparedPaymentInfo();
+
+        $paymentInfo->expects($this->once())->method('lookupTransaction')->with('', Transaction::TYPE_CAPTURE)->will(
+            $this->returnValue(false)
+        );
+        $this->assertFalse($this->_model->canRefund());
+    }
+
+    public function testCanRefundCaptureExistNoAdditionalInfo()
+    {
+        $paymentInfo = $this->_getPreparedPaymentInfo();
+        $captureTransaction = $this->_getCaptureTransaction();
+        $captureTransaction->expects($this->once())->method('getAdditionalInformation')->with(
+            Payflow\Pro::TRANSPORT_PAYFLOW_TXN_ID
+        )->will($this->returnValue(null));
+        $paymentInfo->expects($this->once())->method('lookupTransaction')->with('', Transaction::TYPE_CAPTURE)->will(
+            $this->returnValue($captureTransaction)
+        );
+        $this->assertFalse($this->_model->canRefund());
+    }
+
+    public function testCanRefundCaptureExistValid()
+    {
+        $paymentInfo = $this->_getPreparedPaymentInfo();
+        $captureTransaction = $this->_getCaptureTransaction();
+        $captureTransaction->expects($this->once())->method('getAdditionalInformation')->with(
+            Payflow\Pro::TRANSPORT_PAYFLOW_TXN_ID
+        )->will($this->returnValue(self::TRANSPORT_PAYFLOW_TXN_ID));
+        $paymentInfo->expects($this->once())->method('lookupTransaction')->with('', Transaction::TYPE_CAPTURE)->will(
+            $this->returnValue($captureTransaction)
+        );
+        $this->assertTrue($this->_model->canRefund());
+    }
+
+    /**
+     * Prepares payment info mock and adds it to the model
+     *
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getPreparedPaymentInfo()
+    {
+        $paymentInfo = $this->getMockBuilder(
+            'Magento\Sales\Model\Order\Payment'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+        $this->_model->setData('info_instance', $paymentInfo);
+        return $paymentInfo;
+    }
+
+    /**
+     * Prepares capture transaction
+     *
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function _getCaptureTransaction()
+    {
+        return $this->getMockBuilder(
+            'Magento\Sales\Model\Order\Payment\Transaction'
+        )->disableOriginalConstructor()->setMethods([])->getMock();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Model/_files/additional_info_data.php b/dev/tests/unit/testsuite/Magento/Paypal/Model/_files/additional_info_data.php
new file mode 100644
index 0000000000000000000000000000000000000000..bcab4fedbdb3cb466744d6db746320564868bc01
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Model/_files/additional_info_data.php
@@ -0,0 +1,183 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (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\Paypal\Model\Info;
+
+return [
+    [
+        [
+            Info::PAYPAL_PAYER_ID => Info::PAYPAL_PAYER_ID,
+            Info::PAYPAL_PAYER_EMAIL => Info::PAYPAL_PAYER_EMAIL,
+            Info::PAYPAL_PAYER_STATUS => Info::PAYPAL_PAYER_STATUS,
+            Info::PAYPAL_ADDRESS_ID => Info::PAYPAL_ADDRESS_ID,
+            Info::PAYPAL_ADDRESS_STATUS => Info::PAYPAL_ADDRESS_STATUS,
+            Info::PAYPAL_PROTECTION_ELIGIBILITY => Info::PAYPAL_PROTECTION_ELIGIBILITY,
+            Info::PAYPAL_FRAUD_FILTERS => Info::PAYPAL_FRAUD_FILTERS,
+            Info::PAYPAL_CORRELATION_ID => Info::PAYPAL_CORRELATION_ID,
+            Info::BUYER_TAX_ID => Info::BUYER_TAX_ID,
+            Info::PAYPAL_AVS_CODE => 'A',
+            Info::PAYPAL_CVV2_MATCH => 'M',
+            Info::BUYER_TAX_ID_TYPE => Info::BUYER_TAX_ID_TYPE_CNPJ,
+            Info::CENTINEL_VPAS => '2',
+            Info::CENTINEL_ECI => '01'
+        ],
+        [
+            Info::PAYPAL_PAYER_ID => [
+                'label' => 'Payer ID',
+                'value' => Info::PAYPAL_PAYER_ID,
+            ],
+            Info::PAYPAL_PAYER_EMAIL => [
+                'label' => 'Payer Email',
+                'value' => Info::PAYPAL_PAYER_EMAIL,
+            ],
+            Info::PAYPAL_PAYER_STATUS => [
+                'label' => 'Payer Status',
+                'value' => Info::PAYPAL_PAYER_STATUS,
+            ],
+            Info::PAYPAL_ADDRESS_ID => [
+                'label' => 'Payer Address ID',
+                'value' => Info::PAYPAL_ADDRESS_ID,
+            ],
+            Info::PAYPAL_ADDRESS_STATUS => [
+                'label' => 'Payer Address Status',
+                'value' => Info::PAYPAL_ADDRESS_STATUS,
+            ],
+            Info::PAYPAL_PROTECTION_ELIGIBILITY => [
+                'label' => 'Merchant Protection Eligibility',
+                'value' => Info::PAYPAL_PROTECTION_ELIGIBILITY,
+            ],
+            Info::PAYPAL_FRAUD_FILTERS => [
+                'label' => 'Triggered Fraud Filters',
+                'value' => Info::PAYPAL_FRAUD_FILTERS,
+            ],
+            Info::PAYPAL_CORRELATION_ID => [
+                'label' => 'Last Correlation ID',
+                'value' => Info::PAYPAL_CORRELATION_ID,
+            ],
+            Info::PAYPAL_AVS_CODE => [
+                'label' => 'Address Verification System Response',
+                'value' => '#A: Matched Address only (no ZIP)',
+            ],
+            Info::PAYPAL_CVV2_MATCH => [
+                'label' => 'CVV2 Check Result by PayPal',
+                'value' => '#M: Matched (CVV2CSC)',
+            ],
+            Info::CENTINEL_VPAS => [
+                'label' => 'PayPal/Centinel Visa Payer Authentication Service Result',
+                'value' => '#2: Authenticated, Good Result',
+            ],
+            Info::CENTINEL_ECI => [
+                'label' => 'PayPal/Centinel Electronic Commerce Indicator',
+                'value' => '#01: Merchant Liability',
+            ],
+            Info::BUYER_TAX_ID => [
+                'label' => 'Buyer\'s Tax ID',
+                'value' => Info::BUYER_TAX_ID,
+            ],
+            Info::BUYER_TAX_ID_TYPE => [
+                'label' => 'Buyer\'s Tax ID Type',
+                'value' => 'CNPJ',
+            ],
+            'last_trans_id' => [
+                'label' => 'Last Transaction ID',
+                'value' => NULL
+            ]
+        ]
+    ],
+    [
+        [
+            Info::PAYPAL_PAYER_ID => Info::PAYPAL_PAYER_ID,
+            Info::PAYPAL_PAYER_EMAIL => Info::PAYPAL_PAYER_EMAIL,
+            Info::PAYPAL_PAYER_STATUS => Info::PAYPAL_PAYER_STATUS,
+            Info::PAYPAL_ADDRESS_ID => Info::PAYPAL_ADDRESS_ID,
+            Info::PAYPAL_ADDRESS_STATUS => Info::PAYPAL_ADDRESS_STATUS,
+            Info::PAYPAL_PROTECTION_ELIGIBILITY => Info::PAYPAL_PROTECTION_ELIGIBILITY,
+            Info::PAYPAL_FRAUD_FILTERS => Info::PAYPAL_FRAUD_FILTERS,
+            Info::PAYPAL_CORRELATION_ID => Info::PAYPAL_CORRELATION_ID,
+            Info::BUYER_TAX_ID => Info::BUYER_TAX_ID,
+            Info::PAYPAL_AVS_CODE => Info::PAYPAL_AVS_CODE,
+            Info::PAYPAL_CVV2_MATCH => Info::PAYPAL_CVV2_MATCH,
+            Info::BUYER_TAX_ID_TYPE => Info::BUYER_TAX_ID_TYPE,
+            Info::CENTINEL_VPAS => Info::CENTINEL_VPAS,
+            Info::CENTINEL_ECI => Info::CENTINEL_ECI
+        ],
+        [
+            Info::PAYPAL_PAYER_ID => [
+                'label' => 'Payer ID',
+                'value' => Info::PAYPAL_PAYER_ID,
+            ],
+            Info::PAYPAL_PAYER_EMAIL => [
+                'label' => 'Payer Email',
+                'value' => Info::PAYPAL_PAYER_EMAIL,
+            ],
+            Info::PAYPAL_PAYER_STATUS => [
+                'label' => 'Payer Status',
+                'value' => Info::PAYPAL_PAYER_STATUS,
+            ],
+            Info::PAYPAL_ADDRESS_ID => [
+                'label' => 'Payer Address ID',
+                'value' => Info::PAYPAL_ADDRESS_ID,
+            ],
+            Info::PAYPAL_ADDRESS_STATUS => [
+                'label' => 'Payer Address Status',
+                'value' => Info::PAYPAL_ADDRESS_STATUS,
+            ],
+            Info::PAYPAL_PROTECTION_ELIGIBILITY => [
+                'label' => 'Merchant Protection Eligibility',
+                'value' => Info::PAYPAL_PROTECTION_ELIGIBILITY,
+            ],
+            Info::PAYPAL_FRAUD_FILTERS => [
+                'label' => 'Triggered Fraud Filters',
+                'value' => Info::PAYPAL_FRAUD_FILTERS,
+            ],
+            Info::PAYPAL_CORRELATION_ID => [
+                'label' => 'Last Correlation ID',
+                'value' => Info::PAYPAL_CORRELATION_ID,
+            ],
+            Info::PAYPAL_AVS_CODE => [
+                'label' => 'Address Verification System Response',
+                'value' => '#paypal_avs_code',
+            ],
+            Info::PAYPAL_CVV2_MATCH => [
+                'label' => 'CVV2 Check Result by PayPal',
+                'value' => '#paypal_cvv2_match',
+            ],
+            Info::CENTINEL_VPAS => [
+                'label' => 'PayPal/Centinel Visa Payer Authentication Service Result',
+                'value' => '#centinel_vpas_result',
+            ],
+            Info::CENTINEL_ECI => [
+                'label' => 'PayPal/Centinel Electronic Commerce Indicator',
+                'value' => '#centinel_eci_result',
+            ],
+            Info::BUYER_TAX_ID => [
+                'label' => 'Buyer\'s Tax ID',
+                'value' => Info::BUYER_TAX_ID,
+            ],
+            'last_trans_id' => [
+                'label' => 'Last Transaction ID',
+                'value' => NULL
+            ]
+        ]
+    ]
+];
diff --git a/dev/tests/unit/testsuite/Magento/ProductAlert/Block/Email/StockTest.php b/dev/tests/unit/testsuite/Magento/ProductAlert/Block/Email/StockTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9bf2a9714d0862c0c01ad932642d7167f842627
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/ProductAlert/Block/Email/StockTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ProductAlert\Block\Email;
+
+/**
+ * Test class for \Magento\ProductAlert\Block\Product\View\Stock
+ */
+class StockTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\ProductAlert\Block\Product\View\Stock
+     */
+    protected $_block;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Filter\Input\MaliciousCode
+     */
+    protected $_filter;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_filter = $this->getMock(
+            '\Magento\Framework\Filter\Input\MaliciousCode',
+            array('filter'),
+            array(),
+            '',
+            false
+        );
+        $this->_block = $objectManager->getObject(
+            'Magento\ProductAlert\Block\Email\Stock',
+            array('maliciousCode' => $this->_filter)
+        );
+    }
+
+    /**
+     * @dataProvider testGetFilteredContentDataProvider
+     * @param $contentToFilter
+     * @param $contentFiltered
+     */
+    public function testGetFilteredContent($contentToFilter, $contentFiltered)
+    {
+        $this->_filter->expects($this->once())->method('filter')->with($contentToFilter)
+            ->will($this->returnValue($contentFiltered));
+        $this->assertEquals($contentFiltered, $this->_block->getFilteredContent($contentToFilter));
+    }
+
+    public function testGetFilteredContentDataProvider()
+    {
+        return array(
+            'normal desc' => array('<b>Howdy!</b>', '<b>Howdy!</b>'),
+            'malicious desc 1' => array('<javascript>Howdy!</javascript>', 'Howdy!'),
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/RequireJs/Block/Html/Head/ConfigTest.php b/dev/tests/unit/testsuite/Magento/RequireJs/Block/Html/Head/ConfigTest.php
index 695281ee650e0a1ae871fff7aa49c79a0b247ce3..93c3c4a4d620314adc9ead24976c94834f671eec 100644
--- a/dev/tests/unit/testsuite/Magento/RequireJs/Block/Html/Head/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/RequireJs/Block/Html/Head/ConfigTest.php
@@ -18,9 +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.
  *
- * @category    Magento
- * @package     Magento_Review
- * @subpackage  integration_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)
  */
diff --git a/dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/ProductTest.php b/dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/ProductTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc5e0baa021f6465a218db9f11f3e78e20733589
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/ProductTest.php
@@ -0,0 +1,235 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Controller\Adminhtml;
+
+/**
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ */
+class ProductTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Review\Controller\Adminhtml\Product
+     */
+    protected $_model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_objectManagerHelper;
+
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_registryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_requestMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_responseMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_objectManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_messageManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_storeManagerInterfaceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_storeModelMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_reviewModelMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_reviewFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_ratingModelMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_ratingFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_resourceReviewMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_helperMock;
+
+
+    protected function setUp()
+    {
+        $this->_prepareMockObjects();
+
+        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->_model = $objectManagerHelper->getObject(
+            'Magento\Review\Controller\Adminhtml\Product',
+            [
+                'coreRegistry' => $this->_registryMock,
+                'reviewFactory' => $this->_reviewFactoryMock,
+                'ratingFactory' => $this->_ratingFactoryMock,
+                'request' => $this->_requestMock,
+                'response' => $this->_responseMock,
+                'objectManager' => $this->_objectManagerMock,
+                'messageManager' => $this->_messageManagerMock,
+                'helper' => $this->_helperMock
+            ]
+        );
+
+    }
+
+    /**
+     * Get mock objects for SetUp()
+     */
+    protected function _prepareMockObjects()
+    {
+        $requestMethods = array(
+            'getPost',
+            'getModuleName',
+            'setModuleName',
+            'getActionName',
+            'setActionName',
+            'getParam'
+        );
+        $this->_registryMock = $this->getMock('Magento\Framework\Registry', array(), array(), '', false);
+        $this->_requestMock = $this->getMock(
+            '\Magento\Framework\App\RequestInterface', $requestMethods
+        );
+        $this->_responseMock = $this->getMock(
+            '\Magento\Framework\App\ResponseInterface', array('setRedirect', 'sendResponse')
+        );
+        $this->_objectManagerMock = $this->getMock(
+            '\Magento\Framework\ObjectManager', array('get', 'create', 'configure'), array(), '', false
+        );
+        $this->_messageManagerMock = $this->getMock('\Magento\Framework\Message\Manager', array(), array(), '', false);
+        $this->_storeManagerInterfaceMock = $this->getMockForAbstractClass('Magento\Store\Model\StoreManagerInterface');
+        $this->_storeModelMock = $this->getMock(
+            'Magento\Store\Model\Store', array('__wakeup', 'getId'), array(), '', false
+        );
+        $this->_reviewModelMock = $this->getMock(
+            'Magento\Review\Model\Review',
+            array('__wakeup', 'create', 'save', 'getId', 'getResource', 'aggregate'),
+            array(),
+            '',
+            false
+        );
+
+        $this->_reviewFactoryMock = $this->getMock(
+            'Magento\Review\Model\ReviewFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+
+        $this->_ratingModelMock = $this->getMock(
+            'Magento\Review\Model\Rating',
+            array('__wakeup', 'setRatingId', 'setReviewId', 'addOptionVote'),
+            array(),
+            '',
+            false);
+
+        $this->_ratingFactoryMock = $this->getMock(
+            'Magento\Review\Model\RatingFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+
+        $this->_helperMock = $this->getMock('\Magento\Backend\Helper\Data', array(), array(), '', false);
+    }
+
+    /**
+     * Check postAction method and assert that review model storeId equals null.
+     */
+    public function testPostAction()
+    {
+        $this->_requestMock->expects($this->at(0))->method('getParam')
+            ->will($this->returnValue(1));
+        $this->_requestMock->expects($this->at(2))->method('getParam')
+            ->will($this->returnValue(array('1' => '1')));
+        $this->_requestMock->expects($this->once())->method('getPost')
+            ->will($this->returnValue(array('status_id' => 1)));
+        $this->_objectManagerMock->expects($this->at(0))->method('get')
+            ->with('Magento\Store\Model\StoreManagerInterface')
+            ->will($this->returnValue($this->_storeManagerInterfaceMock));
+        $this->_reviewFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($this->_reviewModelMock));
+        $this->_ratingFactoryMock->expects($this->once())->method('create')
+            ->will($this->returnValue($this->_ratingModelMock));
+        $this->_storeManagerInterfaceMock->expects($this->once())->method('hasSingleStore')
+            ->will($this->returnValue(true));
+        $this->_storeManagerInterfaceMock->expects($this->once())->method('getStore')
+            ->will($this->returnValue($this->_storeModelMock));
+        $this->_storeModelMock->expects($this->once())->method('getId')
+            ->will($this->returnValue(1));
+        $this->_reviewModelMock->expects($this->once())->method('save')
+            ->will($this->returnValue($this->_reviewModelMock));
+        $this->_reviewModelMock->expects($this->once())->method('getId')
+            ->will($this->returnValue(1));
+        $this->_reviewModelMock->expects($this->once())->method('aggregate')
+            ->will($this->returnValue($this->_reviewModelMock));
+        $this->_ratingModelMock->expects($this->once())->method('setRatingId')
+            ->will($this->returnSelf());
+        $this->_ratingModelMock->expects($this->once())->method('setReviewId')
+            ->will($this->returnSelf());
+        $this->_ratingModelMock->expects($this->once())->method('addOptionVote')
+            ->will($this->returnSelf());
+        $this->_helperMock->expects($this->once())->method('geturl')
+            ->will($this->returnValue('url'));
+
+        $this->_model->postAction();
+    }
+
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Helper/Quote/Item/CompareTest.php b/dev/tests/unit/testsuite/Magento/Sales/Helper/Quote/Item/CompareTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb29521c1a6be72b24ed67a1b87b152586fe6cbd
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Helper/Quote/Item/CompareTest.php
@@ -0,0 +1,206 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Sales\Helper\Quote\Item;
+
+/**
+ * Class CompareTest
+ */
+class CompareTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Helper\Quote\Item\Compare
+     */
+    protected $helper;
+
+    /**
+     * @var \Magento\Sales\Model\Quote\Item|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $itemMock;
+
+    /**
+     * @var \Magento\Sales\Model\Quote\Item|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $comparedMock;
+
+    /**
+     * @var \Magento\Sales\Model\Quote\Item\Option|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $optionMock;
+
+    /**
+     * test setUp
+     */
+    public function setUp()
+    {
+        $this->itemMock = $this->getMock(
+            'Magento\Sales\Model\Quote\Item',
+            ['__wakeup', 'getProductId', 'getOptions'],
+            [],
+            '',
+            false
+        );
+        $this->comparedMock = $this->getMock(
+            'Magento\Sales\Model\Quote\Item',
+            ['__wakeup', 'getProductId', 'getOptions'],
+            [],
+            '',
+            false
+        );
+        $this->optionMock = $this->getMock(
+            'Magento\Sales\Model\Quote\Item\Option',
+            ['__wakeup', 'getCode', 'getValue'],
+            [],
+            '',
+            false
+        );
+
+        $this->helper = new \Magento\Sales\Helper\Quote\Item\Compare();
+    }
+
+    /**
+     * @param string $code
+     * @param mixed $value
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getOptionMock($code, $value)
+    {
+        $optionMock = clone $this->optionMock;
+        $optionMock->expects($this->once())
+            ->method('getCode')
+            ->will($this->returnValue($code));
+        $optionMock->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue($value));
+        return $optionMock;
+    }
+
+    /**
+     * test compare two different products
+     */
+    public function testCompareDifferentProduct()
+    {
+        $this->itemMock->expects($this->once())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+        $this->itemMock->expects($this->once())
+            ->method('getProductId')
+            ->will($this->returnValue(2));
+
+        $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock));
+    }
+
+    /**
+     * test compare two items with different options
+     */
+    public function testCompareProductWithDifferentOptions()
+    {
+        $this->itemMock->expects($this->any())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+        $this->comparedMock->expects($this->any())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+
+        $this->itemMock->expects($this->any())
+            ->method('getOptions')
+            ->will($this->returnValue([
+                    $this->getOptionMock('option-1', 1),
+                    $this->getOptionMock('option-2', 'option-value'),
+                    $this->getOptionMock('option-3', serialize([
+                            'value' => 'value-1',
+                            'qty' => 2
+                        ])
+                    )]
+            ));
+        $this->comparedMock->expects($this->any())
+            ->method('getOptions')
+            ->will($this->returnValue([
+                    $this->getOptionMock('option-4', 1),
+                    $this->getOptionMock('option-2', 'option-value'),
+                    $this->getOptionMock('option-3', serialize([
+                        'value' => 'value-1',
+                        'qty' => 2
+                    ]))
+                ])
+            );
+        $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock));
+    }
+
+    /**
+     * test compare two items first with options and second without options
+     */
+    public function testCompareItemWithComparedWithoutOption()
+    {
+        $this->itemMock->expects($this->any())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+        $this->comparedMock->expects($this->any())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+        $this->itemMock->expects($this->any())
+            ->method('getOptions')
+            ->will($this->returnValue([
+                    $this->getOptionMock('option-1', 1),
+                    $this->getOptionMock('option-2', 'option-value'),
+                    $this->getOptionMock('option-3', serialize([
+                            'value' => 'value-1',
+                            'qty' => 2
+                        ])
+                    )]
+            ));
+        $this->comparedMock->expects($this->any())
+            ->method('getOptions')
+            ->will($this->returnValue([]));
+        $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock));
+    }
+
+    /**
+     * test compare two items first without options and second with options
+     */
+    public function testCompareItemWithoutOptionWithCompared()
+    {
+        $this->itemMock->expects($this->any())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+        $this->comparedMock->expects($this->any())
+            ->method('getProductId')
+            ->will($this->returnValue(1));
+        $this->comparedMock->expects($this->any())
+            ->method('getOptions')
+            ->will($this->returnValue([
+                    $this->getOptionMock('option-1', 1),
+                    $this->getOptionMock('option-2', 'option-value'),
+                    $this->getOptionMock('option-3', serialize([
+                            'value' => 'value-1',
+                            'qty' => 2
+                        ])
+                    )]
+            ));
+        $this->itemMock->expects($this->any())
+            ->method('getOptions')
+            ->will($this->returnValue([]));
+        $this->assertFalse($this->helper->compare($this->itemMock, $this->comparedMock));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/ConfigTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b98432146cc5188e357316f408a60eeb5f40394
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/ConfigTest.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\Sales\Model;
+
+class ConfigTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Model\Config
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $configDataMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stateMock;
+
+    protected function setUp()
+    {
+        $this->configDataMock = $this->getMockBuilder('Magento\Sales\Model\Config\Data')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->stateMock = $this->getMockBuilder('Magento\Framework\App\State')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->model = new \Magento\Sales\Model\Config($this->configDataMock, $this->stateMock);
+    }
+
+    public function testInstanceOf()
+    {
+        $model = new \Magento\Sales\Model\Config($this->configDataMock, $this->stateMock);
+        $this->assertInstanceOf('Magento\Sales\Model\Config', $model);
+    }
+
+    public function testGetTotalsRenderer()
+    {
+        $areaCode = 'frontend';
+        $section = 'config';
+        $group = 'sales';
+        $code = 'payment';
+        $path = $section . '/' . $group . '/' . $code . '/' . 'renderers' . '/' . $areaCode;
+        $expected = ['test data'];
+
+        $this->stateMock->expects($this->once())
+            ->method('getAreaCode')
+            ->will($this->returnValue($areaCode));
+        $this->configDataMock->expects($this->once())
+            ->method('get')
+            ->with($this->equalTo($path))
+            ->will($this->returnValue($expected));
+
+        $result = $this->model->getTotalsRenderer($section, $group, $code);
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testGetGroupTotals()
+    {
+        $section = 'config';
+        $group = 'payment';
+        $expected = ['test data'];
+        $path = $section . '/' . $group;
+
+        $this->configDataMock->expects($this->once())
+            ->method('get')
+            ->with($this->equalTo($path))
+            ->will($this->returnValue($expected));
+
+        $result = $this->model->getGroupTotals($section, $group);
+        $this->assertEquals($expected, $result);
+    }
+
+    public function testGetAvailableProductTypes()
+    {
+        $productTypes = ['simple'];
+
+        $this->configDataMock->expects($this->once())
+            ->method('get')
+            ->with($this->equalTo('order/available_product_types'))
+            ->will($this->returnValue($productTypes));
+        $result = $this->model->getAvailableProductTypes();
+        $this->assertEquals($productTypes, $result);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/DownloadTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/DownloadTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..13a3e8e474c71065002742f958aa35828e81646d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/DownloadTest.php
@@ -0,0 +1,247 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model;
+
+class DownloadTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Model\Download
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filesystemMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storageMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storageFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $httpFileFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $writeDirectoryMock;
+
+    protected function setUp()
+    {
+        $this->writeDirectoryMock = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\Write')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->filesystemMock = $this->getMockBuilder('Magento\Framework\App\Filesystem')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->filesystemMock->expects($this->any())
+            ->method('getDirectoryWrite')
+            ->with(\Magento\Framework\App\Filesystem::ROOT_DIR)
+            ->will($this->returnValue($this->writeDirectoryMock));
+
+        $this->storageMock = $this->getMockBuilder('Magento\Core\Helper\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storageFactoryMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\DatabaseFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->httpFileFactoryMock = $this->getMockBuilder('Magento\Framework\App\Response\Http\FileFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->model = new \Magento\Sales\Model\Download(
+            $this->filesystemMock,
+            $this->storageMock,
+            $this->storageFactoryMock,
+            $this->httpFileFactoryMock
+        );
+    }
+
+    public function testInstanceOf()
+    {
+        $model = new \Magento\Sales\Model\Download(
+            $this->filesystemMock,
+            $this->storageMock,
+            $this->storageFactoryMock,
+            $this->httpFileFactoryMock
+        );
+        $this->assertInstanceOf('Magento\Sales\Model\Download', $model);
+    }
+
+    /**
+     * @expectedException \Exception
+     */
+    public function testDownloadFileException()
+    {
+        $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title'];
+        $isFile = true;
+        $isReadable = false;
+
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('getAbsolutePath')
+            ->will($this->returnArgument(0));
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('isFile')
+            ->will($this->returnValue($isFile));
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('isReadable')
+            ->will($this->returnValue($isReadable));
+
+        $this->storageFactoryMock->expects($this->any())
+            ->method('checkDbUsage')
+            ->will($this->returnValue(false));
+
+        $this->model->downloadFile($info);
+    }
+
+    /**
+     * @expectedException \Exception
+     */
+    public function testDownloadFileNoStorage()
+    {
+        $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title'];
+        $isFile = true;
+        $isReadable = false;
+
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('getAbsolutePath')
+            ->will($this->returnArgument(0));
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('isFile')
+            ->will($this->returnValue($isFile));
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('isReadable')
+            ->will($this->returnValue($isReadable));
+
+        $this->storageMock->expects($this->any())
+            ->method('checkDbUsage')
+            ->will($this->returnValue(true));
+        $this->storageMock->expects($this->any())
+            ->method('getMediaRelativePath')
+            ->will($this->returnArgument(0));
+
+        $storageDatabaseMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storageDatabaseMock->expects($this->at(0))
+            ->method('loadByFilename')
+            ->with($this->equalTo($info['order_path']))
+            ->will($this->returnSelf());
+        $storageDatabaseMock->expects($this->at(2))
+            ->method('loadByFilename')
+            ->with($this->equalTo($info['quote_path']))
+            ->will($this->returnSelf());
+
+        $storageDatabaseMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(false));
+
+        $this->storageFactoryMock->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($storageDatabaseMock));
+
+        $this->model->downloadFile($info);
+    }
+
+    public function testDownloadFile()
+    {
+        $info = ['order_path' => 'test/path', 'quote_path' => 'test/path2', 'title' => 'test title'];
+        $isFile = true;
+        $isReadable = false;
+
+        $writeMock = $this->getMockBuilder('Magento\Framework\Filesystem\File\Write')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $writeMock->expects($this->any())
+            ->method('lock');
+        $writeMock->expects($this->any())
+            ->method('write');
+        $writeMock->expects($this->any())
+            ->method('unlock');
+        $writeMock->expects($this->any())
+            ->method('close');
+
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('getAbsolutePath')
+            ->will($this->returnArgument(0));
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('isFile')
+            ->will($this->returnValue($isFile));
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('isReadable')
+            ->will($this->returnValue($isReadable));
+        $this->writeDirectoryMock->expects($this->any())
+            ->method('openFile')
+            ->will($this->returnValue($writeMock));
+        $this->writeDirectoryMock->expects($this->once())
+            ->method('getRelativePath')
+            ->with($info['order_path'])
+            ->will($this->returnArgument(0));
+
+        $this->storageMock->expects($this->any())
+            ->method('checkDbUsage')
+            ->will($this->returnValue(true));
+        $this->storageMock->expects($this->any())
+            ->method('getMediaRelativePath')
+            ->will($this->returnArgument(0));
+
+        $storageDatabaseMock = $this->getMockBuilder('Magento\Core\Model\File\Storage\Database')
+            ->disableOriginalConstructor()
+            ->setMethods(['loadByFilename', 'getId', '__wakeup'])
+            ->getMock();
+        $storageDatabaseMock->expects($this->any())
+            ->method('loadByFilename')
+            ->will($this->returnSelf());
+
+        $storageDatabaseMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(true));
+
+        $this->storageFactoryMock->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($storageDatabaseMock));
+
+        $this->httpFileFactoryMock->expects($this->once())
+            ->method('create')
+            ->with(
+                $info['title'],
+                ['value' => $info['order_path'], 'type' => 'filename'],
+                \Magento\Framework\App\Filesystem::ROOT_DIR,
+                'application/octet-stream',
+                null
+            );
+
+        $result = $this->model->downloadFile($info);
+        $this->assertNull($result);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Payment/Method/ConverterTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Payment/Method/ConverterTest.php
deleted file mode 100644
index 260c572b90c18580fe94cc8ccb861d316f0d360a..0000000000000000000000000000000000000000
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Payment/Method/ConverterTest.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\Sales\Model\Payment\Method;
-
-use Magento\Sales\Model\Payment\Method\Converter;
-
-class ConverterTest extends \PHPUnit_Framework_TestCase
-{
-    const ENCRYPTED_VALUE = 'encrypted_value';
-    const DECRYPTED_VALUE = 'decrypted_value';
-    const INPUT_VALUE = 'input_value';
-
-    /**
-     * The Converter object to be tested
-     *
-     * @var \Magento\Sales\Model\Payment\Method\Converter
-     */
-    private $converter;
-
-    protected function setUp()
-    {
-        /** @var $encryptor \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Encryption\EncryptorInterface */
-        $encryptor = $this->getMock('Magento\Framework\Encryption\EncryptorInterface');
-        $encryptor->expects($this->any())
-            ->method('encrypt')
-            ->with(self::INPUT_VALUE)
-            ->will($this->returnValue(self::ENCRYPTED_VALUE));
-        $encryptor->expects($this->any())
-            ->method('decrypt')
-            ->with(self::INPUT_VALUE)
-            ->will($this->returnValue(self::DECRYPTED_VALUE));
-
-        $this->converter = new Converter($encryptor);
-    }
-
-    /**
-     * Create mock AbstractModel object
-     *
-     * @param string $method
-     * @param string $fieldName
-     * @return \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Model\AbstractModel
-     */
-    private function mockModelObject($method, $fieldName)
-    {
-        $modelMock = $this->getMockBuilder('Magento\Framework\Model\AbstractModel')
-            ->setMethods(['__wakeup', 'getData'])
-            ->disableOriginalConstructor()
-            ->getMockForAbstractClass();
-
-        //map arguments to return values, including optional parameters
-        $valueMap = [
-            ['method', null, $method],
-            [$fieldName, null, self::INPUT_VALUE],
-        ];
-        $modelMock->expects($this->any())
-            ->method('getData')
-            ->will($this->returnValueMap($valueMap));
-
-        return $modelMock;
-    }
-
-    /**
-     * Test positive calls to decode(), value should be decrypted
-     *
-     * @param string $method
-     * @param string $fieldName
-     * @dataProvider positiveDataProvider
-     */
-    public function testDecodePositive($method, $fieldName)
-    {
-        $modelMock = $this->mockModelObject($method, $fieldName);
-
-        $returnValue = $this->converter->decode($modelMock, $fieldName);
-        $this->assertEquals(self::DECRYPTED_VALUE, $returnValue);
-    }
-
-    /**
-     * Test the positive calls to encode(), return value should encrypted
-     *
-     * @param string $method
-     * @param string $fieldName
-     * @dataProvider positiveDataProvider
-     */
-    public function testEncodePositive($method, $fieldName)
-    {
-        $modelMock = $this->mockModelObject($method, $fieldName);
-
-        $returnValue = $this->converter->encode($modelMock, $fieldName);
-        $this->assertEquals(self::ENCRYPTED_VALUE, $returnValue);
-    }
-
-    /**
-     * Positive dataProvider
-     *
-     * @see \Magento\Sales\Model\Payment\Method\Converter::$_encryptFields
-     * @return array
-     */
-    public function positiveDataProvider()
-    {
-        $data = [
-            'owner' => ['ccsave', 'cc_owner'],
-            'exp_year' => ['ccsave', 'cc_exp_year'],
-            'exp_month' => ['ccsave', 'cc_exp_month'],
-        ];
-
-        return $data;
-    }
-
-    /**
-     * Test the negative calls to decode(), value should be original value, not decrypted
-     *
-     * @param string $method
-     * @param string $fieldName
-     * @dataProvider negativeDataProvider
-     */
-    public function testDecodeNegative($method, $fieldName)
-    {
-        $modelMock = $this->mockModelObject($method, $fieldName);
-
-        $returnValue = $this->converter->decode($modelMock, $fieldName);
-        $this->assertEquals(self::INPUT_VALUE, $returnValue);
-    }
-
-    /**
-     * Test the negative calls to encode(), return value should be original value, not encrypted
-     *
-     * @param string $method
-     * @param string $fieldName
-     * @dataProvider negativeDataProvider
-     */
-    public function testEncodeNegative($method, $fieldName)
-    {
-        $modelMock = $this->mockModelObject($method, $fieldName);
-
-        $returnValue = $this->converter->encode($modelMock, $fieldName);
-        $this->assertEquals(self::INPUT_VALUE, $returnValue);
-    }
-
-    /**
-     * Negative dataProvider
-     *
-     * @return array
-     */
-    public function negativeDataProvider()
-    {
-        $data = [
-            'incorrect_method_name' => ['ccsave_incorrect', 'cc_owner'],
-            'incorrect_field_name' => ['ccsave', 'cc_exp_year_incorrect'],
-        ];
-        return $data;
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/ItemTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/ItemTest.php
index c9e41f6ce4b4c2944663e926e7170afcf1856223..e4d2d5311fa05368b9cb3d20c34a840a518467b4 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/ItemTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/ItemTest.php
@@ -60,6 +60,11 @@ class ItemTest extends \PHPUnit_Framework_TestCase
      */
     private $objectManagerHelper;
 
+    /**
+     * @var \Magento\Sales\Helper\Quote\Item\Compare|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $compareHelper;
+
     const PRODUCT_ID = 1;
     const PRODUCT_TYPE = 'simple';
     const PRODUCT_SKU = '12345';
@@ -109,6 +114,14 @@ class ItemTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['create'])
             ->getMock();
 
+        $this->compareHelper = $this->getMock(
+            'Magento\Sales\Helper\Quote\Item\Compare',
+            [],
+            [],
+            '',
+            false
+        );
+
         $this->model = $this->objectManagerHelper->getObject(
             '\Magento\Sales\Model\Quote\Item',
             [
@@ -116,6 +129,7 @@ class ItemTest extends \PHPUnit_Framework_TestCase
                 'context' => $this->modelContext,
                 'statusListFactory' => $statusListFactory,
                 'itemOptionFactory' => $this->itemOptionFactory,
+                'compareHelper' => $this->compareHelper
             ]
         );
     }
@@ -612,6 +626,24 @@ class ItemTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($this->model->representProduct($productMock));
     }
 
+    /**
+     * test compare
+     */
+    public function testCompare()
+    {
+        $itemMock = $this->getMock('Magento\Sales\Model\Quote\Item',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->compareHelper->expects($this->once())
+            ->method('compare')
+            ->with($this->equalTo($this->model), $this->equalTo($itemMock))
+            ->will($this->returnValue(true));
+        $this->assertTrue($this->model->compare($itemMock));
+    }
+
     public function testCompareOptionsEqual()
     {
         $optionCode1 = 1234;
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/QuoteTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/QuoteTest.php
index f46fa01e52141a391139ba5650af8b01de2cc654..06e38508367f25e6ecd7412cdab62d7e3b2e85cb 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/QuoteTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/QuoteTest.php
@@ -47,19 +47,39 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
     protected $quoteAddressCollectionMock;
 
     /**
-     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject
      */
     protected $storeManagerMock;
 
     /**
-     * @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $storeMock;
+    protected $resourceMock;
 
     /**
-     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $scopeConfigMock;
+    protected $contextMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $addressConverterMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eventManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerGroupServiceMock;
 
     /**
      * @var \Magento\Sales\Model\Quote
@@ -75,11 +95,24 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->quoteAddressMock = $this->getMock('Magento\Sales\Model\Quote\Address', array(), array(), '', false);
-        $methods = array('isDeleted', 'setQuoteFilter', 'getIterator', 'validateMinimumAmount');
+        $this->quoteAddressMock = $this->getMock(
+            'Magento\Sales\Model\Quote\Address',
+            [
+                'isDeleted',
+                'getCollection',
+                'getId',
+                'getCustomerAddressId',
+                '__wakeup',
+                'getAddressType',
+                'getDeleteImmediately'
+            ],
+            [],
+            '',
+            false
+        );
         $this->quoteAddressCollectionMock = $this->getMock(
             'Magento\Sales\Model\Resource\Quote\Address\Collection',
-            $methods,
+            array(),
             array(),
             '',
             false
@@ -100,18 +133,49 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($this->quoteAddressCollectionMock)
         );
 
-        $this->storeManagerMock = $this->getMock('Magento\Store\Model\StoreManagerInterface');
+        $this->eventManagerMock = $this->getMockBuilder('Magento\Framework\Event\Manager')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->storeManagerMock = $this->getMockBuilder('Magento\Store\Model\StoreManager')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resourceMock = $this->getMockBuilder('Magento\Sales\Model\Resource\Quote')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->contextMock = $this->getMockBuilder('Magento\Framework\Model\Context')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->customerFactoryMock = $this->getMockBuilder('Magento\Customer\Model\CustomerFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->addressConverterMock = $this->getMockBuilder('Magento\Customer\Model\Address\Converter')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->customerGroupServiceMock = $this->getMockBuilder('Magento\Customer\Service\V1\CustomerGroupService')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->contextMock->expects($this->any())
+            ->method('getEventDispatcher')
+            ->will($this->returnValue($this->eventManagerMock));
 
-        $this->storeMock = $this->getMock('Magento\Store\Model\Store', array(), array(), '', false);
-        $this->storeManagerMock->expects($this->any())->method('getStore')->will($this->returnValue($this->storeMock));
-        $this->scopeConfigMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
-        $this->quote = (new ObjectManager(
+
+        $this->quote = (
+        new ObjectManager(
             $this
-        ))->getObject(
+        )
+        )->getObject(
                 'Magento\Sales\Model\Quote',
-                array('quoteAddressFactory' => $this->quoteAddressFactoryMock,
-                      'storeManager' => $this->storeManagerMock,
-                      'scopeConfig' => $this->scopeConfigMock)
+                [
+                    'quoteAddressFactory' => $this->quoteAddressFactoryMock,
+                    'storeManager' => $this->storeManagerMock,
+                    'resource' => $this->resourceMock,
+                    'context' => $this->contextMock,
+                    'customerFactory' => $this->customerFactoryMock,
+                    'addressConverter' => $this->addressConverterMock,
+                    'customerGroupService' => $this->customerGroupServiceMock
+                ]
             );
     }
 
@@ -201,25 +265,416 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
         return $shippingAddressMock;
     }
 
-    public function testValidateMinimumAmount()
+    public function testGetStoreIdNoId()
     {
+        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue(null));
+        $this->storeManagerMock->expects($this->once())
+            ->method('getStore')
+            ->will($this->returnValue($storeMock));
 
-        $this->storeMock->expects($this->any())->method('getId')->will($this->returnValue(false));
-        $valueMap = array(
-            array('sales/minimum_order/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, false, true),
-            array('sales/minimum_order/multi_address',
-                \Magento\Store\Model\ScopeInterface::SCOPE_STORE, false, true)
-        );
-        $this->scopeConfigMock->expects($this->any())->method('isSetFlag')->will($this->returnValueMap($valueMap));
-        $this->scopeConfigMock->expects($this->once())
-            ->method('getValue')
-            ->with('sales/minimum_order/amount', \Magento\Store\Model\ScopeInterface::SCOPE_STORE, false)
-            ->will($this->returnValue(150));
-        $this->quoteAddressCollectionMock
-            ->expects($this->any())
+        $result = $this->quote->getStoreId();
+        $this->assertNull($result);
+    }
+
+    public function testGetStoreId()
+    {
+        $storeId = 1;
+
+        $result = $this->quote->setStoreId($storeId)->getStoreId();
+        $this->assertEquals($storeId, $result);
+    }
+
+    public function testGetStore()
+    {
+        $storeId = 1;
+
+        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->storeManagerMock->expects($this->once())
+            ->method('getStore')
+            ->with($storeId)
+            ->will($this->returnValue($storeMock));
+
+        $this->quote->setStoreId($storeId);
+        $result = $this->quote->getStore();
+        $this->assertInstanceOf('Magento\Store\Model\Store', $result);
+    }
+
+    public function testSetStore()
+    {
+        $storeId = 1;
+
+        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($storeId));
+
+        $result = $this->quote->setStore($storeMock);
+        $this->assertInstanceOf('Magento\Sales\Model\Quote', $result);
+    }
+
+    public function testGetSharedWebsiteStoreIds()
+    {
+        $sharedIds = null;
+        $storeIds = [1, 2, 3];
+
+        $websiteMock = $this->getMockBuilder('Magento\Store\Model\Website')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $websiteMock->expects($this->once())
+            ->method('getStoreIds')
+            ->will($this->returnValue($storeIds));
+
+        $this->quote->setData('shared_store_ids', $sharedIds);
+        $this->quote->setWebsite($websiteMock);
+        $result = $this->quote->getSharedStoreIds();
+        $this->assertEquals($storeIds, $result);
+    }
+
+    public function testGetSharedStoreIds()
+    {
+        $sharedIds = null;
+        $storeIds = [1, 2, 3];
+        $storeId = 1;
+
+        $websiteMock = $this->getMockBuilder('Magento\Store\Model\Website')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $websiteMock->expects($this->once())
+            ->method('getStoreIds')
+            ->will($this->returnValue($storeIds));
+
+        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storeMock->expects($this->once())
+            ->method('getWebsite')
+            ->will($this->returnValue($websiteMock));
+
+        $this->storeManagerMock->expects($this->once())
+            ->method('getStore')
+            ->with($storeId)
+            ->will($this->returnValue($storeMock));
+
+        $this->quote->setData('shared_store_ids', $sharedIds);
+        $this->quote->setStoreId($storeId);
+        $result = $this->quote->getSharedStoreIds();
+        $this->assertEquals($storeIds, $result);
+    }
+
+    public function testLoadActive()
+    {
+        $quoteId = 1;
+
+        $this->resourceMock->expects($this->once())
+            ->method('loadActive')
+            ->with($this->quote, $quoteId);
+
+        $this->eventManagerMock->expects($this->any())
+            ->method('dispatch');
+
+        $result = $this->quote->loadActive($quoteId);
+        $this->assertInstanceOf('Magento\Sales\Model\Quote', $result);
+    }
+
+    public function testloadByIdWithoutStore()
+    {
+        $quoteId = 1;
+
+        $this->resourceMock->expects($this->once())
+            ->method('loadByIdWithoutStore')
+            ->with($this->quote, $quoteId);
+
+        $this->eventManagerMock->expects($this->any())
+            ->method('dispatch');
+
+        $result = $this->quote->loadByIdWithoutStore($quoteId);
+        $this->assertInstanceOf('Magento\Sales\Model\Quote', $result);
+    }
+
+    public function testSetCustomerAddressData()
+    {
+        $customerId = 1;
+
+        $addressItemMock = $this->getMockBuilder('Magento\Customer\Service\V1\Data\Address')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $addresses = [$addressItemMock];
+
+        $addressModelMock = $this->getMockBuilder('Magento\Customer\Model\Address')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->addressConverterMock->expects($this->once())
+            ->method('createAddressModel')
+            ->with($addressItemMock)
+            ->will($this->returnValue($addressModelMock));
+
+        $addressCollectionMock = $this->getMockBuilder('Magento\Customer\Model\Resource\Address\Collection')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $addressCollectionMock->expects($this->once())
+            ->method('removeAllItems');
+
+        $customerMock = $this->getMockBuilder('Magento\Customer\Model\Customer')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $customerMock->expects($this->once())
+            ->method('load')
+            ->with($customerId);
+        $customerMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue(false));
+        $customerMock->expects($this->once())
+            ->method('getAddressesCollection')
+            ->will($this->returnValue($addressCollectionMock));
+        $customerMock->expects($this->once())
+            ->method('addAddress')
+            ->with($addressModelMock);
+
+        $this->customerFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($customerMock));
+        $this->quote->setCustomerId($customerId);
+
+        $result = $this->quote->setCustomerAddressData($addresses);
+        $this->assertInstanceOf('Magento\Sales\Model\Quote', $result);
+    }
+
+    public function testGetCustomerTaxClassId()
+    {
+        $groupId = 1;
+        $taxClassId = 1;
+
+        $customerGroupMock = $this->getMockBuilder('Magento\Customer\Service\V1\Data\CustomerGroup')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $customerGroupMock->expects($this->once())
+            ->method('getTaxClassId')
+            ->will($this->returnValue($taxClassId));
+
+        $this->customerGroupServiceMock->expects($this->once())
+            ->method('getGroup')
+            ->with($groupId)
+            ->will($this->returnValue($customerGroupMock));
+
+        $this->quote->setData('customer_group_id', $groupId);
+        $result = $this->quote->getCustomerTaxClassId();
+        $this->assertEquals($taxClassId, $result);
+    }
+
+    public function testGetAllAddresses()
+    {
+        $id = 1;
+        $this->quoteAddressCollectionMock->expects($this->once())
+            ->method('setQuoteFilter')
+            ->with($id)
+            ->will($this->returnSelf());
+
+        $this->quoteAddressMock->expects($this->once())
+            ->method('isDeleted')
+            ->will($this->returnValue(false));
+
+        $iterator = new \ArrayIterator([$this->quoteAddressMock]);
+        $this->quoteAddressCollectionMock->expects($this->any())
+            ->method('getIterator')
+            ->will($this->returnValue($iterator));
+
+        $this->quote->setId($id);
+        $result = $this->quote->getAllAddresses();
+        $this->assertEquals([$this->quoteAddressMock], $result);
+    }
+
+    /**
+     * @dataProvider dataProviderGetAddress
+     */
+    public function testGetAddressById($addressId, $expected)
+    {
+        $id = 1;
+        $this->quoteAddressCollectionMock->expects($this->once())
             ->method('setQuoteFilter')
-            ->will($this->returnValue(array($this->quoteAddressCollectionMock)));
-        $this->quoteAddressCollectionMock->expects($this->never())->method('validateMinimumAmount');
-        $this->assertEquals(true, $this->quote->validateMinimumAmount(true));
+            ->with($id)
+            ->will($this->returnSelf());
+
+        $this->quoteAddressMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($id));
+
+        $iterator = new \ArrayIterator([$this->quoteAddressMock]);
+        $this->quoteAddressCollectionMock->expects($this->any())
+            ->method('getIterator')
+            ->will($this->returnValue($iterator));
+
+        $this->quote->setId($id);
+        $result = $this->quote->getAddressById($addressId);
+
+        $this->assertEquals((bool)$expected, (bool)$result);
+    }
+
+    public static function dataProviderGetAddress()
+    {
+        return [
+            [1, true],
+            [2, false]
+        ];
+    }
+
+    /**
+     * @param $isDeleted
+     * @param $customerAddressId
+     * @param $expected
+     *
+     * @dataProvider dataProviderGetAddressByCustomer
+     */
+    public function testGetAddressByCustomerAddressId($isDeleted, $customerAddressId, $expected)
+    {
+        $id = 1;
+        $this->quoteAddressCollectionMock->expects($this->once())
+            ->method('setQuoteFilter')
+            ->with($id)
+            ->will($this->returnSelf());
+
+        $this->quoteAddressMock->expects($this->once())
+            ->method('isDeleted')
+            ->will($this->returnValue($isDeleted));
+        $this->quoteAddressMock->expects($this->once())
+            ->method('getCustomerAddressId')
+            ->will($this->returnValue($customerAddressId));
+
+        $iterator = new \ArrayIterator([$this->quoteAddressMock]);
+        $this->quoteAddressCollectionMock->expects($this->any())
+            ->method('getIterator')
+            ->will($this->returnValue($iterator));
+
+        $this->quote->setId($id);
+        $result = $this->quote->getAddressByCustomerAddressId($id);
+
+        $this->assertEquals((bool)$expected, (bool)$result);
+    }
+
+    public static function dataProviderGetAddressByCustomer()
+    {
+        return [
+            [false, 1, true],
+            [false, 2, false]
+        ];
+    }
+
+    /**
+     * @param $isDeleted
+     * @param $addressType
+     * @param $customerAddressId
+     * @param $expected
+     *
+     * @dataProvider dataProviderShippingAddress
+     */
+    public function testGetShippingAddressByCustomerAddressId($isDeleted, $addressType, $customerAddressId, $expected)
+    {
+        $id = 1;
+
+        $this->quoteAddressCollectionMock->expects($this->once())
+            ->method('setQuoteFilter')
+            ->with($id)
+            ->will($this->returnSelf());
+
+        $this->quoteAddressMock->expects($this->once())
+            ->method('isDeleted')
+            ->will($this->returnValue($isDeleted));
+        $this->quoteAddressMock->expects($this->once())
+            ->method('getCustomerAddressId')
+            ->will($this->returnValue($customerAddressId));
+        $this->quoteAddressMock->expects($this->once())
+            ->method('getAddressType')
+            ->will($this->returnValue($addressType));
+
+        $iterator = new \ArrayIterator([$this->quoteAddressMock]);
+        $this->quoteAddressCollectionMock->expects($this->any())
+            ->method('getIterator')
+            ->will($this->returnValue($iterator));
+
+        $this->quote->setId($id);
+
+        $result = $this->quote->getShippingAddressByCustomerAddressId($id);
+        $this->assertEquals($expected, (bool)$result);
+    }
+
+    public static function dataProviderShippingAddress()
+    {
+        return [
+            [false, \Magento\Customer\Model\Address\AbstractAddress::TYPE_SHIPPING, 1, true],
+            [false, \Magento\Customer\Model\Address\AbstractAddress::TYPE_SHIPPING, 2, false],
+        ];
+    }
+
+    public function testRemoveAddress()
+    {
+        $id = 1;
+
+        $this->quoteAddressCollectionMock->expects($this->once())
+            ->method('setQuoteFilter')
+            ->with($id)
+            ->will($this->returnSelf());
+
+        $this->quoteAddressMock->expects($this->once())
+            ->method('isDeleted')
+            ->with(true);
+        $this->quoteAddressMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($id));
+
+        $iterator = new \ArrayIterator([$this->quoteAddressMock]);
+        $this->quoteAddressCollectionMock->expects($this->any())
+            ->method('getIterator')
+            ->will($this->returnValue($iterator));
+
+        $this->quote->setId($id);
+
+        $result = $this->quote->removeAddress($id);
+        $this->assertInstanceOf('Magento\Sales\Model\Quote', $result);
+    }
+
+    public function testRemoveAllAddresses()
+    {
+        $id = 1;
+
+        $this->quoteAddressCollectionMock->expects($this->once())
+            ->method('setQuoteFilter')
+            ->with($id)
+            ->will($this->returnSelf());
+
+        $this->quoteAddressMock->expects($this->any())
+            ->method('getAddressType')
+            ->will($this->returnValue(\Magento\Customer\Model\Address\AbstractAddress::TYPE_SHIPPING));
+        $this->quoteAddressMock->expects($this->any())
+            ->method('isDeleted')
+            ->will($this->returnValue(false));
+        $this->quoteAddressMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($id));
+        $this->quoteAddressMock->expects($this->once())
+            ->method('getDeleteImmediately')
+            ->will($this->returnValue(true));
+
+        $iterator = new \ArrayIterator([$id => $this->quoteAddressMock]);
+        $this->quoteAddressCollectionMock->expects($this->any())
+            ->method('getIterator')
+            ->will($this->returnValue($iterator));
+        $this->quoteAddressCollectionMock->expects($this->once())
+            ->method('removeItemByKey')
+            ->with($id)
+            ->will($this->returnValue($iterator));
+
+        $this->quote->setId($id);
+
+        $result = $this->quote->removeAllAddresses();
+        $this->assertInstanceOf('Magento\Sales\Model\Quote', $result);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Helper/CouponTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Helper/CouponTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b643ae1f3ade1518a592096fcb891079e745549
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/SalesRule/Helper/CouponTest.php
@@ -0,0 +1,168 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\SalesRule\Helper;
+
+class CouponTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\SalesRule\Helper\Coupon
+     */
+    protected $helper;
+
+    /**
+     * @var \Magento\Framework\App\Config
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Framework\App\Helper\Context
+     */
+    protected $context;
+
+    /**
+     * @var array
+     */
+    protected $couponParameters;
+
+    /**
+     * @var string
+     */
+    protected $separator = '|';
+
+    public function setUp()
+    {
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->scopeConfig = $this->getMock('Magento\Framework\App\Config', [], [], '', false);
+        $this->context = $this->getMock('Magento\Framework\App\Helper\Context', [], [], '', false);
+        $this->couponParameters = [
+            'separator' => $this->separator,
+            'charset' => [
+                'format' => 'abc'
+            ]
+        ];
+
+        $this->helper = $objectManager->getObject(
+            'Magento\SalesRule\Helper\Coupon',
+            [
+                'context' => $this->context,
+                'scopeConfig' => $this->scopeConfig,
+                'couponParameters' => $this->couponParameters
+            ]
+        );
+    }
+
+    public function testGetFormatsList()
+    {
+        $helper = $this->helper;
+        $this->assertArrayHasKey(
+            $helper::COUPON_FORMAT_ALPHABETICAL,
+            $helper->getFormatsList(),
+            'The returned list should contain COUPON_FORMAT_ALPHABETICAL constant value as a key'
+        );
+        $this->assertArrayHasKey(
+            $helper::COUPON_FORMAT_ALPHANUMERIC,
+            $helper->getFormatsList(),
+            'The returned list should contain COUPON_FORMAT_ALPHANUMERIC constant value as a key'
+        );
+        $this->assertArrayHasKey(
+            $helper::COUPON_FORMAT_NUMERIC,
+            $helper->getFormatsList(),
+            'The returned list should contain COUPON_FORMAT_NUMERIC constant value as a key'
+        );
+    }
+
+    public function testGetDefaultLength()
+    {
+        $helper = $this->helper;
+        $defaultLength = 100;
+        $this->scopeConfig->expects($this->once())
+            ->method('getValue')
+            ->with($helper::XML_PATH_SALES_RULE_COUPON_LENGTH, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue($defaultLength));
+
+        $this->assertEquals($defaultLength, $helper->getDefaultLength());
+    }
+
+    public function testGetDefaultFormat()
+    {
+        $helper = $this->helper;
+        $defaultFormat = 'format';
+        $this->scopeConfig->expects($this->once())
+            ->method('getValue')
+            ->with($helper::XML_PATH_SALES_RULE_COUPON_FORMAT, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue($defaultFormat));
+
+        $this->assertEquals($defaultFormat, $helper->getDefaultFormat());
+    }
+
+    public function testGetDefaultPrefix()
+    {
+        $helper = $this->helper;
+        $defaultPrefix = 'prefix';
+        $this->scopeConfig->expects($this->once())
+            ->method('getValue')
+            ->with($helper::XML_PATH_SALES_RULE_COUPON_PREFIX, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue($defaultPrefix));
+
+        $this->assertEquals($defaultPrefix, $helper->getDefaultPrefix());
+    }
+
+    public function testGetDefaultSuffix()
+    {
+        $helper = $this->helper;
+        $defaultSuffix = 'suffix';
+        $this->scopeConfig->expects($this->once())
+            ->method('getValue')
+            ->with($helper::XML_PATH_SALES_RULE_COUPON_SUFFIX, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue($defaultSuffix));
+
+        $this->assertEquals($defaultSuffix, $helper->getDefaultSuffix());
+    }
+
+    public function testGetDefaultDashInterval()
+    {
+        $helper = $this->helper;
+        $defaultDashInterval = 4;
+        $this->scopeConfig->expects($this->once())
+            ->method('getValue')
+            ->with($helper::XML_PATH_SALES_RULE_COUPON_DASH_INTERVAL, \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue($defaultDashInterval));
+
+        $this->assertEquals($defaultDashInterval, $helper->getDefaultDashInterval());
+    }
+
+    public function testGetCharset()
+    {
+        $format = 'format';
+        $expected = ['a', 'b', 'c'];
+
+        $this->assertEquals($expected, $this->helper->getCharset($format));
+    }
+
+    public function testGetSeparator()
+    {
+        $this->assertEquals($this->separator, $this->helper->getCodeSeparator());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Model/ObserverTest.php
index eb612c34ed11ca076a359955f5e3de861b7e196b..a1aa9bac796c43b27e8c5b5a62fbfd7348b911c3 100644
--- a/dev/tests/unit/testsuite/Magento/SalesRule/Model/ObserverTest.php
+++ b/dev/tests/unit/testsuite/Magento/SalesRule/Model/ObserverTest.php
@@ -28,61 +28,487 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\SalesRule\Model\Observer|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_model;
+    protected $model;
 
     /**
      * @var \Magento\SalesRule\Model\Coupon|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_couponMock;
+    protected $couponMock;
+
+    /**
+     * @var \Magento\SalesRule\Model\RuleFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $ruleFactory;
+
+    /**
+     * @var
+     */
+    protected $ruleCustomerFactory;
+
+    /**
+     * @var \Magento\Framework\Locale\Resolver|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $localeResolver;
+
+    /**
+     * @var \Magento\SalesRule\Model\Resource\Coupon\Usage|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $couponUsage;
+
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\Timezone|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $localeDate;
+
+    /**
+     * @var \Magento\SalesRule\Model\Resource\Report\Rule|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $reportRule;
+
+    /**
+     * @var \Magento\SalesRule\Model\Resource\Rule\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionFactory;
+
+    /**
+     * @var \Magento\Framework\Message\Manager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $messageManager;
 
     protected function setUp()
     {
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_couponMock = $this->getMock(
+        $this->initMocks();
+
+        $this->model = $helper->getObject(
+            'Magento\SalesRule\Model\Observer',
+            [
+                'coupon' => $this->couponMock,
+                'ruleFactory' => $this->ruleFactory,
+                'ruleCustomerFactory' => $this->ruleCustomerFactory,
+                'localeResolver' => $this->localeResolver,
+                'couponUsage' => $this->couponUsage,
+                'localeDate' => $this->localeDate,
+                'reportRule' => $this->reportRule,
+                'collectionFactory' => $this->collectionFactory,
+                'messageManager' => $this->messageManager
+            ]
+        );
+    }
+
+    protected function initMocks()
+    {
+        $this->couponMock = $this->getMock(
             '\Magento\SalesRule\Model\Coupon',
-            array('__wakeup', 'save', 'load'),
-            array(),
+            [
+                '__wakeup',
+                'save',
+                'load',
+                'getId',
+                'setTimesUsed',
+                'getTimesUsed',
+                'getRuleId',
+                'loadByCode',
+                'updateCustomerCouponTimesUsed'
+            ],
+            [],
+            '',
+            false
+        );
+        $this->ruleFactory = $this->getMock('Magento\SalesRule\Model\RuleFactory', ['create'], [], '', false);
+        $this->ruleCustomerFactory = $this->getMock(
+            'Magento\SalesRule\Model\Rule\CustomerFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->localeResolver = $this->getMock('Magento\Framework\Locale\Resolver', [], [], '', false);
+        $this->couponUsage = $this->getMock('Magento\SalesRule\Model\Resource\Coupon\Usage', [], [], '', false);
+        $this->localeDate = $this->getMock('Magento\Framework\Stdlib\DateTime\Timezone', ['date'], [], '', false);
+        $this->reportRule = $this->getMock('Magento\SalesRule\Model\Resource\Report\Rule', [], [], '', false);
+        $this->collectionFactory = $this->getMock(
+            'Magento\SalesRule\Model\Resource\Rule\CollectionFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->messageManager = $this->getMock(
+            'Magento\Framework\Message\Manager',
+            ['addWarning'],
+            [],
             '',
             false
         );
-        $this->_model = $helper->getObject('Magento\SalesRule\Model\Observer', array('coupon' => $this->_couponMock));
     }
 
     /**
-     * @covers \Magento\SalesRule\Model\Observer::salesOrderAfterPlace
+     * @param \\PHPUnit_Framework_MockObject_MockObject $observer
+     * @return \PHPUnit_Framework_MockObject_MockObject $order
      */
-    public function testSalesOrderAfterPlaceWithoutDiscount()
+    protected function initOrderFromEvent($observer)
     {
-        $event = new \Magento\Framework\Event();
-        $observer = new \Magento\Framework\Event\Observer(array('event' => $event));
-        /** @var $mockOrder \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject */
-        $mockOrder = $this->getMock(
+        $event = $this->getMock('Magento\Framework\Event', ['getOrder'], [], '', false);
+        $order = $this->getMock(
             'Magento\Sales\Model\Order',
-            array('__wakeup', 'getDiscountAmount'),
-            array(),
+            ['getAppliedRuleIds', 'getCustomerId', 'getDiscountAmount', 'getCouponCode', '__wakeup'],
+            [],
             '',
             false
         );
-        $event->setData('order', $mockOrder);
-        $mockOrder->expects($this->once())->method('getDiscountAmount')->will($this->returnValue(0));
-        $this->assertInstanceOf('Magento\SalesRule\Model\Observer', $this->_model->salesOrderAfterPlace($observer));
+
+        $observer->expects($this->any())
+            ->method('getEvent')
+            ->will($this->returnValue($event));
+        $event->expects($this->any())
+            ->method('getOrder')
+            ->will($this->returnValue($order));
+
+        return $order;
+    }
+
+    public function testSalesOrderAfterPlaceWithoutOrder()
+    {
+        $observer = $this->getMock('Magento\Framework\Event\Observer', [], [], '', false);
+        $this->initOrderFromEvent($observer);
+
+        $this->assertEquals($this->model, $this->model->salesOrderAfterPlace($observer));
+    }
+
+    public function testSalesOrderAfterPlaceWithoutRuleId()
+    {
+        $observer = $this->getMock('Magento\Framework\Event\Observer', [], [], '', false);
+        $order = $this->initOrderFromEvent($observer);
+        $discountAmount = 10;
+        $order->expects($this->once())
+            ->method('getDiscountAmount')
+            ->will($this->returnValue($discountAmount));
+
+        $this->ruleFactory->expects($this->never())
+            ->method('create');
+        $this->assertEquals($this->model, $this->model->salesOrderAfterPlace($observer));
     }
 
     /**
-     * @covers \Magento\SalesRule\Model\Observer::salesOrderAfterPlace
+     * @param int|bool $ruleCustomerId
+     * @dataProvider salesOrderAfterPlaceDataProvider
      */
-    public function testSalesOrderAfterPlaceWithDiscount()
+    public function testSalesOrderAfterPlace($ruleCustomerId)
+    {
+        $observer = $this->getMock('Magento\Framework\Event\Observer', [], [], '', false);
+        $rule = $this->getMock('Magento\SalesRule\Model\Rule', [], [], '', false);
+        $ruleCustomer = $this->getMock(
+            'Magento\SalesRule\Model\Rule\Customer',
+            [
+                'setCustomerId',
+                'loadByCustomerRule',
+                'getId',
+                'setTimesUsed',
+                'setRuleId',
+                'save',
+                '__wakeup'
+            ],
+            [],
+            '',
+            false
+        );
+        $order = $this->initOrderFromEvent($observer);
+        $ruleId = 1;
+        $couponId = 1;
+        $customerId = 1;
+        $discountAmount = 10;
+
+        $order->expects($this->once())
+            ->method('getAppliedRuleIds')
+            ->will($this->returnValue($ruleId));
+        $order->expects($this->once())
+            ->method('getDiscountAmount')
+            ->will($this->returnValue($discountAmount));
+        $order->expects($this->once())
+            ->method('getCustomerId')
+            ->will($this->returnValue($customerId));
+        $this->ruleFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($rule));
+        $rule->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($ruleId));
+        $this->ruleCustomerFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($ruleCustomer));
+        $ruleCustomer->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($ruleCustomerId));
+        $ruleCustomer->expects($this->any())
+            ->method('setCustomerId')
+            ->will($this->returnSelf());
+        $ruleCustomer->expects($this->any())
+            ->method('setRuleId')
+            ->will($this->returnSelf());
+        $this->couponMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($couponId));
+
+        $this->couponUsage->expects($this->once())
+            ->method('updateCustomerCouponTimesUsed')
+            ->with($customerId, $couponId);
+
+        $this->assertEquals($this->model, $this->model->salesOrderAfterPlace($observer));
+    }
+
+    public function salesOrderAfterPlaceDataProvider()
+    {
+        return [
+            'With customer rule id' => [1],
+            'Without customer rule id' => [null]
+        ];
+    }
+
+    public function testAggregateSalesReportCouponsData()
+    {
+        $dateMock = $this->getMock('Magento\Framework\Stdlib\DateTime\DateInterface', [], [], '', false);
+        $this->localeResolver->expects($this->once())
+            ->method('emulate')
+            ->with(0);
+        $this->localeDate->expects($this->once())
+            ->method('date')
+            ->will($this->returnValue($dateMock));
+        $dateMock->expects($this->once())
+            ->method('subHour')
+            ->with(25)
+            ->will($this->returnSelf());
+        $this->reportRule->expects($this->once())
+            ->method('aggregate')
+            ->with($dateMock);
+        $this->localeResolver->expects($this->once())
+            ->method('revert');
+
+        $this->assertEquals($this->model, $this->model->aggregateSalesReportCouponsData());
+    }
+
+    protected function checkSalesRuleAvailability($attributeCode)
+    {
+        $collection = $this->getMock(
+            'Magento\SalesRule\Model\Resource\Rule\Collection',
+            ['addAttributeInConditionFilter', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $rule = $this->getMock(
+            'Magento\SalesRule\Model\Rule',
+            ['setIsActive', 'getConditions', 'getActions', 'save', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $combine = $this->getMock(
+            'Magento\Rule\Model\Condition\Combine',
+            ['getConditions', 'setConditions', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $combineProduct = $this->getMock(
+            'Magento\SalesRule\Model\Rule\Condition\Product',
+            ['getAttribute', 'setConditions', '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+
+        $this->collectionFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($collection));
+        $collection->expects($this->once())
+            ->method('addAttributeInConditionFilter')
+            ->with($attributeCode)
+            ->will($this->returnValue([$rule]));
+        $rule->expects($this->once())
+            ->method('setIsActive')
+            ->with(0);
+        $rule->expects($this->once())
+            ->method('getConditions')
+            ->will($this->returnValue($combine));
+        $rule->expects($this->once())
+            ->method('getActions')
+            ->will($this->returnValue($combine));
+        $combine->expects($this->at(0))
+            ->method('getConditions')
+            ->will($this->returnValue([$combine]));
+        $combine->expects($this->at(1))
+            ->method('getConditions')
+            ->will($this->returnValue([$combineProduct]));
+        $combine->expects($this->at(4))
+            ->method('getConditions')
+            ->will($this->returnValue([]));
+
+        $combineProduct->expects($this->once())
+            ->method('getAttribute')
+            ->will($this->returnValue($attributeCode));
+        $combine->expects($this->any())
+            ->method('setConditions')
+            ->will(
+                $this->returnValueMap(
+                    [
+                        [[], null],
+                        [[$combine], null],
+                        [[], null],
+                    ]
+                )
+            );
+
+        $this->messageManager->expects($this->once())
+            ->method('addWarning')
+            ->with(sprintf('1 Shopping Cart Price Rules based on "%s" attribute have been disabled.', $attributeCode));
+    }
+
+    public function testCatalogAttributeSaveAfter()
+    {
+        $attributeCode = 'attributeCode';
+        $observer = $this->getMock('Magento\Framework\Event\Observer', [], [], '', false);
+        $event = $this->getMock('Magento\Framework\Event', ['getAttribute', '__wakeup'], [], '', false);
+        $attribute = $this->getMock(
+            'Magento\Catalog\Model\Resource\Eav\Attribute',
+            ['dataHasChangedFor', 'getIsUsedForPromoRules', 'getAttributeCode', '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+        $observer->expects($this->once())
+            ->method('getEvent')
+            ->will($this->returnValue($event));
+        $event->expects($this->any())
+            ->method('getAttribute')
+            ->will($this->returnValue($attribute));
+        $attribute->expects($this->any())
+            ->method('dataHasChangedFor')
+            ->with('is_used_for_promo_rules')
+            ->will($this->returnValue(true));
+        $attribute->expects($this->any())
+            ->method('getIsUsedForPromoRules')
+            ->will($this->returnValue(false));
+        $attribute->expects($this->any())
+            ->method('getAttributeCode')
+            ->will($this->returnValue($attributeCode));
+        $this->checkSalesRuleAvailability($attributeCode);
+
+        $this->assertEquals($this->model, $this->model->catalogAttributeSaveAfter($observer));
+    }
+
+    public function testCatalogAttributeDeleteAfter()
     {
-        $event = new \Magento\Framework\Event();
-        $observer = new \Magento\Framework\Event\Observer(array('event' => $event));
-        /** @var $mockOrder \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject */
-        $mockOrder = $this->getMock('Magento\Sales\Model\Order', array('__wakeup'), array(), '', false);
-        $event->setData('order', $mockOrder);
-        $mockOrder->addData(array('discount_amount' => -10, 'applied_rule_ids' => '', 'coupon_code' => 'some_code'));
-        $this->_couponMock->expects($this->once())->method('load')->with('some_code', 'code');
-        $this->_couponMock->expects($this->once())->method('save');
-        $this->_couponMock->addData(array('id' => 'some_code', 'times_used' => 1));
-        $this->assertInstanceOf('Magento\SalesRule\Model\Observer', $this->_model->salesOrderAfterPlace($observer));
-        $this->assertEquals(2, $this->_couponMock->getTimesUsed());
+        $attributeCode = 'attributeCode';
+        $observer = $this->getMock('Magento\Framework\Event\Observer', [], [], '', false);
+        $event = $this->getMock('Magento\Framework\Event', ['getAttribute', '__wakeup'], [], '', false);
+        $attribute = $this->getMock(
+            'Magento\Catalog\Model\Resource\Eav\Attribute',
+            ['dataHasChangedFor', 'getIsUsedForPromoRules', 'getAttributeCode', '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+        $observer->expects($this->once())
+            ->method('getEvent')
+            ->will($this->returnValue($event));
+        $event->expects($this->any())
+            ->method('getAttribute')
+            ->will($this->returnValue($attribute));
+        $attribute->expects($this->any())
+            ->method('getIsUsedForPromoRules')
+            ->will($this->returnValue(true));
+        $attribute->expects($this->any())
+            ->method('getAttributeCode')
+            ->will($this->returnValue($attributeCode));
+        $this->checkSalesRuleAvailability($attributeCode);
+
+        $this->assertEquals($this->model, $this->model->catalogAttributeDeleteAfter($observer));
+    }
+
+    public function testAddSalesRuleNameToOrderWithoutCouponCode()
+    {
+        $observer = $this->getMock('Magento\Framework\Event\Observer', ['getOrder'], [], '', false);
+        $order = $this->getMock(
+            'Magento\Sales\Model\Order',
+            ['setCouponRuleName', 'getCouponCode', '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+        $observer->expects($this->any())
+            ->method('getOrder')
+            ->will($this->returnValue($order));
+
+        $this->couponMock->expects($this->never())
+            ->method('loadByCode');
+
+        $this->assertEquals($this->model, $this->model->addSalesRuleNameToOrder($observer));
+    }
+
+    public function testAddSalesRuleNameToOrderWithoutRule()
+    {
+        $observer = $this->getMock('Magento\Framework\Event\Observer', ['getOrder'], [], '', false);
+        $order = $this->getMock(
+            'Magento\Sales\Model\Order',
+            ['setCouponRuleName', 'getCouponCode', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $couponCode = 'coupon code';
+
+        $observer->expects($this->any())
+            ->method('getOrder')
+            ->will($this->returnValue($order));
+
+        $order->expects($this->once())
+            ->method('getCouponCode')
+            ->will($this->returnValue($couponCode));
+        $this->ruleFactory->expects($this->never())
+            ->method('create');
+
+        $this->assertEquals($this->model, $this->model->addSalesRuleNameToOrder($observer));
+    }
+
+    public function testAddSalesRuleNameToOrder()
+    {
+        $observer = $this->getMock('Magento\Framework\Event\Observer', ['getOrder'], [], '', false);
+        $rule = $this->getMock('Magento\SalesRule\Model\Rule', ['load', 'getName', '__wakeup'], [], '', false);
+        $order = $this->getMock(
+            'Magento\Sales\Model\Order',
+            ['setCouponRuleName', 'getCouponCode', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $couponCode = 'coupon code';
+        $ruleId = 1;
+
+        $observer->expects($this->any())
+            ->method('getOrder')
+            ->will($this->returnValue($order));
+
+        $order->expects($this->once())
+            ->method('getCouponCode')
+            ->will($this->returnValue($couponCode));
+        $this->couponMock->expects($this->once())
+            ->method('getRuleId')
+            ->will($this->returnValue($ruleId));
+        $this->ruleFactory->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($rule));
+        $rule->expects($this->once())
+            ->method('load')
+            ->with($ruleId)
+            ->will($this->returnSelf());
+        $order->expects($this->once())
+            ->method('setCouponRuleName');
+
+        $this->assertEquals($this->model, $this->model->addSalesRuleNameToOrder($observer));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Model/Plugin/QuoteConfigProductAttributesTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Model/Plugin/QuoteConfigProductAttributesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..610ca756b8d39ffde4aed85fd1aa8253efc02c8c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/SalesRule/Model/Plugin/QuoteConfigProductAttributesTest.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\SalesRule\Model\Plugin;
+
+class QuoteConfigProductAttributesTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\SalesRule\Model\Plugin\QuoteConfigProductAttributes|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $plugin;
+
+    /**
+     * @var \Magento\SalesRule\Model\Resource\Rule|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $ruleResource;
+
+    public function setUp()
+    {
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->ruleResource = $this->getMock('Magento\SalesRule\Model\Resource\Rule', [], [], '', false);
+
+        $this->plugin = $objectManager->getObject(
+            'Magento\SalesRule\Model\Plugin\QuoteConfigProductAttributes',
+            [
+                'ruleResource' => $this->ruleResource
+            ]
+        );
+    }
+
+    public function testAfterGetProductAttributes()
+    {
+        $subject = $this->getMock('Magento\Sales\Model\Quote\Config', [], [], '', false);
+        $attributeCode = 'code of the attribute';
+        $expected = [0 => $attributeCode];
+
+        $this->ruleResource->expects($this->once())
+            ->method('getActiveAttributes')
+            ->will(
+                $this->returnValue(
+                    [
+                        ['attribute_code' => $attributeCode, 'enabled' => true]
+                    ]
+                )
+            );
+
+        $this->assertEquals($expected, $this->plugin->afterGetProductAttributes($subject, []));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/SalesRule/Model/System/Config/Source/Coupon/FormatTest.php b/dev/tests/unit/testsuite/Magento/SalesRule/Model/System/Config/Source/Coupon/FormatTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6175448ec126baaefc34996d54600785c8af047
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/SalesRule/Model/System/Config/Source/Coupon/FormatTest.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\SalesRule\Model\System\Config\Source\Coupon;
+
+class FormatTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\SalesRule\Model\System\Config\Source\Coupon\Format|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $model;
+
+    /**
+     * @var \Magento\SalesRule\Helper\Coupon|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $salesRuleCoupon;
+
+    public function setUp()
+    {
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $this->salesRuleCoupon = $this->getMock(
+            'Magento\SalesRule\Helper\Coupon',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->model = $objectManager->getObject(
+            'Magento\SalesRule\Model\System\Config\Source\Coupon\Format',
+            [
+                'salesRuleCoupon' => $this->salesRuleCoupon
+            ]
+        );
+    }
+
+
+    public function testToOptionArray()
+    {
+        $formatTitle = 'format Title';
+        $expected = [
+            [
+                'label' => $formatTitle,
+                'value' => 0
+            ]
+        ];
+        $this->salesRuleCoupon->expects($this->once())
+            ->method('getFormatsList')
+            ->will($this->returnValue([$formatTitle]));
+
+        $this->assertEquals($expected, $this->model->toOptionArray());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Store/App/Response/RedirectTest.php b/dev/tests/unit/testsuite/Magento/Store/App/Response/RedirectTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..42d91bb87bbcfc1b7eedf9c1e9ee7696342fc92c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Store/App/Response/RedirectTest.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Response redirector tests
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Store\App\Response;
+
+class RedirectTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Store\App\Response\Redirect
+     */
+    protected $_model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_requestMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_storeManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_urlCoderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_sessionMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_sidResolverMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_urlBuilderMock;
+
+    protected function setUp()
+    {
+        $this->_requestMock = $this->getMock(
+            'Magento\Framework\App\RequestInterface',
+            array(
+                'getServer',
+                'getModuleName',
+                'setModuleName',
+                'getActionName',
+                'setActionName',
+                'getParam'
+            )
+        );
+        $this->_storeManagerMock = $this->getMock('\Magento\Store\Model\StoreManagerInterface');
+        $this->_urlCoderMock = $this->getMock(
+            '\Magento\Framework\Encryption\UrlCoder',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $this->_sessionMock = $this->getMock('\Magento\Framework\Session\SessionManagerInterface');
+        $this->_sidResolverMock = $this->getMock('\Magento\Framework\Session\SidResolverInterface');
+        $this->_urlBuilderMock = $this->getMock('\Magento\Framework\UrlInterface');
+
+        $this->_model = new \Magento\Store\App\Response\Redirect(
+            $this->_requestMock,
+            $this->_storeManagerMock,
+            $this->_urlCoderMock,
+            $this->_sessionMock,
+            $this->_sidResolverMock,
+            $this->_urlBuilderMock
+        );
+    }
+
+    /**
+     * @dataProvider urlAddresses
+     * @param string $baseUrl
+     * @param string $successUrl
+     */
+    public function testSuccessUrl($baseUrl, $successUrl)
+    {
+        $testStoreMock = $this->getMock('\Magento\Store\Model\Store', array(), array(), '', false);
+        $testStoreMock->expects($this->any())->method('getBaseUrl')->will($this->returnValue($baseUrl));
+        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(null));
+        $this->_storeManagerMock->expects($this->any())->method('getStore')
+            ->will($this->returnValue($testStoreMock));
+        $this->assertEquals($baseUrl, $this->_model->success($successUrl));
+    }
+
+    /**
+     * DataProvider with the test urls
+     *
+     * @return array
+     */
+    public function urlAddresses()
+    {
+        return array(
+            array(
+                'http://externalurl.com/',
+                'http://internalurl.com/'
+            ),
+            array(
+                'http://internalurl.com/',
+                'http://internalurl.com/'
+            )
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Service/Entity/DataFromArrayTest.php b/dev/tests/unit/testsuite/Magento/Webapi/Service/Entity/DataFromArrayTest.php
index 6659cf50cf81cd7b9287a88126bc8275e025ebfa..40c3256c7fafd905e1b8c995f5af49ec08b2ad99 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Service/Entity/DataFromArrayTest.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Service/Entity/DataFromArrayTest.php
@@ -35,7 +35,7 @@ class DataFromArrayTest extends \PHPUnit_Framework_TestCase
     public function setUp()
     {
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $objectFactory = new \Magento\Webapi\Service\Entity\WebapiObjectManager();
+        $objectFactory = new \Magento\Webapi\Service\Entity\WebapiObjectManager($objectManager);
         $typeProcessor = $objectManager->getObject('Magento\Webapi\Model\Config\ClassReflector\TypeProcessor');
         $this->serializer = new ServiceArgsSerializer($typeProcessor, $objectFactory);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Service/Entity/WebapiObjectManager.php b/dev/tests/unit/testsuite/Magento/Webapi/Service/Entity/WebapiObjectManager.php
index a15c6d174891162c6dad1f747eeeaa7e695520b4..b395f8c83c58a3cd69ad517b263fe2d6389742fe 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Service/Entity/WebapiObjectManager.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Service/Entity/WebapiObjectManager.php
@@ -30,6 +30,19 @@ class WebapiObjectManager implements \Magento\Framework\ObjectManager
      */
     private $configuration;
 
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager
+     */
+    protected $factory;
+
+    /**
+     * @param \Magento\TestFramework\Helper\ObjectManager $factory
+     */
+    public function __construct(\Magento\TestFramework\Helper\ObjectManager $factory)
+    {
+        $this->factory = $factory;
+    }
+
     /**
      * Create new object instance
      *
@@ -39,7 +52,7 @@ class WebapiObjectManager implements \Magento\Framework\ObjectManager
      */
     public function create($type, array $arguments = array())
     {
-        return new $type($arguments);
+        return $this->factory->getObject($type, $arguments);
     }
 
     /**
@@ -50,7 +63,7 @@ class WebapiObjectManager implements \Magento\Framework\ObjectManager
      */
     public function get($type)
     {
-        return new $type();
+        return $this->factory->getObject($type);
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Weee/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Weee/Helper/DataTest.php
index ef372460155b4e6aa47aba858d6b4171facfe4cf..da35a3dd5a47f79e2576ef7fa83df9ecc4e0cef1 100644
--- a/dev/tests/unit/testsuite/Magento/Weee/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Weee/Helper/DataTest.php
@@ -35,6 +35,11 @@ class DataTest extends \PHPUnit_Framework_TestCase
      */
     protected $_helperData;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_abstractItem;
+
     protected function setUp()
     {
         $this->_product = $this->getMock('Magento\Catalog\Model\Product', [], [], '', false);
@@ -42,6 +47,25 @@ class DataTest extends \PHPUnit_Framework_TestCase
         $scopeConfig->expects($this->any())->method('getValue')->will($this->returnValue(true));
         $weeeTax = $this->getMock('Magento\Weee\Model\Tax', [], [], '', false);
         $weeeTax->expects($this->any())->method('getWeeeAmount')->will($this->returnValue('11.26'));
+        $this->_abstractItem = $this->getMock(
+            '\Magento\Sales\Model\Quote\Item\AbstractItem',
+            array(
+                '__wakeup',
+                'setDiscountCalculationPrice',
+                'setBaseDiscountCalculationPrice',
+                'getDiscountCalculationPrice',
+                'getBaseDiscountCalculationPrice',
+                'getCalculationPrice',
+                'getBaseCalculationPrice',
+                'setItemDiscountPrices',
+                'getQuote',
+                'getAddress',
+                'getOptionByCode'
+            ),
+            array(),
+            '',
+            false
+        );
         $arguments = array(
             'scopeConfig' => $scopeConfig,
             'weeeTax' => $weeeTax
@@ -54,4 +78,58 @@ class DataTest extends \PHPUnit_Framework_TestCase
     {
         $this->assertEquals('11.26', $this->_helperData->getAmount($this->_product));
     }
+
+    /**
+     * @covers \Magento\Weee\Helper\Data::addItemDiscountPrices
+     * @covers \Magento\Weee\Helper\Data::setItemDiscountPrices
+     *
+     * @param string $getDiscountPrice
+     * @param string $basePrice
+     * @param string $price
+     * @param string $baseDiscountCalculationPrice
+     * @param string $callPriceCalculation
+     *
+     * @dataProvider addItemDiscountPricesDataProvider
+     */
+    public function testAddItemDiscountPrices(
+        $getDiscountPrice, $basePrice, $price, $baseDiscountCalculationPrice, $callPriceCalculation
+    ) {
+        $this->_abstractItem->expects($this->once())->method('getDiscountCalculationPrice')
+            ->will($this->returnValue($getDiscountPrice));
+        $this->_abstractItem->expects($this->once())->method('getBaseDiscountCalculationPrice')
+            ->will($this->returnValue($getDiscountPrice));
+        $this->_abstractItem->expects($this->exactly($callPriceCalculation))->method('getCalculationPrice')
+            ->will($this->returnValue($price));
+        $this->_abstractItem->expects($this->exactly($callPriceCalculation))->method('getBaseCalculationPrice')
+            ->will($this->returnValue($price));
+        $this->_abstractItem->expects($this->once())->method('setDiscountCalculationPrice')
+            ->with($basePrice);
+        $this->_abstractItem->expects($this->once())->method('setBaseDiscountCalculationPrice')
+            ->with($baseDiscountCalculationPrice);
+
+        $this->assertEquals(
+            $this->_helperData, $this->_helperData->addItemDiscountPrices($this->_abstractItem, $basePrice, $price)
+        );
+    }
+
+    public function addItemDiscountPricesDataProvider()
+    {
+        return array(
+            array(
+                'discount_price' => null,
+                'base_price' => '2',
+                'price' => '1',
+                'base_calculation_price' => '3',
+                'call_price_calculation' => 1
+            ),
+            array(
+                'discount_price' => '1',
+                'base_price' => '2',
+                'price' => '1',
+                'base_calculation_price' => '3',
+                'call_price_calculation' => 0
+            )
+        );
+    }
+
 }
diff --git a/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php b/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a9790902c51211e97e03b0ee530269413105896
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php
@@ -0,0 +1,433 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Weee\Model\Total\Quote;
+
+/**
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ */
+class WeeeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_objectMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_weeeDataMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_configMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_storeMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_quoteItemMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_mageObjMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_productModelMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_contextMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_storeManagerInterfaceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_weeeTaxMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_taxHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_registryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_scopeConfigInterfaceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_quoteModelMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_addressMock;
+
+    /**
+     * @var \Magento\Weee\Model\Total\Quote\Weee
+     */
+    protected $_model;
+
+    protected function setUp()
+    {
+        $this->_initializeMockObjects();
+        $this->_prepareStaticMockExpects();
+        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_model = $objectManagerHelper->getObject(
+            '\Magento\Weee\Model\Total\Quote\Weee',
+            array(
+                'weeeData' => $this->_weeeDataMock,
+                'taxConfig' =>  $this->_configMock
+            )
+        );
+    }
+
+    /**
+     * Initialize mock objects
+     */
+    protected function _initializeMockObjects()
+    {
+        $quoteItemMethods = [
+            '__wakeup',
+            'getProduct',
+            'setWeeeTaxAppliedAmount',
+            'setBaseWeeeTaxAppliedAmount',
+            'setWeeeTaxAppliedRowAmount',
+            'setBaseWeeeTaxAppliedRowAmnt',
+            'getHasChildren',
+            'getChildren',
+            'isChildrenCalculated',
+            'getTotalQty',
+            'getQuote'
+        ];
+
+        $this->_storeManagerInterfaceMock = $this->getMock(
+            'Magento\Store\Model\StoreManagerInterface', [], [], '', false
+        );
+        $this->_weeeTaxMock = $this->getMock(
+            '\Magento\Weee\Model\Tax', ['__wakeup', 'getProductWeeeAttributes'], [], '', false
+        );
+        $this->_taxHelperMock = $this->getMock('\Magento\Tax\Helper\Data', [], [], '', false);
+        $this->_registryMock = $this->getMock('\Magento\Framework\Registry', [], [], '', false);
+        $this->_scopeConfigInterfaceMock = $this->getMock(
+            '\Magento\Framework\App\Config\ScopeConfigInterface', ['isSetFlag', 'getValue'], [], '', false
+        );
+        $this->_weeeDataMock = $this->getMock('\Magento\Weee\Helper\Data', array(), array(), '', false);
+        $this->_configMock = $this->getMock('\Magento\Tax\Model\Config', ['priceIncludesTax'], [], '', false);
+        $this->_objectMock = $this->getMock('\Magento\Framework\Object', [], [], '', false);
+        $this->_storeMock = $this->getMock('\Magento\Store\Model\Store', ['__wakeup', 'convertPrice'], [], '', false);
+        $this->_quoteItemMock = $this->getMock('Magento\Sales\Model\Quote\Item', $quoteItemMethods, [], '', false);
+        $this->_productModelMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
+        $this->_quoteModelMock = $this->getMock('\Magento\Sales\Model\Quote',
+            ['__wakeup', 'getBillingAddress', 'getStore'], [], '', false);
+        $this->_addressMock = $this->getMock('\Magento\Sales\Model\Quote\Address', [
+            '__wakeup',
+            'unsSubtotalInclTax',
+            'unsBaseSubtotalInclTax',
+            'getAllItems',
+            'getQuote',
+            'getAllNonNominalItems',
+            'getPrice'
+        ], [], '', false);
+    }
+
+    /**
+     * Prepare expects for mocked objects
+     */
+    protected function _prepareStaticMockExpects()
+    {
+        $this->_addressMock->expects($this->any())->method('getQuote')
+            ->will($this->returnValue($this->_quoteModelMock));
+        $this->_addressMock->expects($this->any())->method('getAllItems')
+            ->will($this->returnValue($this->_quoteModelMock));
+        $this->_quoteModelMock->expects($this->any())->method('getStore')
+            ->will($this->returnValue($this->_storeMock));
+        $this->_quoteModelMock->expects($this->any())->method('getBillingAddress')
+            ->will($this->returnValue($this->_addressMock));
+        $this->_quoteModelMock->expects($this->any())->method('getPrice')
+            ->will($this->returnValue(1));
+        $this->_quoteItemMock->expects($this->any())->method('getProduct')
+            ->will($this->returnValue($this->_productModelMock));
+        $this->_quoteItemMock->expects($this->any())->method('getTotalQty')
+            ->will($this->returnValue(1));
+        $this->_quoteItemMock->expects($this->any())->method('getQuote')
+            ->will($this->returnValue($this->_quoteModelMock));
+        $this->_scopeConfigInterfaceMock->expects($this->any())->method('isSetFlag')
+            ->will($this->returnValue(true));
+        $this->_weeeTaxMock->expects($this->any())->method('getProductWeeeAttributes')
+            ->will($this->returnValue(array($this->_objectMock)));
+        $this->_weeeDataMock->expects($this->any())->method('getProductWeeeAttributes')
+            ->will($this->returnValue(array($this->_objectMock)));
+        $this->_weeeDataMock->expects($this->any())->method('getApplied')
+            ->will($this->returnValue(array()));
+        $this->_storeMock->expects($this->any())->method('convertPrice')
+            ->will($this->returnValue(1));
+    }
+
+    /**
+     * Collect items and apply discount to weee
+     */
+    public function testCollectWithAddItemDiscountPrices()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->once())->method('addItemDiscountPrices');
+        $this->_weeeDataMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue(true));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect items without applying discount to weee
+     */
+    public function testCollectWithoutAddItemDiscountPrices()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->never())->method('addItemDiscountPrices');
+        $this->_weeeDataMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue(true));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect items without address item
+     */
+    public function testCollectWithoutAddressItem()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array()));
+        $this->_addressMock->expects($this->never())->method('setAppliedTaxesReset');
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect items with child
+     */
+    public function testCollectWithChildItem()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue(true));
+        $this->_quoteItemMock->expects($this->once())->method('isChildrenCalculated')
+            ->will($this->returnValue(true));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect items with price that includes tax
+     *
+     * @param array
+     */
+    public function testCollectPriceIncludesTax()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_addressMock->expects($this->once())->method('getAllNonNominalItems');
+        $this->_addressMock->expects($this->once())->method('getAllNonNominalItems');
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->once())->method('addItemDiscountPrices');
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue(true));
+        $this->_configMock->expects($this->once())->method('priceIncludesTax')
+            ->will($this->returnValue(false));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect items with price that does not include tax
+     *
+     * @param array
+     */
+    public function testCollectPriceNotIncludesTax()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->once())->method('addItemDiscountPrices');
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue(true));
+        $this->_configMock->expects($this->once())->method('priceIncludesTax')
+            ->will($this->returnValue(true));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect taxable items
+     */
+    public function testCollectTaxable()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_addressMock->expects($this->once())->method('unsSubtotalInclTax');
+        $this->_addressMock->expects($this->once())->method('unsBaseSubtotalInclTax');
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->once())->method('addItemDiscountPrices');
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue(true));
+        $this->_configMock->expects($this->once())->method('priceIncludesTax')
+            ->will($this->returnValue(true));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect does not taxable items
+     */
+    public function testCollectDataStoreDisabled()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_addressMock->expects($this->never())->method('unsSubtotalInclTax');
+        $this->_addressMock->expects($this->never())->method('unsBaseSubtotalInclTax');
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->any())->method('includeInSubtotal')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->once(0))->method('isEnabled')
+            ->will($this->returnValue(false));
+        $this->_configMock->expects($this->never())->method('priceIncludesTax')
+            ->will($this->returnValue(true));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect items and apply discount to weee
+     */
+    public function testCollectWithChildren()
+    {
+        $childQuoteItemMock = $this->getMock('Magento\Sales\Model\Quote\Item', [], [], '', false);
+
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_quoteItemMock->expects($this->any())->method('getHasChildren')
+            ->will($this->returnValue(true));
+        $this->_quoteItemMock->expects($this->any())->method('isChildrenCalculated')
+            ->will($this->returnValue(true));
+        $this->_quoteItemMock->expects($this->any())->method('getChildren')
+            ->will($this->returnValue(array($childQuoteItemMock)));
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->once())->method('addItemDiscountPrices');
+        $this->_weeeDataMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue(true));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    public function testCollectWeeeIncludeInSubtotal()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(array($this->_quoteItemMock)));
+        $this->_weeeDataMock->expects($this->any())->method('isDiscounted')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->any())->method('isTaxable')
+            ->will($this->returnValue(false));
+        $this->_weeeDataMock->expects($this->once())->method('addItemDiscountPrices');
+        $this->_weeeDataMock->expects($this->any())->method('isEnabled')
+            ->will($this->returnValue(true));
+        $this->_weeeDataMock->expects($this->any())->method('includeInSubtotal')
+            ->will($this->returnValue(true));
+        $this->_model->collect($this->_addressMock);
+    }
+
+    /**
+     * Collect empty items
+     */
+    public function testCollectWithoutItems()
+    {
+        $this->_addressMock->expects($this->any())->method('getAllNonNominalItems')
+            ->will($this->returnValue(null));
+        $this->assertEquals($this->_model, $this->_model->collect($this->_addressMock));
+    }
+
+    /**
+     * Fetch method test
+     */
+    public function testFetch()
+    {
+        $this->assertEquals($this->_model, $this->_model->fetch($this->_addressMock));
+    }
+
+    /**
+     * Process configuration array
+     */
+    public function testProcessConfigArray()
+    {
+        $this->assertEquals(
+            $this->_configMock, $this->_model->processConfigArray($this->_configMock, $this->_storeMock)
+        );
+    }
+
+    /**
+     * Get label
+     */
+    public function testGetLabel()
+    {
+        $this->assertEquals('', $this->_model->getLabel());
+    }
+}
diff --git a/downloader/lib/Magento/Framework/Connect/Converter.php b/downloader/lib/Magento/Framework/Connect/Converter.php
index 0f51b1da174d1200d320c730537ad6afc2fd1b13..6f8c31842047b2565abc14fd3f3ab6fbb55649a8 100644
--- a/downloader/lib/Magento/Framework/Connect/Converter.php
+++ b/downloader/lib/Magento/Framework/Connect/Converter.php
@@ -191,19 +191,27 @@ final class Converter
                 throw new \Exception("Invalid 'getterArgs' for '{$field}', should be array");
             }
 
-            if ($useGetter && !method_exists($pearObject, $rules['getter'])) {
+            if ($useGetter
+                && (!method_exists($pearObject, $rules['getter'])
+                    || !is_callable([$pearObject, $rules['getter']])
+                )
+            ) {
                 $mName = get_class($pearObject) . "::" . $rules['getter'];
                 throw new \Exception('No getter method exists: ' . $mName);
             }
 
-            if ($useSetter && !method_exists($mageObject, $rules['setter'])) {
+            if ($useSetter
+                && (!method_exists($mageObject, $rules['setter'])
+                    || !is_callable([$mageObject, $rules['setter']])
+                )
+            ) {
                 $mName = get_class($mageObject) . "::" . $rules['setter'];
                 throw new \Exception('No setter method exists: ' . $mName);
             }
 
             $useConverter = !empty($rules['converter']);
 
-            if ($useConverter && false === method_exists($this, $rules['converter'])) {
+            if ($useConverter && !method_exists($this, $rules['converter'])) {
                 $mName = get_class($this) . "::" . $rules['converter'];
                 throw new \Exception('No converter method exists: ' . $mName);
             }
diff --git a/downloader/lib/Magento/Framework/Connect/Package.php b/downloader/lib/Magento/Framework/Connect/Package.php
index 3681ff8969f91839a8a459cac0a0f43dab7ed89e..7a25caadcf9b10ff19f4e29835977e84f426fdf0 100644
--- a/downloader/lib/Magento/Framework/Connect/Package.php
+++ b/downloader/lib/Magento/Framework/Connect/Package.php
@@ -1223,7 +1223,7 @@ END;
             /**
              * Check for method availability, validator
              */
-            if (!method_exists($v, $validatorMethod)) {
+            if (!method_exists($v, $validatorMethod) || !is_callable([$v, $validatorMethod])) {
                 throw new \Magento\Framework\Exception("Invalid method specified for Validator : {$validatorMethod}");
             }
 
diff --git a/lib/internal/Magento/Framework/App/Config/Initial/Reader.php b/lib/internal/Magento/Framework/App/Config/Initial/Reader.php
index 25b90165cb4fab8162e8231bf97a447fb49527c2..e63c724365e7858f0b4da6ddae62bb9792a7e378 100644
--- a/lib/internal/Magento/Framework/App/Config/Initial/Reader.php
+++ b/lib/internal/Magento/Framework/App/Config/Initial/Reader.php
@@ -60,7 +60,7 @@ class Reader
      *
      * @var array
      */
-    protected $_scopePriorityScheme = array('primary', 'global');
+    protected $_scopePriorityScheme = array('global');
 
     /**
      * Path to corresponding XSD file with validation rules for config
diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php
index b025f1a1a365945705025d977a2cdcb7a487987f..12909ce6089ab91890e3f65402932cdf6aeeb4bc 100644
--- a/lib/internal/Magento/Framework/AppInterface.php
+++ b/lib/internal/Magento/Framework/AppInterface.php
@@ -35,7 +35,7 @@ interface AppInterface
     /**
      * Magento version
      */
-    const VERSION = '2.0.0.0-dev80';
+    const VERSION = '2.0.0.0-dev81';
 
     /**
      * Launch application
diff --git a/lib/internal/Magento/Framework/Archive.php b/lib/internal/Magento/Framework/Archive.php
index 68bc94b69beef270e78b509cae0f0791a0869fcc..1a113687884fe4465f5c2432b7a74a0bef934cbd 100644
--- a/lib/internal/Magento/Framework/Archive.php
+++ b/lib/internal/Magento/Framework/Archive.php
@@ -80,11 +80,8 @@ class Archive
      */
     protected function _getArchiver($extension)
     {
-        if (array_key_exists(strtolower($extension), $this->_formats)) {
-            $format = $this->_formats[$extension];
-        } else {
-            $format = self::DEFAULT_ARCHIVER;
-        }
+        $extension = strtolower($extension);
+        $format = isset($this->_formats[$extension]) ? $this->_formats[$extension] : self::DEFAULT_ARCHIVER;
         $class = '\\Magento\Framework\Archive\\' . ucfirst($format);
         $this->_archiver = new $class();
         return $this->_archiver;
@@ -99,15 +96,10 @@ class Archive
     protected function _getArchivers($source)
     {
         $ext = pathinfo($source, PATHINFO_EXTENSION);
-        if (!isset($this->_formats[$ext])) {
-            return array();
-        }
-        $format = $this->_formats[$ext];
-        if ($format) {
-            $archivers = explode('.', $format);
-            return $archivers;
+        if (!empty($this->_formats[$ext])) {
+            return explode('.', $this->_formats[$ext]);
         }
-        return array();
+        return [];
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/Connect/Command.php b/lib/internal/Magento/Framework/Connect/Command.php
index b94780cc912ba926bb319216d1a75a61608d577f..a5dd20c163be57596b44b0d573eccb9f497f5049 100644
--- a/lib/internal/Magento/Framework/Connect/Command.php
+++ b/lib/internal/Magento/Framework/Connect/Command.php
@@ -142,7 +142,7 @@ class Command
         $data = $this->getCommandInfo($command);
         $method = $data['function'];
         if (!method_exists($this, $method)) {
-            throw new \Exception("{$method} does't exist in class " . $this->_class);
+            throw new \Exception("{$method} can not be executed in class " . $this->_class);
         }
         return $this->{$method}($command, $options, $params);
     }
diff --git a/lib/internal/Magento/Framework/Connect/Converter.php b/lib/internal/Magento/Framework/Connect/Converter.php
index 63fcc3778821f4e9cb0fa1272d74187608f84ccd..a843ab1c467ad96fcaeda4ac6babd3899d1065eb 100644
--- a/lib/internal/Magento/Framework/Connect/Converter.php
+++ b/lib/internal/Magento/Framework/Connect/Converter.php
@@ -196,19 +196,27 @@ final class Converter
                 throw new \Exception("Invalid 'getterArgs' for '{$field}', should be array");
             }
 
-            if ($useGetter && !method_exists($pearObject, $rules['getter'])) {
+            if ($useGetter
+                && (!method_exists($pearObject, $rules['getter'])
+                    || !is_callable([$pearObject, $rules['getter']])
+                )
+            ) {
                 $mName = get_class($pearObject) . "::" . $rules['getter'];
                 throw new \Exception('No getter method exists: ' . $mName);
             }
 
-            if ($useSetter && !method_exists($mageObject, $rules['setter'])) {
+            if ($useSetter
+                && (!method_exists($mageObject, $rules['setter'])
+                    || !is_callable([$mageObject, $rules['setter']])
+                )
+            ) {
                 $mName = get_class($mageObject) . "::" . $rules['setter'];
                 throw new \Exception('No setter method exists: ' . $mName);
             }
 
             $useConverter = !empty($rules['converter']);
 
-            if ($useConverter && false === method_exists($this, $rules['converter'])) {
+            if ($useConverter && !method_exists($this, $rules['converter'])) {
                 $mName = get_class($this) . "::" . $rules['converter'];
                 throw new \Exception('No converter method exists: ' . $mName);
             }
diff --git a/lib/internal/Magento/Framework/Connect/Package.php b/lib/internal/Magento/Framework/Connect/Package.php
index 599c3c6ff5c7d9b1f16f3a518840e35f4f0fc16f..9ced857a64ed1e94affbc3c2d37a3724ad2e2081 100644
--- a/lib/internal/Magento/Framework/Connect/Package.php
+++ b/lib/internal/Magento/Framework/Connect/Package.php
@@ -1397,7 +1397,7 @@ END;
             /**
              * Check for method availability, validator
              */
-            if (!method_exists($v, $validatorMethod)) {
+            if (!method_exists($v, $validatorMethod) || !is_callable([$v, $validatorMethod])) {
                 throw new \Magento\Framework\Exception("Invalid method specified for Validator : {$validatorMethod}");
             }
 
diff --git a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
index e56566387e714a8d2e6f685d354bbcf688cea8f0..49385b44bfb3b080fadd90076de99e828895da3a 100644
--- a/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
+++ b/lib/internal/Magento/Framework/DB/Adapter/Pdo/Mysql.php
@@ -1141,7 +1141,7 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
 
             // collect CONSTRAINT
             $regExp  = '#,\s+CONSTRAINT `([^`]*)` FOREIGN KEY \(`([^`]*)`\) '
-                . 'REFERENCES (`[^`]*\.)?`([^`]*)` \(`([^`]*)`\)'
+                . 'REFERENCES (`([^`]*)`\.)?`([^`]*)` \(`([^`]*)`\)'
                 . '( ON DELETE (RESTRICT|CASCADE|SET NULL|NO ACTION))?'
                 . '( ON UPDATE (RESTRICT|CASCADE|SET NULL|NO ACTION))?#';
             $matches = array();
@@ -1152,11 +1152,11 @@ class Mysql extends \Zend_Db_Adapter_Pdo_Mysql implements AdapterInterface
                     'SCHEMA_NAME'       => $schemaName,
                     'TABLE_NAME'        => $tableName,
                     'COLUMN_NAME'       => $match[2],
-                    'REF_SHEMA_NAME'    => isset($match[3]) ? $match[3] : $schemaName,
-                    'REF_TABLE_NAME'    => $match[4],
-                    'REF_COLUMN_NAME'   => $match[5],
-                    'ON_DELETE'         => isset($match[6]) ? $match[7] : '',
-                    'ON_UPDATE'         => isset($match[8]) ? $match[9] : ''
+                    'REF_SHEMA_NAME'    => isset($match[4]) ? $match[4] : $schemaName,
+                    'REF_TABLE_NAME'    => $match[5],
+                    'REF_COLUMN_NAME'   => $match[6],
+                    'ON_DELETE'         => isset($match[7]) ? $match[8] : '',
+                    'ON_UPDATE'         => isset($match[9]) ? $match[10] : ''
                 );
             }
 
diff --git a/lib/internal/Magento/Framework/Event/Invoker/InvokerDefault.php b/lib/internal/Magento/Framework/Event/Invoker/InvokerDefault.php
index 5709c05df784a4b05511212d6dfd727db2feff96..721736e899df1339a145fce9b09ed0d83430919b 100644
--- a/lib/internal/Magento/Framework/Event/Invoker/InvokerDefault.php
+++ b/lib/internal/Magento/Framework/Event/Invoker/InvokerDefault.php
@@ -87,7 +87,7 @@ class InvokerDefault implements \Magento\Framework\Event\InvokerInterface
      */
     protected function _callObserverMethod($object, $method, $observer)
     {
-        if (method_exists($object, $method)) {
+        if (method_exists($object, $method) && is_callable([$object, $method])) {
             $object->{$method}($observer);
         } elseif ($this->_appState->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER) {
             throw new \LogicException('Method "' . $method . '" is not defined in "' . get_class($object) . '"');
diff --git a/lib/internal/Magento/Framework/Exception/CouldNotSaveException.php b/lib/internal/Magento/Framework/Exception/CouldNotSaveException.php
new file mode 100644
index 0000000000000000000000000000000000000000..120db878b4c0311e6447a346d5b4cac48a7c368b
--- /dev/null
+++ b/lib/internal/Magento/Framework/Exception/CouldNotSaveException.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 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\Exception;
+
+class CouldNotSaveException extends AbstractAggregateException
+{
+
+}
diff --git a/lib/internal/Magento/Framework/File/Uploader.php b/lib/internal/Magento/Framework/File/Uploader.php
index d3072e9070cc5dfb5c2d3a91c69209366fc5c611..13b008e248467c6359ec5a65aaa77cfe5d559584 100644
--- a/lib/internal/Magento/Framework/File/Uploader.php
+++ b/lib/internal/Magento/Framework/File/Uploader.php
@@ -287,7 +287,10 @@ class Uploader
         }
         //run validate callbacks
         foreach ($this->_validateCallbacks as $params) {
-            if (is_object($params['object']) && method_exists($params['object'], $params['method'])) {
+            if (is_object($params['object'])
+                && method_exists($params['object'], $params['method'])
+                && is_callable([$params['object'], $params['method']])
+            ) {
                 $params['object']->{$params['method']}($this->_file['tmp_name']);
             }
         }
diff --git a/lib/internal/Magento/Framework/Filter/Template.php b/lib/internal/Magento/Framework/Filter/Template.php
index 867c0d49651521339dedfdc9c9a6aad49791b624..e22208d53c72b7752e4d65016e2fa73dcd5ed400 100644
--- a/lib/internal/Magento/Framework/Filter/Template.php
+++ b/lib/internal/Magento/Framework/Filter/Template.php
@@ -119,9 +119,9 @@ class Template implements \Zend_Filter_Interface
     {
         // "depend" and "if" operands should be first
         foreach (array(
-            self::CONSTRUCTION_DEPEND_PATTERN => 'dependDirective',
-            self::CONSTRUCTION_IF_PATTERN => 'ifDirective'
-        ) as $pattern => $directive) {
+                     self::CONSTRUCTION_DEPEND_PATTERN => 'dependDirective',
+                     self::CONSTRUCTION_IF_PATTERN => 'ifDirective'
+                 ) as $pattern => $directive) {
             if (preg_match_all($pattern, $value, $constructions, PREG_SET_ORDER)) {
                 foreach ($constructions as $construction) {
                     $callback = array($this, $directive);
@@ -269,7 +269,7 @@ class Template implements \Zend_Filter_Interface
                 $stackVars[$i]['variable'] =& $this->_templateVars[$stackVars[$i]['name']];
             } elseif (isset(
                 $stackVars[$i - 1]['variable']
-            ) && $stackVars[$i - 1]['variable'] instanceof \Magento\Framework\Object
+                ) && $stackVars[$i - 1]['variable'] instanceof \Magento\Framework\Object
             ) {
                 // If object calling methods or getting properties
                 if ($stackVars[$i]['type'] == 'property') {
diff --git a/lib/internal/Magento/Framework/Gdata/Gshopping/Content.php b/lib/internal/Magento/Framework/Gdata/Gshopping/Content.php
index f3c58c488d7ad6e8f4218c752131a6aa4e1649cf..128e594f7d5f4770fe4766034bde435d82066ef6 100644
--- a/lib/internal/Magento/Framework/Gdata/Gshopping/Content.php
+++ b/lib/internal/Magento/Framework/Gdata/Gshopping/Content.php
@@ -278,7 +278,7 @@ class Content extends \Zend_Gdata
      */
     public function setLogAdapter($instance, $method)
     {
-        if (method_exists($instance, $method)) {
+        if (method_exists($instance, $method) && is_callable([$instance, $method])) {
             $this->_logAdapter = $instance;
             $this->_logAdapterLogAction = $method;
         }
diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php
index 59880c84189d086ed36d3b56bad6d8d16c08c0fe..ccf03d36baca719f2e09111821033dcece7c5b12 100644
--- a/lib/internal/Magento/Framework/Model/AbstractModel.php
+++ b/lib/internal/Magento/Framework/Model/AbstractModel.php
@@ -164,7 +164,9 @@ abstract class AbstractModel extends \Magento\Framework\Object
         $this->_logger = $context->getLogger();
         $this->_actionValidator = $context->getActionValidator();
 
-        if (method_exists($this->_resource, 'getIdFieldName') || $this->_resource instanceof \Magento\Framework\Object) {
+        if (method_exists($this->_resource, 'getIdFieldName')
+            || $this->_resource instanceof \Magento\Framework\Object
+        ) {
             $this->_idFieldName = $this->_getResource()->getIdFieldName();
         }
 
diff --git a/lib/internal/Magento/Framework/ObjectManager/Factory/Factory.php b/lib/internal/Magento/Framework/ObjectManager/Factory/Factory.php
index 86ac4db6d3de71c60d82aa6de0978e89354f7530..7077e7ae27af77fd1f0adabaed40ae9c620ede36 100644
--- a/lib/internal/Magento/Framework/ObjectManager/Factory/Factory.php
+++ b/lib/internal/Magento/Framework/ObjectManager/Factory/Factory.php
@@ -164,7 +164,7 @@ class Factory implements \Magento\Framework\ObjectManager\Factory
                         ? $this->globalArguments[$item['argument']]
                         : null;
                 } else {
-                    $this->parseArray($item);
+                    $this->parseArray($array[$key]);
                 }
             }
         }
diff --git a/lib/internal/Magento/Framework/Registry.php b/lib/internal/Magento/Framework/Registry.php
index f4d59f11ea2119455dc5325b321f049c8ed203be..275dbf8778f30cd9780405839147d5edfaece68f 100644
--- a/lib/internal/Magento/Framework/Registry.php
+++ b/lib/internal/Magento/Framework/Registry.php
@@ -78,7 +78,10 @@ class Registry
     public function unregister($key)
     {
         if (isset($this->_registry[$key])) {
-            if (is_object($this->_registry[$key]) && method_exists($this->_registry[$key], '__destruct')) {
+            if (is_object($this->_registry[$key])
+                && method_exists($this->_registry[$key], '__destruct')
+                && is_callable([$this->_registry[$key], '__destruct'])
+            ) {
                 $this->_registry[$key]->__destruct();
             }
             unset($this->_registry[$key]);
diff --git a/lib/internal/Magento/Framework/Service/Data/AbstractObject.php b/lib/internal/Magento/Framework/Service/Data/AbstractObject.php
index c4d534d29c5316d68f168b5a77da2fb30a9f9b45..efa021b882fe929616fe9df5942408f1d5882f71 100644
--- a/lib/internal/Magento/Framework/Service/Data/AbstractObject.php
+++ b/lib/internal/Magento/Framework/Service/Data/AbstractObject.php
@@ -63,13 +63,16 @@ abstract class AbstractObject
     public function __toArray()
     {
         $data = $this->_data;
+        $hasToArray = function ($model) {
+            return is_object($model) && method_exists($model, '__toArray') && is_callable([$model, '__toArray']);
+        };
         foreach ($data as $key => $value) {
-            if (is_object($value) && method_exists($value, '__toArray')) {
+            if ($hasToArray($value)) {
                 $data[$key] = $value->__toArray();
             } elseif (is_array($value)) {
-                foreach ($value as $nestedArrayKey => $nestedArrayValue) {
-                    if (is_object($nestedArrayValue) && method_exists($nestedArrayValue, '__toArray')) {
-                        $value[$nestedArrayKey] = $nestedArrayValue->__toArray();
+                foreach ($value as $nestedKey => $nestedValue) {
+                    if ($hasToArray($nestedValue)) {
+                        $value[$nestedKey] = $nestedValue->__toArray();
                     }
                 }
                 $data[$key] = $value;
diff --git a/lib/internal/Magento/Framework/Service/Data/AbstractObjectBuilder.php b/lib/internal/Magento/Framework/Service/Data/AbstractObjectBuilder.php
index 86c5ddf0b863f94de1cdaa3fc4e0cd522346f245..81bbd1c075b8a49e5db503fec66bc89127b7278b 100644
--- a/lib/internal/Magento/Framework/Service/Data/AbstractObjectBuilder.php
+++ b/lib/internal/Magento/Framework/Service/Data/AbstractObjectBuilder.php
@@ -34,11 +34,17 @@ abstract class AbstractObjectBuilder
     protected $_data;
 
     /**
-     * Initialize internal storage
+     * @var ObjectFactory
      */
-    public function __construct()
+    protected $objectFactory;
+
+    /**
+     * @param ObjectFactory $objectFactory
+     */
+    public function __construct(ObjectFactory $objectFactory)
     {
         $this->_data = array();
+        $this->objectFactory = $objectFactory;
     }
 
     /**
@@ -152,7 +158,7 @@ abstract class AbstractObjectBuilder
     public function create()
     {
         $dataObjectType = $this->_getDataObjectType();
-        $dataObject = new $dataObjectType($this);
+        $dataObject = $this->objectFactory->create($dataObjectType, ['builder' => $this]);
         $this->_data = array();
         return $dataObject;
     }
diff --git a/lib/internal/Magento/Framework/Service/Data/Eav/AbstractObjectBuilder.php b/lib/internal/Magento/Framework/Service/Data/Eav/AbstractObjectBuilder.php
index e121f6c5d25e5b80e7c8d67657ed26805e74206a..234117461e9cb0a1a653164fe24cfa8d3f6a70fe 100644
--- a/lib/internal/Magento/Framework/Service/Data/Eav/AbstractObjectBuilder.php
+++ b/lib/internal/Magento/Framework/Service/Data/Eav/AbstractObjectBuilder.php
@@ -34,12 +34,15 @@ abstract class AbstractObjectBuilder extends \Magento\Framework\Service\Data\Abs
     protected $_valueBuilder;
 
     /**
+     * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory
      * @param AttributeValueBuilder $valueBuilder
      */
-    public function __construct(AttributeValueBuilder $valueBuilder)
-    {
+    public function __construct(
+        \Magento\Framework\Service\Data\ObjectFactory $objectFactory,
+        AttributeValueBuilder $valueBuilder
+    ) {
         $this->_valueBuilder = $valueBuilder;
-        parent::__construct();
+        parent::__construct($objectFactory);
     }
 
     /**
diff --git a/app/code/Magento/Paypal/Model/Method/ProTypeFactory.php b/lib/internal/Magento/Framework/Service/Data/ObjectFactory.php
similarity index 70%
rename from app/code/Magento/Paypal/Model/Method/ProTypeFactory.php
rename to lib/internal/Magento/Framework/Service/Data/ObjectFactory.php
index 9fbfcb72e2619c0ad8c39a6ee88254295387bc6e..a758b69201a94467b1fa36470994dba8b06dcb86 100644
--- a/app/code/Magento/Paypal/Model/Method/ProTypeFactory.php
+++ b/lib/internal/Magento/Framework/Service/Data/ObjectFactory.php
@@ -21,39 +21,33 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Paypal\Model\Method;
 
-/**
- * Factory class for payment method model
- */
-class ProTypeFactory
+namespace Magento\Framework\Service\Data;
+
+class ObjectFactory
 {
     /**
-     * Object Manager instance
-     *
      * @var \Magento\Framework\ObjectManager
      */
-    protected $_objectManager = null;
+    protected $objectManager;
 
     /**
-     * Factory constructor
-     *
      * @param \Magento\Framework\ObjectManager $objectManager
      */
     public function __construct(\Magento\Framework\ObjectManager $objectManager)
     {
-        $this->_objectManager = $objectManager;
+        $this->objectManager = $objectManager;
     }
 
     /**
-     * Create class instance with specified parameters
+     * Create data object
      *
      * @param string $className
-     * @param array $data
-     * @return \Magento\Framework\Object
+     * @param array $arguments
+     * @return AbstractObject
      */
-    public function create($className, array $data = array())
+    public function create($className, array $arguments)
     {
-        return $this->_objectManager->create($className, $data);
+        return $this->objectManager->create($className, $arguments);
     }
 }
diff --git a/lib/internal/Magento/Framework/Service/V1/Data/Search/FilterGroupBuilder.php b/lib/internal/Magento/Framework/Service/V1/Data/Search/FilterGroupBuilder.php
index aaf1bfcabb7603572c8ccfb1c08fca55eba9c95a..1dbe072de975531b1057c80a377c0105a5deb0b6 100644
--- a/lib/internal/Magento/Framework/Service/V1/Data/Search/FilterGroupBuilder.php
+++ b/lib/internal/Magento/Framework/Service/V1/Data/Search/FilterGroupBuilder.php
@@ -38,13 +38,14 @@ class FilterGroupBuilder extends AbstractObjectBuilder
     protected $_filterBuilder;
 
     /**
-     * Constructor
-     *
+     * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory
      * @param FilterBuilder $filterBuilder
      */
-    public function __construct(FilterBuilder $filterBuilder)
-    {
-        parent::__construct();
+    public function __construct(
+        \Magento\Framework\Service\Data\ObjectFactory $objectFactory,
+        FilterBuilder $filterBuilder
+    ) {
+        parent::__construct($objectFactory);
         $this->_filterBuilder = $filterBuilder;
     }
 
diff --git a/lib/internal/Magento/Framework/Service/V1/Data/SearchCriteriaBuilder.php b/lib/internal/Magento/Framework/Service/V1/Data/SearchCriteriaBuilder.php
index a938584c8929c724f3e29510ab083eda304fa60d..9e56257d09e9e7d83b52cd980b1d95f28c478d71 100644
--- a/lib/internal/Magento/Framework/Service/V1/Data/SearchCriteriaBuilder.php
+++ b/lib/internal/Magento/Framework/Service/V1/Data/SearchCriteriaBuilder.php
@@ -38,13 +38,14 @@ class SearchCriteriaBuilder extends AbstractObjectBuilder
     protected $_filterGroupBuilder;
 
     /**
-     * Constructor
-     *
+     * @param \Magento\Framework\Service\Data\ObjectFactory $objectFactory
      * @param FilterGroupBuilder $filterGroupBuilder
      */
-    public function __construct(FilterGroupBuilder $filterGroupBuilder)
-    {
-        parent::__construct();
+    public function __construct(
+        \Magento\Framework\Service\Data\ObjectFactory $objectFactory,
+        FilterGroupBuilder $filterGroupBuilder
+    ) {
+        parent::__construct($objectFactory);
         $this->_filterGroupBuilder = $filterGroupBuilder;
     }